mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Start cleanup and modernization
This commit is contained in:
parent
812ce631df
commit
f748edfade
11 changed files with 293 additions and 324 deletions
2
Rakefile
2
Rakefile
|
@ -4,5 +4,7 @@
|
||||||
# Thank You.
|
# Thank You.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
require 'rubygems'
|
||||||
|
|
||||||
# load rakefile extensions (tasks)
|
# load rakefile extensions (tasks)
|
||||||
Dir['tasks/*.rake'].sort.each { |f| load f }
|
Dir['tasks/*.rake'].sort.each { |f| load f }
|
||||||
|
|
|
@ -8,12 +8,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "http11_parser.h"
|
#include "http11_parser.h"
|
||||||
|
|
||||||
#ifndef RSTRING_PTR
|
#ifndef MANAGED_STRINGS
|
||||||
#define RSTRING_PTR(s) (RSTRING(s)->ptr)
|
|
||||||
#endif
|
|
||||||
#ifndef RSTRING_LEN
|
|
||||||
#define RSTRING_LEN(s) (RSTRING(s)->len)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef RSTRING_PTR
|
#ifndef RSTRING_PTR
|
||||||
#define RSTRING_PTR(s) (RSTRING(s)->ptr)
|
#define RSTRING_PTR(s) (RSTRING(s)->ptr)
|
||||||
|
@ -22,8 +17,11 @@
|
||||||
#define RSTRING_LEN(s) (RSTRING(s)->len)
|
#define RSTRING_LEN(s) (RSTRING(s)->len)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static VALUE mMongrel;
|
#define rb_extract_chars(e, sz) (*sz = RSTRING_LEN(e), RSTRING_PTR(e))
|
||||||
static VALUE cHttpParser;
|
#define rb_free_chars(e) /* nothing */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static VALUE eHttpParserError;
|
static VALUE eHttpParserError;
|
||||||
|
|
||||||
#define id_handler_map rb_intern("@handler_map")
|
#define id_handler_map rb_intern("@handler_map")
|
||||||
|
@ -36,21 +34,7 @@ static VALUE global_request_uri;
|
||||||
static VALUE global_fragment;
|
static VALUE global_fragment;
|
||||||
static VALUE global_query_string;
|
static VALUE global_query_string;
|
||||||
static VALUE global_http_version;
|
static VALUE global_http_version;
|
||||||
static VALUE global_content_length;
|
|
||||||
static VALUE global_http_content_length;
|
|
||||||
static VALUE global_request_path;
|
static VALUE global_request_path;
|
||||||
static VALUE global_content_type;
|
|
||||||
static VALUE global_http_content_type;
|
|
||||||
static VALUE global_gateway_interface;
|
|
||||||
static VALUE global_gateway_interface_value;
|
|
||||||
static VALUE global_server_name;
|
|
||||||
static VALUE global_server_port;
|
|
||||||
static VALUE global_server_protocol;
|
|
||||||
static VALUE global_server_protocol_value;
|
|
||||||
static VALUE global_http_host;
|
|
||||||
static VALUE global_mongrel_version;
|
|
||||||
static VALUE global_server_software;
|
|
||||||
static VALUE global_port_80;
|
|
||||||
|
|
||||||
#define TRIE_INCREASE 30
|
#define TRIE_INCREASE 30
|
||||||
|
|
||||||
|
@ -61,7 +45,7 @@ static VALUE global_port_80;
|
||||||
#define VALIDATE_MAX_LENGTH(len, N) if(len > MAX_##N##_LENGTH) { rb_raise(eHttpParserError, MAX_##N##_LENGTH_ERR); }
|
#define VALIDATE_MAX_LENGTH(len, N) if(len > MAX_##N##_LENGTH) { rb_raise(eHttpParserError, MAX_##N##_LENGTH_ERR); }
|
||||||
|
|
||||||
/** Defines global strings in the init method. */
|
/** Defines global strings in the init method. */
|
||||||
#define DEF_GLOBAL(N, val) global_##N = rb_obj_freeze(rb_str_new2(val)); rb_global_variable(&global_##N)
|
#define DEF_GLOBAL(N, val) global_##N = rb_str_new2(val); rb_global_variable(&global_##N)
|
||||||
|
|
||||||
|
|
||||||
/* Defines the maximum allowed lengths for various input elements.*/
|
/* Defines the maximum allowed lengths for various input elements.*/
|
||||||
|
@ -149,7 +133,7 @@ static void init_common_fields(void)
|
||||||
|
|
||||||
for(i = 0; i < ARRAY_SIZE(common_http_fields); cf++, i++) {
|
for(i = 0; i < ARRAY_SIZE(common_http_fields); cf++, i++) {
|
||||||
memcpy(tmp + HTTP_PREFIX_LEN, cf->name, cf->len + 1);
|
memcpy(tmp + HTTP_PREFIX_LEN, cf->name, cf->len + 1);
|
||||||
cf->value = rb_obj_freeze(rb_str_new(tmp, HTTP_PREFIX_LEN + cf->len));
|
cf->value = rb_str_new(tmp, HTTP_PREFIX_LEN + cf->len);
|
||||||
rb_global_variable(&cf->value);
|
rb_global_variable(&cf->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,9 +168,9 @@ static VALUE find_common_field_value(const char *field, size_t flen)
|
||||||
#endif /* !HAVE_QSORT_BSEARCH */
|
#endif /* !HAVE_QSORT_BSEARCH */
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_field(void *data, const char *field, size_t flen, const char *value, size_t vlen)
|
void http_field(http_parser* hp, const char *field, size_t flen,
|
||||||
|
const char *value, size_t vlen)
|
||||||
{
|
{
|
||||||
VALUE req = (VALUE)data;
|
|
||||||
VALUE v = Qnil;
|
VALUE v = Qnil;
|
||||||
VALUE f = Qnil;
|
VALUE f = Qnil;
|
||||||
|
|
||||||
|
@ -201,122 +185,83 @@ void http_field(void *data, const char *field, size_t flen, const char *value, s
|
||||||
/*
|
/*
|
||||||
* We got a strange header that we don't have a memoized value for.
|
* We got a strange header that we don't have a memoized value for.
|
||||||
* Fallback to creating a new string to use as a hash key.
|
* Fallback to creating a new string to use as a hash key.
|
||||||
*
|
|
||||||
* using rb_str_new(NULL, len) here is faster than rb_str_buf_new(len)
|
|
||||||
* in my testing, because: there's no minimum allocation length (and
|
|
||||||
* no check for it, either), RSTRING_LEN(f) does not need to be
|
|
||||||
* written twice, and and RSTRING_PTR(f) will already be
|
|
||||||
* null-terminated for us.
|
|
||||||
*/
|
*/
|
||||||
f = rb_str_new(NULL, HTTP_PREFIX_LEN + flen);
|
|
||||||
memcpy(RSTRING_PTR(f), HTTP_PREFIX, HTTP_PREFIX_LEN);
|
size_t new_size = HTTP_PREFIX_LEN + flen;
|
||||||
memcpy(RSTRING_PTR(f) + HTTP_PREFIX_LEN, field, flen);
|
assert(new_size < BUFFER_LEN);
|
||||||
assert(*(RSTRING_PTR(f) + RSTRING_LEN(f)) == '\0'); /* paranoia */
|
|
||||||
/* fprintf(stderr, "UNKNOWN HEADER <%s>\n", RSTRING_PTR(f)); */
|
memcpy(hp->buf, HTTP_PREFIX, HTTP_PREFIX_LEN);
|
||||||
|
memcpy(hp->buf + HTTP_PREFIX_LEN, field, flen);
|
||||||
|
|
||||||
|
f = rb_str_new(hp->buf, new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_hash_aset(req, f, v);
|
rb_hash_aset(hp->request, f, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void request_method(void *data, const char *at, size_t length)
|
void request_method(http_parser* hp, const char *at, size_t length)
|
||||||
{
|
{
|
||||||
VALUE req = (VALUE)data;
|
|
||||||
VALUE val = Qnil;
|
VALUE val = Qnil;
|
||||||
|
|
||||||
val = rb_str_new(at, length);
|
val = rb_str_new(at, length);
|
||||||
rb_hash_aset(req, global_request_method, val);
|
rb_hash_aset(hp->request, global_request_method, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void request_uri(void *data, const char *at, size_t length)
|
void request_uri(http_parser* hp, const char *at, size_t length)
|
||||||
{
|
{
|
||||||
VALUE req = (VALUE)data;
|
|
||||||
VALUE val = Qnil;
|
VALUE val = Qnil;
|
||||||
|
|
||||||
VALIDATE_MAX_LENGTH(length, REQUEST_URI);
|
VALIDATE_MAX_LENGTH(length, REQUEST_URI);
|
||||||
|
|
||||||
val = rb_str_new(at, length);
|
val = rb_str_new(at, length);
|
||||||
rb_hash_aset(req, global_request_uri, val);
|
rb_hash_aset(hp->request, global_request_uri, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fragment(void *data, const char *at, size_t length)
|
void fragment(http_parser* hp, const char *at, size_t length)
|
||||||
{
|
{
|
||||||
VALUE req = (VALUE)data;
|
|
||||||
VALUE val = Qnil;
|
VALUE val = Qnil;
|
||||||
|
|
||||||
VALIDATE_MAX_LENGTH(length, FRAGMENT);
|
VALIDATE_MAX_LENGTH(length, FRAGMENT);
|
||||||
|
|
||||||
val = rb_str_new(at, length);
|
val = rb_str_new(at, length);
|
||||||
rb_hash_aset(req, global_fragment, val);
|
rb_hash_aset(hp->request, global_fragment, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void request_path(void *data, const char *at, size_t length)
|
void request_path(http_parser* hp, const char *at, size_t length)
|
||||||
{
|
{
|
||||||
VALUE req = (VALUE)data;
|
|
||||||
VALUE val = Qnil;
|
VALUE val = Qnil;
|
||||||
|
|
||||||
VALIDATE_MAX_LENGTH(length, REQUEST_PATH);
|
VALIDATE_MAX_LENGTH(length, REQUEST_PATH);
|
||||||
|
|
||||||
val = rb_str_new(at, length);
|
val = rb_str_new(at, length);
|
||||||
rb_hash_aset(req, global_request_path, val);
|
rb_hash_aset(hp->request, global_request_path, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_string(void *data, const char *at, size_t length)
|
void query_string(http_parser* hp, const char *at, size_t length)
|
||||||
{
|
{
|
||||||
VALUE req = (VALUE)data;
|
|
||||||
VALUE val = Qnil;
|
VALUE val = Qnil;
|
||||||
|
|
||||||
VALIDATE_MAX_LENGTH(length, QUERY_STRING);
|
VALIDATE_MAX_LENGTH(length, QUERY_STRING);
|
||||||
|
|
||||||
val = rb_str_new(at, length);
|
val = rb_str_new(at, length);
|
||||||
rb_hash_aset(req, global_query_string, val);
|
rb_hash_aset(hp->request, global_query_string, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_version(void *data, const char *at, size_t length)
|
void http_version(http_parser* hp, const char *at, size_t length)
|
||||||
{
|
{
|
||||||
VALUE req = (VALUE)data;
|
|
||||||
VALUE val = rb_str_new(at, length);
|
VALUE val = rb_str_new(at, length);
|
||||||
rb_hash_aset(req, global_http_version, val);
|
rb_hash_aset(hp->request, global_http_version, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Finalizes the request header to have a bunch of stuff that's
|
/** Finalizes the request header to have a bunch of stuff that's
|
||||||
needed. */
|
needed. */
|
||||||
|
|
||||||
void header_done(void *data, const char *at, size_t length)
|
void header_done(http_parser* hp, const char *at, size_t length)
|
||||||
{
|
{
|
||||||
VALUE req = (VALUE)data;
|
VALUE req = hp->request;
|
||||||
VALUE temp = Qnil;
|
|
||||||
VALUE ctype = Qnil;
|
|
||||||
VALUE clen = Qnil;
|
|
||||||
char *colon = NULL;
|
|
||||||
|
|
||||||
clen = rb_hash_aref(req, global_http_content_length);
|
|
||||||
if(clen != Qnil) {
|
|
||||||
rb_hash_aset(req, global_content_length, clen);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctype = rb_hash_aref(req, global_http_content_type);
|
|
||||||
if(ctype != Qnil) {
|
|
||||||
rb_hash_aset(req, global_content_type, ctype);
|
|
||||||
}
|
|
||||||
|
|
||||||
rb_hash_aset(req, global_gateway_interface, global_gateway_interface_value);
|
|
||||||
if((temp = rb_hash_aref(req, global_http_host)) != Qnil) {
|
|
||||||
colon = memchr(RSTRING_PTR(temp), ':', RSTRING_LEN(temp));
|
|
||||||
if(colon != NULL) {
|
|
||||||
rb_hash_aset(req, global_server_name, rb_str_substr(temp, 0, colon - RSTRING_PTR(temp)));
|
|
||||||
rb_hash_aset(req, global_server_port,
|
|
||||||
rb_str_substr(temp, colon - RSTRING_PTR(temp)+1,
|
|
||||||
RSTRING_LEN(temp)));
|
|
||||||
} else {
|
|
||||||
rb_hash_aset(req, global_server_name, temp);
|
|
||||||
rb_hash_aset(req, global_server_port, global_port_80);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* grab the initial body and stuff it into an ivar */
|
/* grab the initial body and stuff it into an ivar */
|
||||||
rb_ivar_set(req, id_http_body, rb_str_new(at, length));
|
rb_ivar_set(req, id_http_body, rb_str_new(at, length));
|
||||||
rb_hash_aset(req, global_server_protocol, global_server_protocol_value);
|
|
||||||
rb_hash_aset(req, global_server_software, global_mongrel_version);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -328,10 +273,12 @@ void HttpParser_free(void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HttpParser_mark(http_parser* hp) {
|
||||||
|
if(hp->request) rb_gc_mark(hp->request);
|
||||||
|
}
|
||||||
|
|
||||||
VALUE HttpParser_alloc(VALUE klass)
|
VALUE HttpParser_alloc(VALUE klass)
|
||||||
{
|
{
|
||||||
VALUE obj;
|
|
||||||
http_parser *hp = ALLOC_N(http_parser, 1);
|
http_parser *hp = ALLOC_N(http_parser, 1);
|
||||||
TRACE();
|
TRACE();
|
||||||
hp->http_field = http_field;
|
hp->http_field = http_field;
|
||||||
|
@ -342,14 +289,13 @@ VALUE HttpParser_alloc(VALUE klass)
|
||||||
hp->query_string = query_string;
|
hp->query_string = query_string;
|
||||||
hp->http_version = http_version;
|
hp->http_version = http_version;
|
||||||
hp->header_done = header_done;
|
hp->header_done = header_done;
|
||||||
|
hp->request = Qnil;
|
||||||
|
|
||||||
http_parser_init(hp);
|
http_parser_init(hp);
|
||||||
|
|
||||||
obj = Data_Wrap_Struct(klass, NULL, HttpParser_free, hp);
|
return Data_Wrap_Struct(klass, HttpParser_mark, HttpParser_free, hp);
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* parser.new -> parser
|
* parser.new -> parser
|
||||||
|
@ -427,15 +373,16 @@ VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
|
||||||
DATA_GET(self, http_parser, http);
|
DATA_GET(self, http_parser, http);
|
||||||
|
|
||||||
from = FIX2INT(start);
|
from = FIX2INT(start);
|
||||||
dptr = RSTRING_PTR(data);
|
dptr = rb_extract_chars(data, &dlen);
|
||||||
dlen = RSTRING_LEN(data);
|
|
||||||
|
|
||||||
if(from >= dlen) {
|
if(from >= dlen) {
|
||||||
|
rb_free_chars(dptr);
|
||||||
rb_raise(eHttpParserError, "Requested start is after data buffer end.");
|
rb_raise(eHttpParserError, "Requested start is after data buffer end.");
|
||||||
} else {
|
} else {
|
||||||
http->data = (void *)req_hash;
|
http->request = req_hash;
|
||||||
http_parser_execute(http, dptr, dlen, from);
|
http_parser_execute(http, dptr, dlen, from);
|
||||||
|
|
||||||
|
rb_free_chars(dptr);
|
||||||
VALIDATE_MAX_LENGTH(http_parser_nread(http), HEADER);
|
VALIDATE_MAX_LENGTH(http_parser_nread(http), HEADER);
|
||||||
|
|
||||||
if(http_parser_has_error(http)) {
|
if(http_parser_has_error(http)) {
|
||||||
|
@ -496,7 +443,7 @@ VALUE HttpParser_nread(VALUE self)
|
||||||
void Init_http11()
|
void Init_http11()
|
||||||
{
|
{
|
||||||
|
|
||||||
mMongrel = rb_define_module("Mongrel");
|
VALUE mMongrel = rb_define_module("Mongrel");
|
||||||
|
|
||||||
DEF_GLOBAL(request_method, "REQUEST_METHOD");
|
DEF_GLOBAL(request_method, "REQUEST_METHOD");
|
||||||
DEF_GLOBAL(request_uri, "REQUEST_URI");
|
DEF_GLOBAL(request_uri, "REQUEST_URI");
|
||||||
|
@ -504,24 +451,11 @@ void Init_http11()
|
||||||
DEF_GLOBAL(query_string, "QUERY_STRING");
|
DEF_GLOBAL(query_string, "QUERY_STRING");
|
||||||
DEF_GLOBAL(http_version, "HTTP_VERSION");
|
DEF_GLOBAL(http_version, "HTTP_VERSION");
|
||||||
DEF_GLOBAL(request_path, "REQUEST_PATH");
|
DEF_GLOBAL(request_path, "REQUEST_PATH");
|
||||||
DEF_GLOBAL(content_length, "CONTENT_LENGTH");
|
|
||||||
DEF_GLOBAL(http_content_length, "HTTP_CONTENT_LENGTH");
|
|
||||||
DEF_GLOBAL(content_type, "CONTENT_TYPE");
|
|
||||||
DEF_GLOBAL(http_content_type, "HTTP_CONTENT_TYPE");
|
|
||||||
DEF_GLOBAL(gateway_interface, "GATEWAY_INTERFACE");
|
|
||||||
DEF_GLOBAL(gateway_interface_value, "CGI/1.2");
|
|
||||||
DEF_GLOBAL(server_name, "SERVER_NAME");
|
|
||||||
DEF_GLOBAL(server_port, "SERVER_PORT");
|
|
||||||
DEF_GLOBAL(server_protocol, "SERVER_PROTOCOL");
|
|
||||||
DEF_GLOBAL(server_protocol_value, "HTTP/1.1");
|
|
||||||
DEF_GLOBAL(http_host, "HTTP_HOST");
|
|
||||||
DEF_GLOBAL(mongrel_version, "Mongrel 1.2.0.beta.1"); /* XXX Why is this defined here? */
|
|
||||||
DEF_GLOBAL(server_software, "SERVER_SOFTWARE");
|
|
||||||
DEF_GLOBAL(port_80, "80");
|
|
||||||
|
|
||||||
eHttpParserError = rb_define_class_under(mMongrel, "HttpParserError", rb_eIOError);
|
eHttpParserError = rb_define_class_under(mMongrel, "HttpParserError", rb_eIOError);
|
||||||
|
rb_global_variable(&eHttpParserError);
|
||||||
|
|
||||||
cHttpParser = rb_define_class_under(mMongrel, "HttpParser", rb_cObject);
|
VALUE cHttpParser = rb_define_class_under(mMongrel, "HttpParser", rb_cObject);
|
||||||
rb_define_alloc_func(cHttpParser, HttpParser_alloc);
|
rb_define_alloc_func(cHttpParser, HttpParser_alloc);
|
||||||
rb_define_method(cHttpParser, "initialize", HttpParser_init,0);
|
rb_define_method(cHttpParser, "initialize", HttpParser_init,0);
|
||||||
rb_define_method(cHttpParser, "reset", HttpParser_reset,0);
|
rb_define_method(cHttpParser, "reset", HttpParser_reset,0);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
#line 1 "ext/http11/http11_parser.rl"
|
#line 1 "ext/http11/http11_parser.rl"
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2005 Zed A. Shaw
|
* Copyright (c) 2005 Zed A. Shaw
|
||||||
|
@ -28,28 +29,31 @@ static void snake_upcase_char(char *c)
|
||||||
|
|
||||||
/** Machine **/
|
/** Machine **/
|
||||||
|
|
||||||
#line 87 "ext/http11/http11_parser.rl"
|
|
||||||
|
#line 78 "ext/http11/http11_parser.rl"
|
||||||
|
|
||||||
|
|
||||||
/** Data **/
|
/** Data **/
|
||||||
|
|
||||||
#line 37 "ext/http11/http11_parser.c"
|
#line 39 "ext/http11/http11_parser.c"
|
||||||
static const int http_parser_start = 1;
|
static const int http_parser_start = 1;
|
||||||
static const int http_parser_first_final = 57;
|
static const int http_parser_first_final = 57;
|
||||||
static const int http_parser_error = 0;
|
static const int http_parser_error = 0;
|
||||||
|
|
||||||
static const int http_parser_en_main = 1;
|
static const int http_parser_en_main = 1;
|
||||||
|
|
||||||
#line 91 "ext/http11/http11_parser.rl"
|
|
||||||
|
#line 82 "ext/http11/http11_parser.rl"
|
||||||
|
|
||||||
int http_parser_init(http_parser *parser) {
|
int http_parser_init(http_parser *parser) {
|
||||||
int cs = 0;
|
int cs = 0;
|
||||||
|
|
||||||
#line 49 "ext/http11/http11_parser.c"
|
#line 52 "ext/http11/http11_parser.c"
|
||||||
{
|
{
|
||||||
cs = http_parser_start;
|
cs = http_parser_start;
|
||||||
}
|
}
|
||||||
#line 95 "ext/http11/http11_parser.rl"
|
|
||||||
|
#line 86 "ext/http11/http11_parser.rl"
|
||||||
parser->cs = cs;
|
parser->cs = cs;
|
||||||
parser->body_start = 0;
|
parser->body_start = 0;
|
||||||
parser->content_len = 0;
|
parser->content_len = 0;
|
||||||
|
@ -57,8 +61,9 @@ int http_parser_init(http_parser *parser) {
|
||||||
parser->nread = 0;
|
parser->nread = 0;
|
||||||
parser->field_len = 0;
|
parser->field_len = 0;
|
||||||
parser->field_start = 0;
|
parser->field_start = 0;
|
||||||
|
parser->request = Qnil;
|
||||||
|
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +81,7 @@ size_t http_parser_execute(http_parser *parser, const char *buffer, size_t len,
|
||||||
assert(pe - p == len - off && "pointers aren't same distance");
|
assert(pe - p == len - off && "pointers aren't same distance");
|
||||||
|
|
||||||
|
|
||||||
#line 80 "ext/http11/http11_parser.c"
|
#line 85 "ext/http11/http11_parser.c"
|
||||||
{
|
{
|
||||||
if ( p == pe )
|
if ( p == pe )
|
||||||
goto _test_eof;
|
goto _test_eof;
|
||||||
|
@ -107,7 +112,7 @@ st2:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof2;
|
goto _test_eof2;
|
||||||
case 2:
|
case 2:
|
||||||
#line 111 "ext/http11/http11_parser.c"
|
#line 116 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 32: goto tr2;
|
case 32: goto tr2;
|
||||||
case 36: goto st38;
|
case 36: goto st38;
|
||||||
|
@ -123,17 +128,16 @@ case 2:
|
||||||
goto st38;
|
goto st38;
|
||||||
goto st0;
|
goto st0;
|
||||||
tr2:
|
tr2:
|
||||||
#line 49 "ext/http11/http11_parser.rl"
|
#line 47 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_method != NULL)
|
parser->request_method(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->request_method(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st3;
|
goto st3;
|
||||||
st3:
|
st3:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof3;
|
goto _test_eof3;
|
||||||
case 3:
|
case 3:
|
||||||
#line 137 "ext/http11/http11_parser.c"
|
#line 141 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 42: goto tr4;
|
case 42: goto tr4;
|
||||||
case 43: goto tr5;
|
case 43: goto tr5;
|
||||||
|
@ -157,78 +161,69 @@ st4:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof4;
|
goto _test_eof4;
|
||||||
case 4:
|
case 4:
|
||||||
#line 161 "ext/http11/http11_parser.c"
|
#line 165 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 32: goto tr8;
|
case 32: goto tr8;
|
||||||
case 35: goto tr9;
|
case 35: goto tr9;
|
||||||
}
|
}
|
||||||
goto st0;
|
goto st0;
|
||||||
tr8:
|
tr8:
|
||||||
#line 53 "ext/http11/http11_parser.rl"
|
#line 50 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_uri != NULL)
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st5;
|
goto st5;
|
||||||
tr31:
|
tr31:
|
||||||
#line 34 "ext/http11/http11_parser.rl"
|
#line 34 "ext/http11/http11_parser.rl"
|
||||||
{ MARK(mark, p); }
|
{ MARK(mark, p); }
|
||||||
#line 57 "ext/http11/http11_parser.rl"
|
#line 53 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->fragment != NULL)
|
parser->fragment(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->fragment(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st5;
|
goto st5;
|
||||||
tr34:
|
tr34:
|
||||||
#line 57 "ext/http11/http11_parser.rl"
|
#line 53 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->fragment != NULL)
|
parser->fragment(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->fragment(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st5;
|
goto st5;
|
||||||
tr42:
|
tr42:
|
||||||
#line 73 "ext/http11/http11_parser.rl"
|
#line 66 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_path != NULL)
|
parser->request_path(parser, PTR_TO(mark), LEN(mark,p));
|
||||||
parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
|
|
||||||
}
|
}
|
||||||
#line 53 "ext/http11/http11_parser.rl"
|
#line 50 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_uri != NULL)
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st5;
|
goto st5;
|
||||||
tr53:
|
tr53:
|
||||||
#line 62 "ext/http11/http11_parser.rl"
|
#line 57 "ext/http11/http11_parser.rl"
|
||||||
{ MARK(query_start, p); }
|
{ MARK(query_start, p); }
|
||||||
#line 63 "ext/http11/http11_parser.rl"
|
#line 58 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->query_string != NULL)
|
parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p));
|
||||||
parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
|
|
||||||
}
|
}
|
||||||
#line 53 "ext/http11/http11_parser.rl"
|
#line 50 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_uri != NULL)
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st5;
|
goto st5;
|
||||||
tr57:
|
tr57:
|
||||||
#line 63 "ext/http11/http11_parser.rl"
|
#line 58 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->query_string != NULL)
|
parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p));
|
||||||
parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
|
|
||||||
}
|
}
|
||||||
#line 53 "ext/http11/http11_parser.rl"
|
#line 50 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_uri != NULL)
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st5;
|
goto st5;
|
||||||
st5:
|
st5:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof5;
|
goto _test_eof5;
|
||||||
case 5:
|
case 5:
|
||||||
#line 232 "ext/http11/http11_parser.c"
|
#line 227 "ext/http11/http11_parser.c"
|
||||||
if ( (*p) == 72 )
|
if ( (*p) == 72 )
|
||||||
goto tr10;
|
goto tr10;
|
||||||
goto st0;
|
goto st0;
|
||||||
|
@ -240,7 +235,7 @@ st6:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof6;
|
goto _test_eof6;
|
||||||
case 6:
|
case 6:
|
||||||
#line 244 "ext/http11/http11_parser.c"
|
#line 239 "ext/http11/http11_parser.c"
|
||||||
if ( (*p) == 84 )
|
if ( (*p) == 84 )
|
||||||
goto st7;
|
goto st7;
|
||||||
goto st0;
|
goto st0;
|
||||||
|
@ -298,10 +293,9 @@ case 13:
|
||||||
goto st13;
|
goto st13;
|
||||||
goto st0;
|
goto st0;
|
||||||
tr18:
|
tr18:
|
||||||
#line 68 "ext/http11/http11_parser.rl"
|
#line 62 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->http_version != NULL)
|
parser->http_version(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->http_version(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st14;
|
goto st14;
|
||||||
tr26:
|
tr26:
|
||||||
|
@ -309,24 +303,20 @@ tr26:
|
||||||
{ MARK(mark, p); }
|
{ MARK(mark, p); }
|
||||||
#line 44 "ext/http11/http11_parser.rl"
|
#line 44 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->http_field != NULL) {
|
parser->http_field(parser, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
goto st14;
|
goto st14;
|
||||||
tr29:
|
tr29:
|
||||||
#line 44 "ext/http11/http11_parser.rl"
|
#line 44 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->http_field != NULL) {
|
parser->http_field(parser, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
goto st14;
|
goto st14;
|
||||||
st14:
|
st14:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof14;
|
goto _test_eof14;
|
||||||
case 14:
|
case 14:
|
||||||
#line 330 "ext/http11/http11_parser.c"
|
#line 320 "ext/http11/http11_parser.c"
|
||||||
if ( (*p) == 10 )
|
if ( (*p) == 10 )
|
||||||
goto st15;
|
goto st15;
|
||||||
goto st0;
|
goto st0;
|
||||||
|
@ -366,11 +356,10 @@ case 16:
|
||||||
goto tr22;
|
goto tr22;
|
||||||
goto st0;
|
goto st0;
|
||||||
tr22:
|
tr22:
|
||||||
#line 78 "ext/http11/http11_parser.rl"
|
#line 70 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
parser->body_start = p - buffer + 1;
|
parser->body_start = p - buffer + 1;
|
||||||
if(parser->header_done != NULL)
|
parser->header_done(parser, p + 1, pe - p - 1);
|
||||||
parser->header_done(parser->data, p + 1, pe - p - 1);
|
|
||||||
{p++; cs = 57; goto _out;}
|
{p++; cs = 57; goto _out;}
|
||||||
}
|
}
|
||||||
goto st57;
|
goto st57;
|
||||||
|
@ -378,7 +367,7 @@ st57:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof57;
|
goto _test_eof57;
|
||||||
case 57:
|
case 57:
|
||||||
#line 382 "ext/http11/http11_parser.c"
|
#line 371 "ext/http11/http11_parser.c"
|
||||||
goto st0;
|
goto st0;
|
||||||
tr21:
|
tr21:
|
||||||
#line 37 "ext/http11/http11_parser.rl"
|
#line 37 "ext/http11/http11_parser.rl"
|
||||||
|
@ -394,7 +383,7 @@ st17:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof17;
|
goto _test_eof17;
|
||||||
case 17:
|
case 17:
|
||||||
#line 398 "ext/http11/http11_parser.c"
|
#line 387 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 33: goto tr23;
|
case 33: goto tr23;
|
||||||
case 58: goto tr24;
|
case 58: goto tr24;
|
||||||
|
@ -433,7 +422,7 @@ st18:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof18;
|
goto _test_eof18;
|
||||||
case 18:
|
case 18:
|
||||||
#line 437 "ext/http11/http11_parser.c"
|
#line 426 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 13: goto tr26;
|
case 13: goto tr26;
|
||||||
case 32: goto tr27;
|
case 32: goto tr27;
|
||||||
|
@ -447,60 +436,53 @@ st19:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof19;
|
goto _test_eof19;
|
||||||
case 19:
|
case 19:
|
||||||
#line 451 "ext/http11/http11_parser.c"
|
#line 440 "ext/http11/http11_parser.c"
|
||||||
if ( (*p) == 13 )
|
if ( (*p) == 13 )
|
||||||
goto tr29;
|
goto tr29;
|
||||||
goto st19;
|
goto st19;
|
||||||
tr9:
|
tr9:
|
||||||
#line 53 "ext/http11/http11_parser.rl"
|
#line 50 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_uri != NULL)
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st20;
|
goto st20;
|
||||||
tr43:
|
tr43:
|
||||||
#line 73 "ext/http11/http11_parser.rl"
|
#line 66 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_path != NULL)
|
parser->request_path(parser, PTR_TO(mark), LEN(mark,p));
|
||||||
parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
|
|
||||||
}
|
}
|
||||||
#line 53 "ext/http11/http11_parser.rl"
|
#line 50 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_uri != NULL)
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st20;
|
goto st20;
|
||||||
tr54:
|
tr54:
|
||||||
#line 62 "ext/http11/http11_parser.rl"
|
#line 57 "ext/http11/http11_parser.rl"
|
||||||
{ MARK(query_start, p); }
|
{ MARK(query_start, p); }
|
||||||
#line 63 "ext/http11/http11_parser.rl"
|
#line 58 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->query_string != NULL)
|
parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p));
|
||||||
parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
|
|
||||||
}
|
}
|
||||||
#line 53 "ext/http11/http11_parser.rl"
|
#line 50 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_uri != NULL)
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st20;
|
goto st20;
|
||||||
tr58:
|
tr58:
|
||||||
#line 63 "ext/http11/http11_parser.rl"
|
#line 58 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->query_string != NULL)
|
parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p));
|
||||||
parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p));
|
|
||||||
}
|
}
|
||||||
#line 53 "ext/http11/http11_parser.rl"
|
#line 50 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_uri != NULL)
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
|
||||||
parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p));
|
|
||||||
}
|
}
|
||||||
goto st20;
|
goto st20;
|
||||||
st20:
|
st20:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof20;
|
goto _test_eof20;
|
||||||
case 20:
|
case 20:
|
||||||
#line 504 "ext/http11/http11_parser.c"
|
#line 486 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 32: goto tr31;
|
case 32: goto tr31;
|
||||||
case 37: goto tr32;
|
case 37: goto tr32;
|
||||||
|
@ -522,7 +504,7 @@ st21:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof21;
|
goto _test_eof21;
|
||||||
case 21:
|
case 21:
|
||||||
#line 526 "ext/http11/http11_parser.c"
|
#line 508 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 32: goto tr34;
|
case 32: goto tr34;
|
||||||
case 37: goto st22;
|
case 37: goto st22;
|
||||||
|
@ -544,7 +526,7 @@ st22:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof22;
|
goto _test_eof22;
|
||||||
case 22:
|
case 22:
|
||||||
#line 548 "ext/http11/http11_parser.c"
|
#line 530 "ext/http11/http11_parser.c"
|
||||||
if ( (*p) < 65 ) {
|
if ( (*p) < 65 ) {
|
||||||
if ( 48 <= (*p) && (*p) <= 57 )
|
if ( 48 <= (*p) && (*p) <= 57 )
|
||||||
goto st23;
|
goto st23;
|
||||||
|
@ -575,7 +557,7 @@ st24:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof24;
|
goto _test_eof24;
|
||||||
case 24:
|
case 24:
|
||||||
#line 579 "ext/http11/http11_parser.c"
|
#line 561 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 43: goto st24;
|
case 43: goto st24;
|
||||||
case 58: goto st25;
|
case 58: goto st25;
|
||||||
|
@ -600,7 +582,7 @@ st25:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof25;
|
goto _test_eof25;
|
||||||
case 25:
|
case 25:
|
||||||
#line 604 "ext/http11/http11_parser.c"
|
#line 586 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 32: goto tr8;
|
case 32: goto tr8;
|
||||||
case 34: goto st0;
|
case 34: goto st0;
|
||||||
|
@ -647,7 +629,7 @@ st28:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof28;
|
goto _test_eof28;
|
||||||
case 28:
|
case 28:
|
||||||
#line 651 "ext/http11/http11_parser.c"
|
#line 633 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 32: goto tr42;
|
case 32: goto tr42;
|
||||||
case 34: goto st0;
|
case 34: goto st0;
|
||||||
|
@ -689,17 +671,16 @@ case 30:
|
||||||
goto st28;
|
goto st28;
|
||||||
goto st0;
|
goto st0;
|
||||||
tr45:
|
tr45:
|
||||||
#line 73 "ext/http11/http11_parser.rl"
|
#line 66 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_path != NULL)
|
parser->request_path(parser, PTR_TO(mark), LEN(mark,p));
|
||||||
parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
|
|
||||||
}
|
}
|
||||||
goto st31;
|
goto st31;
|
||||||
st31:
|
st31:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof31;
|
goto _test_eof31;
|
||||||
case 31:
|
case 31:
|
||||||
#line 703 "ext/http11/http11_parser.c"
|
#line 684 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 32: goto tr8;
|
case 32: goto tr8;
|
||||||
case 34: goto st0;
|
case 34: goto st0;
|
||||||
|
@ -740,17 +721,16 @@ case 33:
|
||||||
goto st31;
|
goto st31;
|
||||||
goto st0;
|
goto st0;
|
||||||
tr46:
|
tr46:
|
||||||
#line 73 "ext/http11/http11_parser.rl"
|
#line 66 "ext/http11/http11_parser.rl"
|
||||||
{
|
{
|
||||||
if(parser->request_path != NULL)
|
parser->request_path(parser, PTR_TO(mark), LEN(mark,p));
|
||||||
parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p));
|
|
||||||
}
|
}
|
||||||
goto st34;
|
goto st34;
|
||||||
st34:
|
st34:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof34;
|
goto _test_eof34;
|
||||||
case 34:
|
case 34:
|
||||||
#line 754 "ext/http11/http11_parser.c"
|
#line 734 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 32: goto tr53;
|
case 32: goto tr53;
|
||||||
case 34: goto st0;
|
case 34: goto st0;
|
||||||
|
@ -764,14 +744,14 @@ case 34:
|
||||||
goto st0;
|
goto st0;
|
||||||
goto tr52;
|
goto tr52;
|
||||||
tr52:
|
tr52:
|
||||||
#line 62 "ext/http11/http11_parser.rl"
|
#line 57 "ext/http11/http11_parser.rl"
|
||||||
{ MARK(query_start, p); }
|
{ MARK(query_start, p); }
|
||||||
goto st35;
|
goto st35;
|
||||||
st35:
|
st35:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof35;
|
goto _test_eof35;
|
||||||
case 35:
|
case 35:
|
||||||
#line 775 "ext/http11/http11_parser.c"
|
#line 755 "ext/http11/http11_parser.c"
|
||||||
switch( (*p) ) {
|
switch( (*p) ) {
|
||||||
case 32: goto tr57;
|
case 32: goto tr57;
|
||||||
case 34: goto st0;
|
case 34: goto st0;
|
||||||
|
@ -785,14 +765,14 @@ case 35:
|
||||||
goto st0;
|
goto st0;
|
||||||
goto st35;
|
goto st35;
|
||||||
tr55:
|
tr55:
|
||||||
#line 62 "ext/http11/http11_parser.rl"
|
#line 57 "ext/http11/http11_parser.rl"
|
||||||
{ MARK(query_start, p); }
|
{ MARK(query_start, p); }
|
||||||
goto st36;
|
goto st36;
|
||||||
st36:
|
st36:
|
||||||
if ( ++p == pe )
|
if ( ++p == pe )
|
||||||
goto _test_eof36;
|
goto _test_eof36;
|
||||||
case 36:
|
case 36:
|
||||||
#line 796 "ext/http11/http11_parser.c"
|
#line 776 "ext/http11/http11_parser.c"
|
||||||
if ( (*p) < 65 ) {
|
if ( (*p) < 65 ) {
|
||||||
if ( 48 <= (*p) && (*p) <= 57 )
|
if ( 48 <= (*p) && (*p) <= 57 )
|
||||||
goto st37;
|
goto st37;
|
||||||
|
@ -1207,7 +1187,8 @@ case 56:
|
||||||
_test_eof: {}
|
_test_eof: {}
|
||||||
_out: {}
|
_out: {}
|
||||||
}
|
}
|
||||||
#line 121 "ext/http11/http11_parser.rl"
|
|
||||||
|
#line 113 "ext/http11/http11_parser.rl"
|
||||||
|
|
||||||
if (!http_parser_has_error(parser))
|
if (!http_parser_has_error(parser))
|
||||||
parser->cs = cs;
|
parser->cs = cs;
|
||||||
|
|
|
@ -6,14 +6,24 @@
|
||||||
#ifndef http11_parser_h
|
#ifndef http11_parser_h
|
||||||
#define http11_parser_h
|
#define http11_parser_h
|
||||||
|
|
||||||
|
#include "ruby.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void (*element_cb)(void *data, const char *at, size_t length);
|
#define BUFFER_LEN 1024
|
||||||
typedef void (*field_cb)(void *data, const char *field, size_t flen, const char *value, size_t vlen);
|
|
||||||
|
struct http_parser;
|
||||||
|
|
||||||
|
typedef void (*element_cb)(struct http_parser* hp,
|
||||||
|
const char *at, size_t length);
|
||||||
|
|
||||||
|
typedef void (*field_cb)(struct http_parser* hp,
|
||||||
|
const char *field, size_t flen,
|
||||||
|
const char *value, size_t vlen);
|
||||||
|
|
||||||
typedef struct http_parser {
|
typedef struct http_parser {
|
||||||
int cs;
|
int cs;
|
||||||
|
@ -25,7 +35,7 @@ typedef struct http_parser {
|
||||||
size_t field_len;
|
size_t field_len;
|
||||||
size_t query_start;
|
size_t query_start;
|
||||||
|
|
||||||
void *data;
|
VALUE request;
|
||||||
|
|
||||||
field_cb http_field;
|
field_cb http_field;
|
||||||
element_cb request_method;
|
element_cb request_method;
|
||||||
|
@ -36,11 +46,14 @@ typedef struct http_parser {
|
||||||
element_cb http_version;
|
element_cb http_version;
|
||||||
element_cb header_done;
|
element_cb header_done;
|
||||||
|
|
||||||
|
char buf[BUFFER_LEN];
|
||||||
|
|
||||||
} http_parser;
|
} http_parser;
|
||||||
|
|
||||||
int http_parser_init(http_parser *parser);
|
int http_parser_init(http_parser *parser);
|
||||||
int http_parser_finish(http_parser *parser);
|
int http_parser_finish(http_parser *parser);
|
||||||
size_t http_parser_execute(http_parser *parser, const char *data, size_t len, size_t off);
|
size_t http_parser_execute(http_parser *parser, const char *data,
|
||||||
|
size_t len, size_t off);
|
||||||
int http_parser_has_error(http_parser *parser);
|
int http_parser_has_error(http_parser *parser);
|
||||||
int http_parser_is_finished(http_parser *parser);
|
int http_parser_is_finished(http_parser *parser);
|
||||||
|
|
||||||
|
|
|
@ -42,43 +42,34 @@ static void snake_upcase_char(char *c)
|
||||||
|
|
||||||
action start_value { MARK(mark, fpc); }
|
action start_value { MARK(mark, fpc); }
|
||||||
action write_value {
|
action write_value {
|
||||||
if(parser->http_field != NULL) {
|
parser->http_field(parser, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, fpc));
|
||||||
parser->http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, fpc));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
action request_method {
|
action request_method {
|
||||||
if(parser->request_method != NULL)
|
parser->request_method(parser, PTR_TO(mark), LEN(mark, fpc));
|
||||||
parser->request_method(parser->data, PTR_TO(mark), LEN(mark, fpc));
|
|
||||||
}
|
}
|
||||||
action request_uri {
|
action request_uri {
|
||||||
if(parser->request_uri != NULL)
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, fpc));
|
||||||
parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, fpc));
|
|
||||||
}
|
}
|
||||||
action fragment {
|
action fragment {
|
||||||
if(parser->fragment != NULL)
|
parser->fragment(parser, PTR_TO(mark), LEN(mark, fpc));
|
||||||
parser->fragment(parser->data, PTR_TO(mark), LEN(mark, fpc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
action start_query { MARK(query_start, fpc); }
|
action start_query { MARK(query_start, fpc); }
|
||||||
action query_string {
|
action query_string {
|
||||||
if(parser->query_string != NULL)
|
parser->query_string(parser, PTR_TO(query_start), LEN(query_start, fpc));
|
||||||
parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, fpc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
action http_version {
|
action http_version {
|
||||||
if(parser->http_version != NULL)
|
parser->http_version(parser, PTR_TO(mark), LEN(mark, fpc));
|
||||||
parser->http_version(parser->data, PTR_TO(mark), LEN(mark, fpc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
action request_path {
|
action request_path {
|
||||||
if(parser->request_path != NULL)
|
parser->request_path(parser, PTR_TO(mark), LEN(mark,fpc));
|
||||||
parser->request_path(parser->data, PTR_TO(mark), LEN(mark,fpc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
action done {
|
action done {
|
||||||
parser->body_start = fpc - buffer + 1;
|
parser->body_start = fpc - buffer + 1;
|
||||||
if(parser->header_done != NULL)
|
parser->header_done(parser, fpc + 1, pe - fpc - 1);
|
||||||
parser->header_done(parser->data, fpc + 1, pe - fpc - 1);
|
|
||||||
fbreak;
|
fbreak;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +90,9 @@ int http_parser_init(http_parser *parser) {
|
||||||
parser->nread = 0;
|
parser->nread = 0;
|
||||||
parser->field_len = 0;
|
parser->field_len = 0;
|
||||||
parser->field_start = 0;
|
parser->field_start = 0;
|
||||||
|
parser->request = Qnil;
|
||||||
|
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,6 @@ end
|
||||||
|
|
||||||
# Gem conditional loader
|
# Gem conditional loader
|
||||||
require 'mongrel/gems'
|
require 'mongrel/gems'
|
||||||
Mongrel::Gems.require 'cgi_multipart_eof_fix'
|
|
||||||
Mongrel::Gems.require 'fastthread'
|
|
||||||
require 'thread'
|
require 'thread'
|
||||||
|
|
||||||
# Ruby Mongrel
|
# Ruby Mongrel
|
||||||
|
@ -71,6 +69,9 @@ module Mongrel
|
||||||
# releases of Mongrel will find other creative ways to make threads faster, but don't
|
# releases of Mongrel will find other creative ways to make threads faster, but don't
|
||||||
# hold your breath until Ruby 1.9 is actually finally useful.
|
# hold your breath until Ruby 1.9 is actually finally useful.
|
||||||
class HttpServer
|
class HttpServer
|
||||||
|
|
||||||
|
include Mongrel::Const
|
||||||
|
|
||||||
attr_reader :acceptor
|
attr_reader :acceptor
|
||||||
attr_reader :workers
|
attr_reader :workers
|
||||||
attr_reader :classifier
|
attr_reader :classifier
|
||||||
|
@ -117,7 +118,7 @@ module Mongrel
|
||||||
parser = HttpParser.new
|
parser = HttpParser.new
|
||||||
params = HttpParams.new
|
params = HttpParams.new
|
||||||
request = nil
|
request = nil
|
||||||
data = client.readpartial(Const::CHUNK_SIZE)
|
data = client.readpartial(CHUNK_SIZE)
|
||||||
nparsed = 0
|
nparsed = 0
|
||||||
|
|
||||||
# Assumption: nparsed will always be less since data will get filled with more
|
# Assumption: nparsed will always be less since data will get filled with more
|
||||||
|
@ -128,19 +129,42 @@ module Mongrel
|
||||||
nparsed = parser.execute(params, data, nparsed)
|
nparsed = parser.execute(params, data, nparsed)
|
||||||
|
|
||||||
if parser.finished?
|
if parser.finished?
|
||||||
if not params[Const::REQUEST_PATH]
|
|
||||||
# it might be a dumbass full host request header
|
if host = params[HTTP_HOST]
|
||||||
uri = URI.parse(params[Const::REQUEST_URI])
|
if colon = host.index(":")
|
||||||
params[Const::REQUEST_PATH] = uri.path
|
params[SERVER_NAME] = host[0, colon]
|
||||||
|
params[SERVER_PORT] = host[colon+1, host.size]
|
||||||
|
else
|
||||||
|
params[SERVER_NAME] = host
|
||||||
|
params[SERVER_PORT] = PORT_80
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
raise "No REQUEST PATH" if not params[Const::REQUEST_PATH]
|
if len = params[HTTP_CONTENT_LENGTH]
|
||||||
|
params[CONTENT_LENGTH] = len
|
||||||
|
end
|
||||||
|
|
||||||
script_name, path_info, handlers = @classifier.resolve(params[Const::REQUEST_PATH])
|
if type = params[HTTP_CONTENT_TYPE]
|
||||||
|
params[RAW_CONTENT_TYPE] = type
|
||||||
|
end
|
||||||
|
|
||||||
|
params[SERVER_PROTOCOL] = HTTP_11
|
||||||
|
params[SERVER_SOFTWARE] = MONGREL_VERSION
|
||||||
|
params[GATEWAY_INTERFACE] = CGI_VER
|
||||||
|
|
||||||
|
if not params[REQUEST_PATH]
|
||||||
|
# it might be a dumbass full host request header
|
||||||
|
uri = URI.parse(params[REQUEST_URI])
|
||||||
|
params[REQUEST_PATH] = uri.path
|
||||||
|
end
|
||||||
|
|
||||||
|
raise "No REQUEST PATH" if not params[REQUEST_PATH]
|
||||||
|
|
||||||
|
script_name, path_info, handlers = @classifier.resolve(params[REQUEST_PATH])
|
||||||
|
|
||||||
if handlers
|
if handlers
|
||||||
params[Const::PATH_INFO] = path_info
|
params[PATH_INFO] = path_info
|
||||||
params[Const::SCRIPT_NAME] = script_name
|
params[SCRIPT_NAME] = script_name
|
||||||
|
|
||||||
# From http://www.ietf.org/rfc/rfc3875 :
|
# From http://www.ietf.org/rfc/rfc3875 :
|
||||||
# "Script authors should be aware that the REMOTE_ADDR and REMOTE_HOST
|
# "Script authors should be aware that the REMOTE_ADDR and REMOTE_HOST
|
||||||
|
@ -148,7 +172,7 @@ module Mongrel
|
||||||
# ultimate source of the request. They identify the client for the
|
# ultimate source of the request. They identify the client for the
|
||||||
# immediate request to the server; that client may be a proxy, gateway,
|
# immediate request to the server; that client may be a proxy, gateway,
|
||||||
# or other intermediary acting on behalf of the actual source client."
|
# or other intermediary acting on behalf of the actual source client."
|
||||||
params[Const::REMOTE_ADDR] = client.peeraddr.last
|
params[REMOTE_ADDR] = client.peeraddr.last
|
||||||
|
|
||||||
# select handlers that want more detailed request notification
|
# select handlers that want more detailed request notification
|
||||||
notifiers = handlers.select { |h| h.request_notify }
|
notifiers = handlers.select { |h| h.request_notify }
|
||||||
|
@ -172,17 +196,17 @@ module Mongrel
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
# Didn't find it, return a stock 404 response.
|
# Didn't find it, return a stock 404 response.
|
||||||
client.write(Const::ERROR_404_RESPONSE)
|
client.write(ERROR_404_RESPONSE)
|
||||||
end
|
end
|
||||||
|
|
||||||
break #done
|
break #done
|
||||||
else
|
else
|
||||||
# Parser is not done, queue up more data to read and continue parsing
|
# Parser is not done, queue up more data to read and continue parsing
|
||||||
chunk = client.readpartial(Const::CHUNK_SIZE)
|
chunk = client.readpartial(CHUNK_SIZE)
|
||||||
break if !chunk or chunk.length == 0 # read failed, stop processing
|
break if !chunk or chunk.length == 0 # read failed, stop processing
|
||||||
|
|
||||||
data << chunk
|
data << chunk
|
||||||
if data.length >= Const::MAX_HEADER
|
if data.length >= MAX_HEADER
|
||||||
raise HttpParserError.new("HEADER is longer than allowed, aborting client early.")
|
raise HttpParserError.new("HEADER is longer than allowed, aborting client early.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -190,7 +214,7 @@ module Mongrel
|
||||||
rescue EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
|
rescue EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
|
||||||
client.close rescue nil
|
client.close rescue nil
|
||||||
rescue HttpParserError => e
|
rescue HttpParserError => e
|
||||||
STDERR.puts "#{Time.now}: HTTP parse error, malformed request (#{params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last}): #{e.inspect}"
|
STDERR.puts "#{Time.now}: HTTP parse error, malformed request (#{params[HTTP_X_FORWARDED_FOR] || client.peeraddr.last}): #{e.inspect}"
|
||||||
STDERR.puts "#{Time.now}: REQUEST DATA: #{data.inspect}\n---\nPARAMS: #{params.inspect}\n---\n"
|
STDERR.puts "#{Time.now}: REQUEST DATA: #{data.inspect}\n---\nPARAMS: #{params.inspect}\n---\n"
|
||||||
rescue Errno::EMFILE
|
rescue Errno::EMFILE
|
||||||
reap_dead_workers('too many files')
|
reap_dead_workers('too many files')
|
||||||
|
@ -244,18 +268,22 @@ module Mongrel
|
||||||
end
|
end
|
||||||
|
|
||||||
def configure_socket_options
|
def configure_socket_options
|
||||||
|
@tcp_defer_accept_opts = nil
|
||||||
|
@tcp_cork_opts = nil
|
||||||
|
|
||||||
case RUBY_PLATFORM
|
case RUBY_PLATFORM
|
||||||
when /linux/
|
when /linux/
|
||||||
# 9 is currently TCP_DEFER_ACCEPT
|
# 9 is currently TCP_DEFER_ACCEPT
|
||||||
$tcp_defer_accept_opts = [Socket::SOL_TCP, 9, 1]
|
@tcp_defer_accept_opts = [Socket::SOL_TCP, 9, 1]
|
||||||
$tcp_cork_opts = [Socket::SOL_TCP, 3, 1]
|
@tcp_cork_opts = [Socket::SOL_TCP, 3, 1]
|
||||||
|
|
||||||
when /freebsd(([1-4]\..{1,2})|5\.[0-4])/
|
when /freebsd(([1-4]\..{1,2})|5\.[0-4])/
|
||||||
# Do nothing, just closing a bug when freebsd <= 5.4
|
# Do nothing, just closing a bug when freebsd <= 5.4
|
||||||
when /freebsd/
|
when /freebsd/
|
||||||
# Use the HTTP accept filter if available.
|
# Use the HTTP accept filter if available.
|
||||||
# The struct made by pack() is defined in /usr/include/sys/socket.h as accept_filter_arg
|
# The struct made by pack() is defined in /usr/include/sys/socket.h as accept_filter_arg
|
||||||
unless `/sbin/sysctl -nq net.inet.accf.http`.empty?
|
unless `/sbin/sysctl -nq net.inet.accf.http`.empty?
|
||||||
$tcp_defer_accept_opts = [Socket::SOL_SOCKET, Socket::SO_ACCEPTFILTER, ['httpready', nil].pack('a16a240')]
|
@tcp_defer_accept_opts = [Socket::SOL_SOCKET, Socket::SO_ACCEPTFILTER, ['httpready', nil].pack('a16a240')]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -267,19 +295,19 @@ module Mongrel
|
||||||
|
|
||||||
configure_socket_options
|
configure_socket_options
|
||||||
|
|
||||||
if defined?($tcp_defer_accept_opts) and $tcp_defer_accept_opts
|
if @tcp_defer_accept_opts
|
||||||
@socket.setsockopt(*$tcp_defer_accept_opts) rescue nil
|
@socket.setsockopt(*@tcp_defer_accept_opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
tcp_cork_opts = @tcp_cork_opts
|
||||||
|
|
||||||
@acceptor = Thread.new do
|
@acceptor = Thread.new do
|
||||||
begin
|
begin
|
||||||
while true
|
while true
|
||||||
begin
|
begin
|
||||||
client = @socket.accept
|
client = @socket.accept
|
||||||
|
|
||||||
if defined?($tcp_cork_opts) and $tcp_cork_opts
|
client.setsockopt(*tcp_cork_opts) if tcp_cork_opts
|
||||||
client.setsockopt(*$tcp_cork_opts) rescue nil
|
|
||||||
end
|
|
||||||
|
|
||||||
worker_list = @workers.list
|
worker_list = @workers.list
|
||||||
|
|
||||||
|
@ -359,8 +387,4 @@ module Mongrel
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Load experimental library, if present. We put it here so it can override anything
|
|
||||||
# in regular Mongrel.
|
|
||||||
|
|
||||||
$LOAD_PATH.unshift 'projects/mongrel_experimental/lib/'
|
|
||||||
Mongrel::Gems.require 'mongrel_experimental', ">=#{Mongrel::Const::MONGREL_VERSION}"
|
Mongrel::Gems.require 'mongrel_experimental', ">=#{Mongrel::Const::MONGREL_VERSION}"
|
||||||
|
|
|
@ -53,29 +53,29 @@ module Mongrel
|
||||||
# REMOTE_USER, or REMOTE_HOST parameters since those are either a security problem or
|
# REMOTE_USER, or REMOTE_HOST parameters since those are either a security problem or
|
||||||
# too taxing on performance.
|
# too taxing on performance.
|
||||||
module Const
|
module Const
|
||||||
DATE = "Date".freeze
|
DATE = "Date"
|
||||||
|
|
||||||
# This is the part of the path after the SCRIPT_NAME. URIClassifier will determine this.
|
# This is the part of the path after the SCRIPT_NAME. URIClassifier will determine this.
|
||||||
PATH_INFO="PATH_INFO".freeze
|
PATH_INFO="PATH_INFO"
|
||||||
|
|
||||||
# This is the initial part that your handler is identified as by URIClassifier.
|
# This is the initial part that your handler is identified as by URIClassifier.
|
||||||
SCRIPT_NAME="SCRIPT_NAME".freeze
|
SCRIPT_NAME="SCRIPT_NAME"
|
||||||
|
|
||||||
# The original URI requested by the client. Passed to URIClassifier to build PATH_INFO and SCRIPT_NAME.
|
# The original URI requested by the client. Passed to URIClassifier to build PATH_INFO and SCRIPT_NAME.
|
||||||
REQUEST_URI='REQUEST_URI'.freeze
|
REQUEST_URI='REQUEST_URI'
|
||||||
REQUEST_PATH='REQUEST_PATH'.freeze
|
REQUEST_PATH='REQUEST_PATH'
|
||||||
|
|
||||||
MONGREL_VERSION = VERSION = "1.2.0.beta.1".freeze
|
MONGREL_VERSION = VERSION = "1.3.0"
|
||||||
|
|
||||||
MONGREL_TMP_BASE="mongrel".freeze
|
MONGREL_TMP_BASE="mongrel"
|
||||||
|
|
||||||
# The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
|
# The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
|
||||||
ERROR_404_RESPONSE="HTTP/1.1 404 Not Found\r\nConnection: close\r\nServer: Mongrel #{MONGREL_VERSION}\r\n\r\nNOT FOUND".freeze
|
ERROR_404_RESPONSE="HTTP/1.1 404 Not Found\r\nConnection: close\r\nServer: Mongrel #{MONGREL_VERSION}\r\n\r\nNOT FOUND"
|
||||||
|
|
||||||
CONTENT_LENGTH="CONTENT_LENGTH".freeze
|
CONTENT_LENGTH="CONTENT_LENGTH"
|
||||||
|
|
||||||
# A common header for indicating the server is too busy. Not used yet.
|
# A common header for indicating the server is too busy. Not used yet.
|
||||||
ERROR_503_RESPONSE="HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY".freeze
|
ERROR_503_RESPONSE="HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY"
|
||||||
|
|
||||||
# The basic max request size we'll try to read.
|
# The basic max request size we'll try to read.
|
||||||
CHUNK_SIZE=(16 * 1024)
|
CHUNK_SIZE=(16 * 1024)
|
||||||
|
@ -88,23 +88,40 @@ module Mongrel
|
||||||
MAX_BODY=MAX_HEADER
|
MAX_BODY=MAX_HEADER
|
||||||
|
|
||||||
# A frozen format for this is about 15% faster
|
# A frozen format for this is about 15% faster
|
||||||
STATUS_FORMAT = "HTTP/1.1 %d %s\r\nConnection: close\r\n".freeze
|
STATUS_FORMAT = "HTTP/1.1 %d %s\r\nConnection: close\r\n"
|
||||||
CONTENT_TYPE = "Content-Type".freeze
|
CONTENT_TYPE = "Content-Type"
|
||||||
LAST_MODIFIED = "Last-Modified".freeze
|
LAST_MODIFIED = "Last-Modified"
|
||||||
ETAG = "ETag".freeze
|
ETAG = "ETag"
|
||||||
SLASH = "/".freeze
|
SLASH = "/"
|
||||||
REQUEST_METHOD="REQUEST_METHOD".freeze
|
REQUEST_METHOD="REQUEST_METHOD"
|
||||||
GET="GET".freeze
|
GET="GET"
|
||||||
HEAD="HEAD".freeze
|
HEAD="HEAD"
|
||||||
# ETag is based on the apache standard of hex mtime-size-inode (inode is 0 on win32)
|
# ETag is based on the apache standard of hex mtime-size-inode (inode is 0 on win32)
|
||||||
ETAG_FORMAT="\"%x-%x-%x\"".freeze
|
ETAG_FORMAT="\"%x-%x-%x\""
|
||||||
HEADER_FORMAT="%s: %s\r\n".freeze
|
HEADER_FORMAT="%s: %s\r\n"
|
||||||
LINE_END="\r\n".freeze
|
LINE_END="\r\n"
|
||||||
REMOTE_ADDR="REMOTE_ADDR".freeze
|
REMOTE_ADDR="REMOTE_ADDR"
|
||||||
HTTP_X_FORWARDED_FOR="HTTP_X_FORWARDED_FOR".freeze
|
HTTP_X_FORWARDED_FOR="HTTP_X_FORWARDED_FOR"
|
||||||
HTTP_IF_MODIFIED_SINCE="HTTP_IF_MODIFIED_SINCE".freeze
|
HTTP_IF_MODIFIED_SINCE="HTTP_IF_MODIFIED_SINCE"
|
||||||
HTTP_IF_NONE_MATCH="HTTP_IF_NONE_MATCH".freeze
|
HTTP_IF_NONE_MATCH="HTTP_IF_NONE_MATCH"
|
||||||
REDIRECT = "HTTP/1.1 302 Found\r\nLocation: %s\r\nConnection: close\r\n\r\n".freeze
|
REDIRECT = "HTTP/1.1 302 Found\r\nLocation: %s\r\nConnection: close\r\n\r\n"
|
||||||
HOST = "HOST".freeze
|
HOST = "HOST"
|
||||||
|
|
||||||
|
SERVER_NAME = "SERVER_NAME"
|
||||||
|
SERVER_PORT = "SERVER_PORT"
|
||||||
|
HTTP_HOST = "HTTP_HOST"
|
||||||
|
PORT_80 = "80"
|
||||||
|
|
||||||
|
SERVER_PROTOCOL = "SERVER_PROTOCOL"
|
||||||
|
HTTP_11 = "HTTP/1.1"
|
||||||
|
|
||||||
|
SERVER_SOFTWARE = "SERVER_SOFTWARE"
|
||||||
|
GATEWAY_INTERFACE = "GATEWAY_INTERFACE"
|
||||||
|
CGI_VER = "CGI/1.2"
|
||||||
|
|
||||||
|
HTTP_CONTENT_LENGTH = "HTTP_CONTENT_LENGTH"
|
||||||
|
|
||||||
|
HTTP_CONTENT_TYPE = "HTTP_CONTENT_TYPE"
|
||||||
|
RAW_CONTENT_TYPE = "CONTENT_TYPE"
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -119,7 +119,7 @@ module Mongrel
|
||||||
|
|
||||||
# You give it the path to the directory root and and optional listing_allowed and index_html
|
# You give it the path to the directory root and and optional listing_allowed and index_html
|
||||||
def initialize(path, listing_allowed=true, index_html="index.html")
|
def initialize(path, listing_allowed=true, index_html="index.html")
|
||||||
@path = File.expand_path(path) if path
|
@path = (File.expand_path(path) if path)
|
||||||
@listing_allowed = listing_allowed
|
@listing_allowed = listing_allowed
|
||||||
@index_html = index_html
|
@index_html = index_html
|
||||||
@default_content_type = "application/octet-stream".freeze
|
@default_content_type = "application/octet-stream".freeze
|
||||||
|
|
|
@ -4,6 +4,7 @@ module Mongrel
|
||||||
|
|
||||||
class RegistrationError < RuntimeError
|
class RegistrationError < RuntimeError
|
||||||
end
|
end
|
||||||
|
|
||||||
class UsageError < RuntimeError
|
class UsageError < RuntimeError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -56,8 +57,6 @@ module Mongrel
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def rebuild
|
def rebuild
|
||||||
if @handler_map.size == 1 and @handler_map[Const::SLASH]
|
if @handler_map.size == 1 and @handler_map[Const::SLASH]
|
||||||
@root_handler = @handler_map.values.first
|
@root_handler = @handler_map.values.first
|
||||||
|
@ -66,11 +65,16 @@ module Mongrel
|
||||||
routes = @handler_map.keys.sort.sort_by do |uri|
|
routes = @handler_map.keys.sort.sort_by do |uri|
|
||||||
-uri.length
|
-uri.length
|
||||||
end
|
end
|
||||||
@matcher = Regexp.new(routes.map do |uri|
|
|
||||||
|
all_possibles = routes.map do |uri|
|
||||||
Regexp.new('^' + Regexp.escape(uri))
|
Regexp.new('^' + Regexp.escape(uri))
|
||||||
end.join('|'))
|
end.join('|')
|
||||||
|
|
||||||
|
@matcher = Regexp.new(all_possibles)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private :rebuild
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,3 +1,5 @@
|
||||||
|
if ENV['JAVA']
|
||||||
|
|
||||||
require 'rake/javaextensiontask'
|
require 'rake/javaextensiontask'
|
||||||
|
|
||||||
# build http11 java extension
|
# build http11 java extension
|
||||||
|
@ -6,3 +8,5 @@ Rake::JavaExtensionTask.new('http11', HOE.spec) do |ext|
|
||||||
gs.dependencies.delete gs.dependencies.find { |d| d.name == 'daemons' }
|
gs.dependencies.delete gs.dependencies.find { |d| d.name == 'daemons' }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
|
@ -21,11 +21,9 @@ class HttpParserTest < Test::Unit::TestCase
|
||||||
assert !parser.error?, "Parser had error"
|
assert !parser.error?, "Parser had error"
|
||||||
assert nread == parser.nread, "Number read returned from execute does not match"
|
assert nread == parser.nread, "Number read returned from execute does not match"
|
||||||
|
|
||||||
assert_equal 'HTTP/1.1', req['SERVER_PROTOCOL']
|
|
||||||
assert_equal '/', req['REQUEST_PATH']
|
assert_equal '/', req['REQUEST_PATH']
|
||||||
assert_equal 'HTTP/1.1', req['HTTP_VERSION']
|
assert_equal 'HTTP/1.1', req['HTTP_VERSION']
|
||||||
assert_equal '/', req['REQUEST_URI']
|
assert_equal '/', req['REQUEST_URI']
|
||||||
assert_equal 'CGI/1.2', req['GATEWAY_INTERFACE']
|
|
||||||
assert_equal 'GET', req['REQUEST_METHOD']
|
assert_equal 'GET', req['REQUEST_METHOD']
|
||||||
assert_nil req['FRAGMENT']
|
assert_nil req['FRAGMENT']
|
||||||
assert_nil req['QUERY_STRING']
|
assert_nil req['QUERY_STRING']
|
||||||
|
|
Loading…
Reference in a new issue