HTTP Parser and message builder / objects in plain C Snapshot
hparse.c
Go to the documentation of this file.
00001 #include "http.h"
00002 
00003 
00004 // Content-Length    = "Content-Length" ":" 1*DIGIT
00005 static int parser_content_length_header( struct tagHTTP_MESSAGE *message, struct tagHTTP_PARSER *parser )
00006 {
00007   int rt;
00008   
00009   rt = HTTP_get_header_token( parser );
00010   if (rt != HTTP_TK_TEXT) {
00011     return -1;
00012   }
00013 
00014   rt = atoi( parser->token );
00015   if (rt <= 0) {
00016     return -1;
00017   }
00018 
00019   message->content_length = rt;  
00020   message->flags |=  HTTP_MESSAGE_FLAG_HAS_CONTENT_LENGTH;  
00021   return 0;
00022 }
00023 
00024 
00025 //Connection = "Connection" ":" 1#(connection-token)
00026 //       connection-token  = token
00027 // ? close seems to be the only value
00028 
00029 static int parser_connection_header(  struct tagHTTP_MESSAGE *message, struct tagHTTP_PARSER *parser )
00030 {
00031   int rt;
00032   
00033   rt = HTTP_get_header_token( parser );
00034   if (rt != HTTP_TK_TEXT) {
00035     return -1;
00036   }
00037 
00038   if ( strcmp( parser->token,"close") == 0) {
00039     message->flags |= HTTP_MESSAGE_FLAG_CONNECTION_CLOSE;
00040     return 0;
00041   }
00042   if ( strcasecmp( parser->token,"keep-alive") == 0) {
00043     message->flags |= HTTP_MESSAGE_FLAG_KEEPALIVE;
00044   }
00045 
00046   return -1;
00047 }
00048 
00049 
00050        
00051 //Transfer-Encoding       = "Transfer-Encoding" ":" 1#transfer-coding
00052 //
00053 
00054 static int parser_transfer_encoding_header(  struct tagHTTP_MESSAGE *message, struct tagHTTP_PARSER *parser )
00055 {
00056   int rt;
00057   
00058   rt = HTTP_get_header_token( parser );
00059   if (rt != HTTP_TK_TEXT) {
00060     return -1;
00061   }
00062 
00063   if ( strcmp( parser->token,"chunked") == 0) {
00064     message->flags |= HTTP_MESSAGE_FLAG_TRANSFER_CHUNKED;
00065     return 0;
00066   }
00067 
00068   return -1;
00069 }
00070 
00071 static int parser_expect_header(  struct tagHTTP_MESSAGE *message, struct tagHTTP_PARSER *parser )
00072 {
00073   HTTP_REQUEST *req;
00074   int rt;
00075   
00076   rt = HTTP_get_header_token( parser );
00077   if (rt != HTTP_TK_TEXT) {
00078         return -1;
00079   }
00080 
00081   if ( strcmp( parser->token,"100-continue") == 0) {
00082     req =  (HTTP_REQUEST *)  message;
00083     req->expect_100_continue = 1;
00084   }
00085   return 0;
00086 }
00087 
00088 // Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
00089 static int parser_host_header(  struct tagHTTP_MESSAGE *message, struct tagHTTP_PARSER *parser )
00090 {
00091   int rt;
00092   HTTP_REQUEST *req = (HTTP_REQUEST *) message;
00093  
00094   
00095   req->has_host_header = 1;
00096   req->host_header_port = -1;
00097   
00098   rt = HTTP_get_header_token( parser );
00099   if (rt == HTTP_TK_TEXT) {
00100     req->host_header = strdup( parser->token );
00101     rt = HTTP_get_header_token( parser );
00102     if (rt == HTTP_TK_SEPARATOR && parser->token[0] == ':') {
00103       rt = HTTP_get_header_token( parser );
00104       if (rt == HTTP_TK_TEXT) {
00105         req->host_header_port = atoi( parser->token );
00106       }
00107     }
00108   }
00109  
00110   return 0;
00111 }
00112 
00113 int init_parsers_general_header( HTTP_PARSER *parser )
00114 {
00115   if (HTTP_add_header_parser( parser, "content-length",  parser_content_length_header) ||
00116       HTTP_add_header_parser( parser, "connection",  parser_connection_header) || 
00117        HTTP_add_header_parser( parser, "transfer-encoding",  parser_transfer_encoding_header) ) {
00118     return -1;
00119   }
00120   return 0;
00121 }
00122 
00123 int init_parsers_request_header( HTTP_PARSER *parser )
00124 {
00125   if (HTTP_add_header_parser( parser, "expect",  parser_expect_header) || 
00126       HTTP_add_header_parser( parser, "host",  parser_host_header) ) {
00127     return -1;
00128   }
00129   return 0;
00130 }