HTTP Parser and message builder / objects in plain C Snapshot
|
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 }