Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

use HTTP::Parser::XS for the additional speedups.

  • Loading branch information...
commit e40c242632f315eda8cdf79ead83e504f6def175 1 parent 3c3dac5
@miyagawa authored
Showing with 19 additions and 40 deletions.
  1. +1 −1  Makefile.PL
  2. +2 −2 README
  3. +1 −1  lib/Nomo.pm
  4. +15 −36 lib/Nomo/Server.pm
View
2  Makefile.PL
@@ -7,7 +7,7 @@ requires 'Plack', 0.99;
requires 'Net::Server';
requires 'Net::Server::SS::Prefork';
requires 'Data::Dump';
-requires 'HTTP::HeaderParser::XS';
+requires 'HTTP::Parser::XS';
requires 'HTTP::Status';
requires 'HTTP::Date';
requires 'URI::Escape';
View
4 README
@@ -39,7 +39,7 @@ PERFORMANCE
ApacheBench concurrenty 10 and Keep-alive on.
-- server: Nomo
- Requests per second: 5858.96 [#/sec] (mean)
+ Requests per second: 6413.87 [#/sec] (mean)
-- server: AnyEvent
Requests per second: 3911.78 [#/sec] (mean)
-- server: AnyEvent::HTTPD
@@ -56,7 +56,7 @@ PERFORMANCE
Requests per second: 503.59 [#/sec] (mean)
NOMO?
- The name Nomo is taken from the baseball player *Hideo Nomo*, who is a
+ The name Nomo is taken from the baseball player <Hideo Nomo>, who is a
great starter, famous for his forkball and whose nickname is Tornado.
AUTHOR
View
2  lib/Nomo.pm
@@ -65,7 +65,7 @@ A simple benchmark using C<Hello.psgi> as of Plack git SHA I<82121a>
with ApacheBench concurrenty 10 and Keep-alive on.
-- server: Nomo
- Requests per second: 5858.96 [#/sec] (mean)
+ Requests per second: 6413.87 [#/sec] (mean)
-- server: AnyEvent
Requests per second: 3911.78 [#/sec] (mean)
-- server: AnyEvent::HTTPD
View
51 lib/Nomo/Server.pm
@@ -5,7 +5,7 @@ use base 'Net::Server::PreFork';
use Data::Dump qw(dump);
use Socket;
use IO::Socket qw(:crlf);
-use HTTP::HeaderParser::XS;
+use HTTP::Parser::XS qw(parse_http_request);
use HTTP::Status qw(status_message);
use HTTP::Date qw(time2str);
use URI::Escape;
@@ -88,37 +88,12 @@ sub process_request {
# Read until we see all headers
last if !$self->_read_headers;
- # Parse headers
- my $h = HTTP::HeaderParser::XS->new( \delete $self->{client}->{headerbuf} );
-
- if ( !$h ) {
- # Bad request
- DEBUG && warn "[$$] Bad request\n";
- $self->_http_error(400, { SERVER_PROTOCOL => "HTTP/1.0" });
- last;
- }
-
- # Initialize PSGI environment
- my $uri = $h->request_uri();
- my ( $path, $query_string ) = split /\?/, $uri, 2;
-
- my $version = $h->version_number();
- my $proto = sprintf( "HTTP/%d.%d", int( $version / 1000 ), $version % 1000 );
- my $headers = $h->getHeaders();
-
my $env = {
REMOTE_ADDR => $self->{server}->{peeraddr},
REMOTE_HOST => $self->{server}->{peerhost} || $self->{server}->{peeraddr},
SERVER_NAME => $self->{server}->{sockaddr}, # XXX: needs to be resolved?
SERVER_PORT => $self->{server}->{port}->[0],
SCRIPT_NAME => '',
- REQUEST_METHOD => $h->request_method() || '',
- PATH_INFO => URI::Escape::uri_unescape($path),
- REQUEST_URI => $uri,
- QUERY_STRING => $query_string || '',
- SERVER_PROTOCOL => $proto,
- CONTENT_TYPE => $headers->{'Content-Type'},
- CONTENT_LENGTH => $headers->{'Content-Length'},
'psgi.version' => [ 1, 1 ],
'psgi.errors' => *STDERR,
'psgi.url_scheme' => 'http',
@@ -129,15 +104,19 @@ sub process_request {
'psgi.multiprocess' => Plack::Util::TRUE,
};
- # Add headers
- while (my($key, $value) = each %$headers) {
- next if $key eq 'Content-Length' or $key eq 'Content-Type';
- $key =~ tr/-/_/;
- $env->{"HTTP_" . uc($key)} = $value;
+ # Parse headers
+ my $reqlen = parse_http_request(delete $self->{client}->{headerbuf}, $env);
+ if ( $reqlen == -1 ) {
+ # Bad request
+ DEBUG && warn "[$$] Bad request\n";
+ $self->_http_error(400, { SERVER_PROTOCOL => "HTTP/1.0" });
+ last;
}
+ # Initialize PSGI environment
# Determine whether we will keep the connection open after the request
- my $connection = $headers->{Connection};
+ my $connection = delete $env->{HTTP_CONNECTION};
+ my $proto = $env->{SERVER_PROTOCOL};
if ( $proto && $proto eq 'HTTP/1.0' ) {
if ( $connection && $connection =~ /^keep-alive$/i ) {
# Keep-alive only with explicit header in HTTP/1.0
@@ -157,8 +136,8 @@ sub process_request {
}
# Do we need to send 100 Continue?
- if ( $headers->{Expect} ) {
- if ( $headers->{Expect} eq '100-continue' ) {
+ if ( $env->{HTTP_EXPECT} ) {
+ if ( $env->{HTTP_EXPECT} eq '100-continue' ) {
syswrite STDOUT, 'HTTP/1.1 100 Continue' . $CRLF . $CRLF;
DEBUG && warn "[$$] Sent 100 Continue response\n";
}
@@ -169,7 +148,7 @@ sub process_request {
}
}
- unless ($headers->{Host}) {
+ unless ($env->{HTTP_HOST}) {
# No host, bad request
DEBUG && warn "[$$] Bad request, HTTP/1.1 without Host header\n";
$self->_http_error( 400, $env );
@@ -177,7 +156,7 @@ sub process_request {
}
}
- $self->_prepare_env($env, $headers);
+ $self->_prepare_env($env);
# Run PSGI apps
my $res = Plack::Util::run_app($self->{app}, $env);
Please sign in to comment.
Something went wrong with that request. Please try again.