mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Beginning of a tuning effort.
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@116 19e92222-5c0b-0410-8929-a290d50e31e9
This commit is contained in:
parent
28c6a99aee
commit
ebeac4b031
7 changed files with 128 additions and 102 deletions
4
Rakefile
4
Rakefile
|
@ -65,7 +65,7 @@ task :package_win32 do
|
|||
spec.required_ruby_version = '>= 1.8.4'
|
||||
|
||||
spec.add_dependency('win32-service', '>= 0.5.0')
|
||||
spec.add_dependency('gem_plugin', ">= 0.2")
|
||||
spec.add_dependency('gem_plugin', ">= 0.2.1")
|
||||
|
||||
spec.extensions = []
|
||||
spec.platform = Gem::Platform::WIN32
|
||||
|
@ -79,11 +79,13 @@ task :install do
|
|||
sh %{sudo gem install pkg/mongrel-#{version}}
|
||||
sub_project("mongrel_status", :install)
|
||||
sub_project("mongrel_config", :install)
|
||||
sub_project("mongrel_console", :install)
|
||||
end
|
||||
|
||||
task :uninstall => [:clean] do
|
||||
sub_project("mongrel_status", :uninstall)
|
||||
sub_project("mongrel_config", :uninstall)
|
||||
sub_project("mongrel_console", :uninstall)
|
||||
sh %{sudo gem uninstall mongrel}
|
||||
sub_project("gem_plugin", :uninstall)
|
||||
end
|
||||
|
|
|
@ -19,6 +19,16 @@ class SimpleHandler < Mongrel::HttpHandler
|
|||
end
|
||||
end
|
||||
|
||||
class DumbHandler < Mongrel::HttpHandler
|
||||
def process(request, response)
|
||||
response.start do |head,out|
|
||||
head["Content-Type"] = "text/html"
|
||||
out.write("test")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if ARGV.length != 3
|
||||
STDERR.puts "usage: simpletest.rb <host> <port> <docroot>"
|
||||
exit(1)
|
||||
|
@ -26,6 +36,7 @@ end
|
|||
|
||||
h = Mongrel::HttpServer.new(ARGV[0], ARGV[1].to_i)
|
||||
h.register("/", SimpleHandler.new)
|
||||
h.register("/dumb", DumbHandler.new)
|
||||
h.register("/files", Mongrel::DirHandler.new(ARGV[2]))
|
||||
h.run
|
||||
|
||||
|
|
|
@ -16,6 +16,21 @@ static VALUE global_request_method;
|
|||
static VALUE global_request_uri;
|
||||
static VALUE global_query_string;
|
||||
static VALUE global_http_version;
|
||||
static VALUE global_content_length;
|
||||
static VALUE global_http_content_length;
|
||||
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_interface_value;
|
||||
static VALUE global_remote_address;
|
||||
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;
|
||||
|
||||
|
||||
void http_field(void *data, const char *field, size_t flen, const char *value, size_t vlen)
|
||||
|
@ -67,8 +82,34 @@ void http_version(void *data, const char *at, size_t length)
|
|||
rb_hash_aset(req, global_http_version, val);
|
||||
}
|
||||
|
||||
/** Finalizes the request header to have a bunch of stuff that's
|
||||
needed. */
|
||||
|
||||
void header_done(void *data, const char *at, size_t length)
|
||||
{
|
||||
VALUE req = (VALUE)data;
|
||||
VALUE temp = Qnil;
|
||||
VALUE host = Qnil;
|
||||
VALUE port = Qnil;
|
||||
char *colon = NULL;
|
||||
|
||||
rb_hash_aset(req, global_content_length, rb_hash_aref(req, global_http_content_length));
|
||||
rb_hash_aset(req, global_content_type, rb_hash_aref(req, global_http_content_type));
|
||||
rb_hash_aset(req, global_gateway_interface, global_gateway_interface_value);
|
||||
if((temp = rb_hash_aref(req, global_http_host)) != Qnil) {
|
||||
// ruby better close strings off with a '\0' dammit
|
||||
colon = strchr(RSTRING(temp)->ptr, ':');
|
||||
if(colon != NULL) {
|
||||
rb_hash_aset(req, global_server_name, rb_str_substr(temp, 0, colon - RSTRING(temp)->ptr));
|
||||
rb_hash_aset(req, global_server_port,
|
||||
rb_str_substr(temp, colon - RSTRING(temp)->ptr+1,
|
||||
RSTRING(temp)->len));
|
||||
}
|
||||
}
|
||||
|
||||
rb_hash_aset(req, global_server_protocol, global_server_protocol_value);
|
||||
rb_hash_aset(req, global_server_software, global_mongrel_version);
|
||||
}
|
||||
|
||||
|
||||
void HttpParser_free(void *data) {
|
||||
|
@ -90,7 +131,8 @@ VALUE HttpParser_alloc(VALUE klass)
|
|||
hp->request_uri = request_uri;
|
||||
hp->query_string = query_string;
|
||||
hp->http_version = http_version;
|
||||
|
||||
hp->header_done = header_done;
|
||||
|
||||
obj = Data_Wrap_Struct(klass, NULL, HttpParser_free, hp);
|
||||
|
||||
return obj;
|
||||
|
@ -406,6 +448,8 @@ VALUE URIClassifier_resolve(VALUE self, VALUE uri)
|
|||
return result;
|
||||
}
|
||||
|
||||
#define DEF_GLOBAL(name, val) global_##name = rb_str_new2(val); rb_global_variable(&global_##name)
|
||||
|
||||
|
||||
void Init_http11()
|
||||
{
|
||||
|
@ -413,17 +457,27 @@ void Init_http11()
|
|||
mMongrel = rb_define_module("Mongrel");
|
||||
id_handler_map = rb_intern("@handler_map");
|
||||
|
||||
global_http_prefix = rb_str_new2("HTTP_");
|
||||
rb_global_variable(&global_http_prefix);
|
||||
global_request_method = rb_str_new2("REQUEST_METHOD");
|
||||
rb_global_variable(&global_request_method);
|
||||
global_request_uri = rb_str_new2("REQUEST_URI");
|
||||
rb_global_variable(&global_request_uri);
|
||||
global_query_string = rb_str_new2("QUERY_STRING");
|
||||
rb_global_variable(&global_query_string);
|
||||
global_http_version = rb_str_new2("HTTP_VERSION");
|
||||
rb_global_variable(&global_http_version);
|
||||
|
||||
DEF_GLOBAL(http_prefix, "HTTP_");
|
||||
DEF_GLOBAL(request_method, "REQUEST_METHOD");
|
||||
DEF_GLOBAL(request_uri, "REQUEST_URI");
|
||||
DEF_GLOBAL(query_string, "QUERY_STRING");
|
||||
DEF_GLOBAL(http_version, "HTTP_VERSION");
|
||||
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(remote_address, "REMOTE_ADDR");
|
||||
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 0.3.12");
|
||||
DEF_GLOBAL(server_software, "SERVER_SOFTWARE");
|
||||
|
||||
|
||||
cHttpParser = rb_define_class_under(mMongrel, "HttpParser", rb_cObject);
|
||||
rb_define_alloc_func(cHttpParser, HttpParser_alloc);
|
||||
rb_define_method(cHttpParser, "initialize", HttpParser_init,0);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#define MARK(S,F) assert((F) - (S)->mark >= 0); (S)->mark = (F);
|
||||
|
||||
/** machine **/
|
||||
#line 98 "ext/http11/http11_parser.rl"
|
||||
#line 101 "ext/http11/http11_parser.rl"
|
||||
|
||||
|
||||
/** Data **/
|
||||
|
@ -21,7 +21,7 @@ static int http_parser_first_final = 53;
|
|||
|
||||
static int http_parser_error = 1;
|
||||
|
||||
#line 102 "ext/http11/http11_parser.rl"
|
||||
#line 105 "ext/http11/http11_parser.rl"
|
||||
|
||||
int http_parser_init(http_parser *parser) {
|
||||
int cs = 0;
|
||||
|
@ -30,7 +30,7 @@ int http_parser_init(http_parser *parser) {
|
|||
{
|
||||
cs = http_parser_start;
|
||||
}
|
||||
#line 106 "ext/http11/http11_parser.rl"
|
||||
#line 109 "ext/http11/http11_parser.rl"
|
||||
parser->cs = cs;
|
||||
parser->body_start = NULL;
|
||||
parser->content_len = 0;
|
||||
|
@ -305,14 +305,17 @@ case 21:
|
|||
tr40:
|
||||
#line 46 "ext/http11/http11_parser.rl"
|
||||
{
|
||||
parser->body_start = p+1; goto _out53;
|
||||
parser->body_start = p+1;
|
||||
if(parser->header_done != NULL)
|
||||
parser->header_done(parser->data, p, 0);
|
||||
goto _out53;
|
||||
}
|
||||
goto st53;
|
||||
st53:
|
||||
if ( ++p == pe )
|
||||
goto _out53;
|
||||
case 53:
|
||||
#line 316 "ext/http11/http11_parser.c"
|
||||
#line 319 "ext/http11/http11_parser.c"
|
||||
goto st1;
|
||||
tr36:
|
||||
#line 16 "ext/http11/http11_parser.rl"
|
||||
|
@ -322,7 +325,7 @@ st22:
|
|||
if ( ++p == pe )
|
||||
goto _out22;
|
||||
case 22:
|
||||
#line 326 "ext/http11/http11_parser.c"
|
||||
#line 329 "ext/http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 33: goto st22;
|
||||
case 58: goto tr32;
|
||||
|
@ -357,7 +360,7 @@ st23:
|
|||
if ( ++p == pe )
|
||||
goto _out23;
|
||||
case 23:
|
||||
#line 361 "ext/http11/http11_parser.c"
|
||||
#line 364 "ext/http11/http11_parser.c"
|
||||
if ( (*p) == 13 )
|
||||
goto tr49;
|
||||
goto tr52;
|
||||
|
@ -369,7 +372,7 @@ st24:
|
|||
if ( ++p == pe )
|
||||
goto _out24;
|
||||
case 24:
|
||||
#line 373 "ext/http11/http11_parser.c"
|
||||
#line 376 "ext/http11/http11_parser.c"
|
||||
if ( (*p) == 13 )
|
||||
goto tr49;
|
||||
goto st24;
|
||||
|
@ -381,7 +384,7 @@ st25:
|
|||
if ( ++p == pe )
|
||||
goto _out25;
|
||||
case 25:
|
||||
#line 385 "ext/http11/http11_parser.c"
|
||||
#line 388 "ext/http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 43: goto st25;
|
||||
case 58: goto st26;
|
||||
|
@ -406,7 +409,7 @@ st26:
|
|||
if ( ++p == pe )
|
||||
goto _out26;
|
||||
case 26:
|
||||
#line 410 "ext/http11/http11_parser.c"
|
||||
#line 413 "ext/http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 32: goto tr34;
|
||||
case 37: goto st27;
|
||||
|
@ -454,7 +457,7 @@ st29:
|
|||
if ( ++p == pe )
|
||||
goto _out29;
|
||||
case 29:
|
||||
#line 458 "ext/http11/http11_parser.c"
|
||||
#line 461 "ext/http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 32: goto tr34;
|
||||
case 37: goto st31;
|
||||
|
@ -525,7 +528,7 @@ st33:
|
|||
if ( ++p == pe )
|
||||
goto _out33;
|
||||
case 33:
|
||||
#line 529 "ext/http11/http11_parser.c"
|
||||
#line 532 "ext/http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 32: goto tr46;
|
||||
case 37: goto tr51;
|
||||
|
@ -547,7 +550,7 @@ st34:
|
|||
if ( ++p == pe )
|
||||
goto _out34;
|
||||
case 34:
|
||||
#line 551 "ext/http11/http11_parser.c"
|
||||
#line 554 "ext/http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 32: goto tr46;
|
||||
case 37: goto st35;
|
||||
|
@ -569,7 +572,7 @@ st35:
|
|||
if ( ++p == pe )
|
||||
goto _out35;
|
||||
case 35:
|
||||
#line 573 "ext/http11/http11_parser.c"
|
||||
#line 576 "ext/http11/http11_parser.c"
|
||||
if ( (*p) < 65 ) {
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto st36;
|
||||
|
@ -600,7 +603,7 @@ st37:
|
|||
if ( ++p == pe )
|
||||
goto _out37;
|
||||
case 37:
|
||||
#line 604 "ext/http11/http11_parser.c"
|
||||
#line 607 "ext/http11/http11_parser.c"
|
||||
if ( (*p) == 69 )
|
||||
goto st38;
|
||||
goto st1;
|
||||
|
@ -619,7 +622,7 @@ st39:
|
|||
if ( ++p == pe )
|
||||
goto _out39;
|
||||
case 39:
|
||||
#line 623 "ext/http11/http11_parser.c"
|
||||
#line 626 "ext/http11/http11_parser.c"
|
||||
if ( (*p) == 69 )
|
||||
goto st40;
|
||||
goto st1;
|
||||
|
@ -645,7 +648,7 @@ st42:
|
|||
if ( ++p == pe )
|
||||
goto _out42;
|
||||
case 42:
|
||||
#line 649 "ext/http11/http11_parser.c"
|
||||
#line 652 "ext/http11/http11_parser.c"
|
||||
if ( (*p) == 80 )
|
||||
goto st43;
|
||||
goto st1;
|
||||
|
@ -692,7 +695,7 @@ st48:
|
|||
if ( ++p == pe )
|
||||
goto _out48;
|
||||
case 48:
|
||||
#line 696 "ext/http11/http11_parser.c"
|
||||
#line 699 "ext/http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 79: goto st49;
|
||||
case 85: goto st38;
|
||||
|
@ -713,7 +716,7 @@ st50:
|
|||
if ( ++p == pe )
|
||||
goto _out50;
|
||||
case 50:
|
||||
#line 717 "ext/http11/http11_parser.c"
|
||||
#line 720 "ext/http11/http11_parser.c"
|
||||
if ( (*p) == 82 )
|
||||
goto st51;
|
||||
goto st1;
|
||||
|
@ -788,15 +791,15 @@ case 52:
|
|||
|
||||
_out: {}
|
||||
}
|
||||
#line 125 "ext/http11/http11_parser.rl"
|
||||
#line 128 "ext/http11/http11_parser.rl"
|
||||
|
||||
parser->cs = cs;
|
||||
parser->nread = p - buffer;
|
||||
if(parser->body_start) {
|
||||
/* final \r\n combo encountered so stop right here */
|
||||
|
||||
#line 799 "ext/http11/http11_parser.c"
|
||||
#line 131 "ext/http11/http11_parser.rl"
|
||||
#line 802 "ext/http11/http11_parser.c"
|
||||
#line 134 "ext/http11/http11_parser.rl"
|
||||
parser->nread++;
|
||||
}
|
||||
|
||||
|
@ -808,8 +811,8 @@ int http_parser_finish(http_parser *parser)
|
|||
int cs = parser->cs;
|
||||
|
||||
|
||||
#line 812 "ext/http11/http11_parser.c"
|
||||
#line 142 "ext/http11/http11_parser.rl"
|
||||
#line 815 "ext/http11/http11_parser.c"
|
||||
#line 145 "ext/http11/http11_parser.rl"
|
||||
|
||||
parser->cs = cs;
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@ typedef struct http_parser {
|
|||
element_cb request_uri;
|
||||
element_cb query_string;
|
||||
element_cb http_version;
|
||||
|
||||
element_cb header_done;
|
||||
|
||||
} http_parser;
|
||||
|
||||
int http_parser_init(http_parser *parser);
|
||||
|
|
|
@ -44,7 +44,10 @@
|
|||
parser->http_version(parser->data, parser->mark, p - parser->mark);
|
||||
}
|
||||
action done {
|
||||
parser->body_start = p+1; fbreak;
|
||||
parser->body_start = p+1;
|
||||
if(parser->header_done != NULL)
|
||||
parser->header_done(parser->data, p, 0);
|
||||
fbreak;
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,7 +95,7 @@
|
|||
|
||||
message_header = field_name ":" field_value $0 CRLF >1;
|
||||
|
||||
Request = Request_Line (message_header)* ( CRLF @done );
|
||||
Request = Request_Line (message_header)* ( CRLF @done);
|
||||
|
||||
main := Request;
|
||||
}%%
|
||||
|
|
|
@ -90,59 +90,20 @@ module Mongrel
|
|||
module Const
|
||||
# This is the part of the path after the SCRIPT_NAME. URIClassifier will determine this.
|
||||
PATH_INFO="PATH_INFO"
|
||||
|
||||
# This is the intial part that your handler is identified as by URIClassifier.
|
||||
SCRIPT_NAME="SCRIPT_NAME"
|
||||
|
||||
# The original URI requested by the client. Passed to URIClassifier to build PATH_INFO and SCRIPT_NAME.
|
||||
REQUEST_URI='REQUEST_URI'
|
||||
|
||||
# Content length (also available as HTTP_CONTENT_LENGTH).
|
||||
CONTENT_LENGTH='CONTENT_LENGTH'
|
||||
|
||||
# Content length (also available as CONTENT_LENGTH).
|
||||
HTTP_CONTENT_LENGTH='HTTP_CONTENT_LENGTH'
|
||||
|
||||
# Content type (also available as HTTP_CONTENT_TYPE).
|
||||
CONTENT_TYPE='CONTENT_TYPE'
|
||||
|
||||
# Content type (also available as CONTENT_TYPE).
|
||||
HTTP_CONTENT_TYPE='HTTP_CONTENT_TYPE'
|
||||
|
||||
# Gateway interface key in the HttpRequest parameters.
|
||||
GATEWAY_INTERFACE='GATEWAY_INTERFACE'
|
||||
# We claim to support CGI/1.2.
|
||||
GATEWAY_INTERFACE_VALUE='CGI/1.2'
|
||||
|
||||
# Hosts remote IP address. Mongrel does not do DNS resolves since that slows
|
||||
# processing down considerably.
|
||||
REMOTE_ADDR='REMOTE_ADDR'
|
||||
|
||||
# This is not given since Mongrel does not do DNS resolves. It is only here for
|
||||
# completeness for the CGI standard.
|
||||
REMOTE_HOST='REMOTE_HOST'
|
||||
|
||||
# The name/host of our server as given by the HttpServer.new(host,port) call.
|
||||
SERVER_NAME='SERVER_NAME'
|
||||
|
||||
# The port of our server as given by the HttpServer.new(host,port) call.
|
||||
SERVER_PORT='SERVER_PORT'
|
||||
|
||||
# SERVER_NAME and SERVER_PORT come from this.
|
||||
HTTP_HOST='HTTP_HOST'
|
||||
|
||||
# Official server protocol key in the HttpRequest parameters.
|
||||
SERVER_PROTOCOL='SERVER_PROTOCOL'
|
||||
# Mongrel claims to support HTTP/1.1.
|
||||
SERVER_PROTOCOL_VALUE='HTTP/1.1'
|
||||
|
||||
# The actual server software being used (it's Mongrel man).
|
||||
SERVER_SOFTWARE='SERVER_SOFTWARE'
|
||||
|
||||
# Current Mongrel version (used for SERVER_SOFTWARE and other response headers).
|
||||
MONGREL_VERSION='Mongrel 0.3.10'
|
||||
MONGREL_VERSION="0.3.12"
|
||||
|
||||
# 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_VERSION}\r\n\r\nNOT FOUND"
|
||||
|
||||
CONTENT_LENGTH="CONTENT_LENGTH"
|
||||
|
||||
# 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"
|
||||
|
||||
|
@ -172,27 +133,14 @@ module Mongrel
|
|||
@body = initial_body || ""
|
||||
@params = params
|
||||
@socket = socket
|
||||
|
||||
# fix up the CGI requirements
|
||||
params[Const::CONTENT_LENGTH] = params[Const::HTTP_CONTENT_LENGTH] || 0
|
||||
params[Const::CONTENT_TYPE] = params[Const::HTTP_CONTENT_TYPE] if params[Const::HTTP_CONTENT_TYPE]
|
||||
params[Const::GATEWAY_INTERFACE]=Const::GATEWAY_INTERFACE_VALUE
|
||||
params[Const::REMOTE_ADDR]=socket.peeraddr[3]
|
||||
if params.has_key? Const::HTTP_HOST
|
||||
host,port = params[Const::HTTP_HOST].split(":")
|
||||
params[Const::SERVER_NAME]=host
|
||||
params[Const::SERVER_PORT]=port || 80
|
||||
end
|
||||
params[Const::SERVER_PROTOCOL]=Const::SERVER_PROTOCOL_VALUE
|
||||
params[Const::SERVER_SOFTWARE]=Const::MONGREL_VERSION
|
||||
|
||||
|
||||
# now, if the initial_body isn't long enough for the content length we have to fill it
|
||||
# TODO: adapt for big ass stuff by writing to a temp file
|
||||
clen = params[Const::HTTP_CONTENT_LENGTH].to_i
|
||||
clen = params[Const::CONTENT_LENGTH].to_i
|
||||
if @body.length < clen
|
||||
@body << @socket.read(clen - @body.length)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -354,9 +302,11 @@ module Mongrel
|
|||
# create the worker threads
|
||||
num_processors.times do |i|
|
||||
@processors << Thread.new do
|
||||
parser = HttpParser.new
|
||||
while client = @req_queue.deq
|
||||
Timeout::timeout(timeout) do
|
||||
process_client(client)
|
||||
process_client(client, parser)
|
||||
parser.reset
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -370,14 +320,15 @@ module Mongrel
|
|||
# the performance just does not improve. It is currently carefully constructed
|
||||
# to make sure that it gets the best possible performance, but anyone who
|
||||
# thinks they can make it faster is more than welcome to take a crack at it.
|
||||
def process_client(client)
|
||||
def process_client(client, parser)
|
||||
begin
|
||||
parser = HttpParser.new
|
||||
params = {}
|
||||
|
||||
data = client.readpartial(Const::CHUNK_SIZE)
|
||||
|
||||
while true
|
||||
nread = parser.execute(params, data)
|
||||
|
||||
if parser.finished?
|
||||
script_name, path_info, handler = @classifier.resolve(params[Const::REQUEST_URI])
|
||||
|
||||
|
@ -385,6 +336,7 @@ module Mongrel
|
|||
params[Const::PATH_INFO] = path_info
|
||||
params[Const::SCRIPT_NAME] = script_name
|
||||
request = HttpRequest.new(params, data[nread ... data.length], client)
|
||||
|
||||
response = HttpResponse.new(client)
|
||||
handler.process(request, response)
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue