1 /* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org> 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to 5 * deal in the Software without restriction, including without limitation the 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 * sell copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 * IN THE SOFTWARE. 20 */ 21 /* modified by Moriyoshi Koizumi <moriyoshi@php.net> to make it fit to PHP source tree. */ 22 #ifndef php_http_parser_h 23 #define php_http_parser_h 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 29 #include <sys/types.h> 30 #if defined(_WIN32) && !defined(__MINGW32__) 31 # include <windows.h> 32 # include "config.w32.h" 33 #else 34 # include "php_config.h" 35 #endif 36 37 #include "php_stdint.h" 38 39 /* Compile with -DPHP_HTTP_PARSER_STRICT=0 to make less checks, but run 40 * faster 41 */ 42 #ifndef PHP_HTTP_PARSER_STRICT 43 # define PHP_HTTP_PARSER_STRICT 1 44 #else 45 # define PHP_HTTP_PARSER_STRICT 0 46 #endif 47 48 49 /* Maximium header size allowed */ 50 #define PHP_HTTP_MAX_HEADER_SIZE (80*1024) 51 52 53 typedef struct php_http_parser php_http_parser; 54 typedef struct php_http_parser_settings php_http_parser_settings; 55 56 57 /* Callbacks should return non-zero to indicate an error. The parser will 58 * then halt execution. 59 * 60 * The one exception is on_headers_complete. In a PHP_HTTP_RESPONSE parser 61 * returning '1' from on_headers_complete will tell the parser that it 62 * should not expect a body. This is used when receiving a response to a 63 * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: 64 * chunked' headers that indicate the presence of a body. 65 * 66 * http_data_cb does not return data chunks. It will be call arbitrarally 67 * many times for each string. E.G. you might get 10 callbacks for "on_path" 68 * each providing just a few characters more data. 69 */ 70 typedef int (*php_http_data_cb) (php_http_parser*, const char *at, size_t length); 71 typedef int (*php_http_cb) (php_http_parser*); 72 73 74 /* Request Methods */ 75 enum php_http_method 76 { PHP_HTTP_DELETE = 0 77 , PHP_HTTP_GET 78 , PHP_HTTP_HEAD 79 , PHP_HTTP_POST 80 , PHP_HTTP_PUT 81 , PHP_HTTP_PATCH 82 /* pathological */ 83 , PHP_HTTP_CONNECT 84 , PHP_HTTP_OPTIONS 85 , PHP_HTTP_TRACE 86 /* webdav */ 87 , PHP_HTTP_COPY 88 , PHP_HTTP_LOCK 89 , PHP_HTTP_MKCOL 90 , PHP_HTTP_MOVE 91 , PHP_HTTP_MKCALENDAR 92 , PHP_HTTP_PROPFIND 93 , PHP_HTTP_PROPPATCH 94 , PHP_HTTP_UNLOCK 95 /* subversion */ 96 , PHP_HTTP_REPORT 97 , PHP_HTTP_MKACTIVITY 98 , PHP_HTTP_CHECKOUT 99 , PHP_HTTP_MERGE 100 /* upnp */ 101 , PHP_HTTP_MSEARCH 102 , PHP_HTTP_NOTIFY 103 , PHP_HTTP_SUBSCRIBE 104 , PHP_HTTP_UNSUBSCRIBE 105 /* unknown, not implemented */ 106 , PHP_HTTP_NOT_IMPLEMENTED 107 }; 108 109 110 enum php_http_parser_type { PHP_HTTP_REQUEST, PHP_HTTP_RESPONSE, PHP_HTTP_BOTH }; 111 112 113 struct php_http_parser { 114 /** PRIVATE **/ 115 unsigned char type : 2; 116 unsigned char flags : 6; 117 unsigned char state; 118 unsigned char header_state; 119 unsigned char index; 120 121 uint32_t nread; 122 ssize_t content_length; 123 124 /** READ-ONLY **/ 125 unsigned short http_major; 126 unsigned short http_minor; 127 unsigned short status_code; /* responses only */ 128 unsigned char method; /* requests only */ 129 130 /* 1 = Upgrade header was present and the parser has exited because of that. 131 * 0 = No upgrade header present. 132 * Should be checked when http_parser_execute() returns in addition to 133 * error checking. 134 */ 135 char upgrade; 136 137 /** PUBLIC **/ 138 void *data; /* A pointer to get hook to the "connection" or "socket" object */ 139 }; 140 141 142 struct php_http_parser_settings { 143 php_http_cb on_message_begin; 144 php_http_data_cb on_path; 145 php_http_data_cb on_query_string; 146 php_http_data_cb on_url; 147 php_http_data_cb on_fragment; 148 php_http_data_cb on_header_field; 149 php_http_data_cb on_header_value; 150 php_http_cb on_headers_complete; 151 php_http_data_cb on_body; 152 php_http_cb on_message_complete; 153 }; 154 155 156 void php_http_parser_init(php_http_parser *parser, enum php_http_parser_type type); 157 158 159 size_t php_http_parser_execute(php_http_parser *parser, 160 const php_http_parser_settings *settings, 161 const char *data, 162 size_t len); 163 164 165 /* If php_http_should_keep_alive() in the on_headers_complete or 166 * on_message_complete callback returns true, then this will be should be 167 * the last message on the connection. 168 * If you are the server, respond with the "Connection: close" header. 169 * If you are the client, close the connection. 170 */ 171 int php_http_should_keep_alive(php_http_parser *parser); 172 173 /* Returns a string version of the HTTP method. */ 174 const char *php_http_method_str(enum php_http_method); 175 176 #ifdef __cplusplus 177 } 178 #endif 179 #endif 180