mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
403b1b968d
`rake ragel` failed due to renaming the ragel machine from
`http_parser` to `puma_parser` in 3726b7ef19
.
The problem was probably overseen since the file
http11_parser.java.rl has not been touched at this commit
and therefore the rake task did not invoke the parser
generation for the java parser.
161 lines
3.9 KiB
Ragel
161 lines
3.9 KiB
Ragel
package org.jruby.puma;
|
|
|
|
import org.jruby.util.ByteList;
|
|
|
|
public class Http11Parser {
|
|
|
|
/** Machine **/
|
|
|
|
%%{
|
|
|
|
machine puma_parser;
|
|
|
|
action mark {parser.mark = fpc; }
|
|
|
|
action start_field { parser.field_start = fpc; }
|
|
action snake_upcase_field { /* FIXME stub */ }
|
|
action write_field {
|
|
parser.field_len = fpc-parser.field_start;
|
|
}
|
|
|
|
action start_value { parser.mark = fpc; }
|
|
action write_value {
|
|
if(parser.http_field != null) {
|
|
parser.http_field.call(parser.data, parser.field_start, parser.field_len, parser.mark, fpc-parser.mark);
|
|
}
|
|
}
|
|
action request_method {
|
|
if(parser.request_method != null)
|
|
parser.request_method.call(parser.data, parser.mark, fpc-parser.mark);
|
|
}
|
|
action request_uri {
|
|
if(parser.request_uri != null)
|
|
parser.request_uri.call(parser.data, parser.mark, fpc-parser.mark);
|
|
}
|
|
action fragment {
|
|
if(parser.fragment != null)
|
|
parser.fragment.call(parser.data, parser.mark, fpc-parser.mark);
|
|
}
|
|
|
|
action start_query {parser.query_start = fpc; }
|
|
action query_string {
|
|
if(parser.query_string != null)
|
|
parser.query_string.call(parser.data, parser.query_start, fpc-parser.query_start);
|
|
}
|
|
|
|
action http_version {
|
|
if(parser.http_version != null)
|
|
parser.http_version.call(parser.data, parser.mark, fpc-parser.mark);
|
|
}
|
|
|
|
action request_path {
|
|
if(parser.request_path != null)
|
|
parser.request_path.call(parser.data, parser.mark, fpc-parser.mark);
|
|
}
|
|
|
|
action done {
|
|
parser.body_start = fpc + 1;
|
|
if(parser.header_done != null)
|
|
parser.header_done.call(parser.data, fpc + 1, pe - fpc - 1);
|
|
fbreak;
|
|
}
|
|
|
|
include puma_parser_common "http11_parser_common.rl";
|
|
|
|
}%%
|
|
|
|
/** Data **/
|
|
%% write data;
|
|
|
|
public static interface ElementCB {
|
|
public void call(Object data, int at, int length);
|
|
}
|
|
|
|
public static interface FieldCB {
|
|
public void call(Object data, int field, int flen, int value, int vlen);
|
|
}
|
|
|
|
public static class HttpParser {
|
|
int cs;
|
|
int body_start;
|
|
int content_len;
|
|
int nread;
|
|
int mark;
|
|
int field_start;
|
|
int field_len;
|
|
int query_start;
|
|
|
|
Object data;
|
|
ByteList buffer;
|
|
|
|
public FieldCB http_field;
|
|
public ElementCB request_method;
|
|
public ElementCB request_uri;
|
|
public ElementCB fragment;
|
|
public ElementCB request_path;
|
|
public ElementCB query_string;
|
|
public ElementCB http_version;
|
|
public ElementCB header_done;
|
|
|
|
public void init() {
|
|
cs = 0;
|
|
|
|
%% write init;
|
|
|
|
body_start = 0;
|
|
content_len = 0;
|
|
mark = 0;
|
|
nread = 0;
|
|
field_len = 0;
|
|
field_start = 0;
|
|
}
|
|
}
|
|
|
|
public final HttpParser parser = new HttpParser();
|
|
|
|
public int execute(ByteList buffer, int off) {
|
|
int p, pe;
|
|
int cs = parser.cs;
|
|
int len = buffer.length();
|
|
assert off<=len : "offset past end of buffer";
|
|
|
|
p = off;
|
|
pe = len;
|
|
// get a copy of the bytes, since it may not start at 0
|
|
// FIXME: figure out how to just use the bytes in-place
|
|
byte[] data = buffer.bytes();
|
|
parser.buffer = buffer;
|
|
|
|
%% write exec;
|
|
|
|
parser.cs = cs;
|
|
parser.nread += (p - off);
|
|
|
|
assert p <= pe : "buffer overflow after parsing execute";
|
|
assert parser.nread <= len : "nread longer than length";
|
|
assert parser.body_start <= len : "body starts after buffer end";
|
|
assert parser.mark < len : "mark is after buffer end";
|
|
assert parser.field_len <= len : "field has length longer than whole buffer";
|
|
assert parser.field_start < len : "field starts after buffer end";
|
|
|
|
return parser.nread;
|
|
}
|
|
|
|
public int finish() {
|
|
if(has_error()) {
|
|
return -1;
|
|
} else if(is_finished()) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public boolean has_error() {
|
|
return parser.cs == puma_parser_error;
|
|
}
|
|
|
|
public boolean is_finished() {
|
|
return parser.cs == puma_parser_first_final;
|
|
}
|
|
}
|