about summary refs log tree commit homepage
path: root/ext
diff options
context:
space:
mode:
authorzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-03-19 05:18:11 +0000
committerzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-03-19 05:18:11 +0000
commitebeac4b0312015147ef2319b27c903a791f122af (patch)
treee5d743a971f4fd9fc429d7df7b81d78a2c56bf25 /ext
parent28c6a99aee10fcdeecf5326f610455b79a3a9026 (diff)
downloadunicorn-ebeac4b0312015147ef2319b27c903a791f122af.tar.gz
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@116 19e92222-5c0b-0410-8929-a290d50e31e9
Diffstat (limited to 'ext')
-rw-r--r--ext/http11/http11.c78
-rw-r--r--ext/http11/http11_parser.c51
-rw-r--r--ext/http11/http11_parser.h3
-rw-r--r--ext/http11/http11_parser.rl7
4 files changed, 100 insertions, 39 deletions
diff --git a/ext/http11/http11.c b/ext/http11/http11.c
index e69d185..1abec65 100644
--- a/ext/http11/http11.c
+++ b/ext/http11/http11.c
@@ -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);
diff --git a/ext/http11/http11_parser.c b/ext/http11/http11_parser.c
index c17d907..fcbfa31 100644
--- a/ext/http11/http11_parser.c
+++ b/ext/http11/http11_parser.c
@@ -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;
 
diff --git a/ext/http11/http11_parser.h b/ext/http11/http11_parser.h
index 6ca9cef..8d49a42 100644
--- a/ext/http11/http11_parser.h
+++ b/ext/http11/http11_parser.h
@@ -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);
diff --git a/ext/http11/http11_parser.rl b/ext/http11/http11_parser.rl
index 1073d9f..8ef4acb 100644
--- a/ext/http11/http11_parser.rl
+++ b/ext/http11/http11_parser.rl
@@ -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;
 }%%