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 "win32/php_stdint.h" 33 # include "config.w32.h" 34 #else 35 # include "php_config.h" 36 # ifdef HAVE_STDINT_H 37 # include <stdint.h> 38 # endif 39 #endif 40 41 /* Compile with -DPHP_HTTP_PARSER_STRICT=0 to make less checks, but run 42 * faster 43 */ 44 #ifndef PHP_HTTP_PARSER_STRICT 45 # define PHP_HTTP_PARSER_STRICT 1 46 #else 47 # define PHP_HTTP_PARSER_STRICT 0 48 #endif 49 50 51 /* Maximium header size allowed */ 52 #define PHP_HTTP_MAX_HEADER_SIZE (80*1024) 53 54 55 typedef struct php_http_parser php_http_parser; 56 typedef struct php_http_parser_settings php_http_parser_settings; 57 58 59 /* Callbacks should return non-zero to indicate an error. The parser will 60 * then halt execution. 61 * 62 * The one exception is on_headers_complete. In a PHP_HTTP_RESPONSE parser 63 * returning '1' from on_headers_complete will tell the parser that it 64 * should not expect a body. This is used when receiving a response to a 65 * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: 66 * chunked' headers that indicate the presence of a body. 67 * 68 * http_data_cb does not return data chunks. It will be call arbitrarally 69 * many times for each string. E.G. you might get 10 callbacks for "on_path" 70 * each providing just a few characters more data. 71 */ 72 typedef int (*php_http_data_cb) (php_http_parser*, const char *at, size_t length); 73 typedef int (*php_http_cb) (php_http_parser*); 74 75 76 /* Request Methods */ 77 enum php_http_method 78 { PHP_HTTP_DELETE = 0 79 , PHP_HTTP_GET 80 , PHP_HTTP_HEAD 81 , PHP_HTTP_POST 82 , PHP_HTTP_PUT 83 , PHP_HTTP_PATCH 84 /* pathological */ 85 , PHP_HTTP_CONNECT 86 , PHP_HTTP_OPTIONS 87 , PHP_HTTP_TRACE 88 /* webdav */ 89 , PHP_HTTP_COPY 90 , PHP_HTTP_LOCK 91 , PHP_HTTP_MKCOL 92 , PHP_HTTP_MOVE 93 , PHP_HTTP_PROPFIND 94 , PHP_HTTP_PROPPATCH 95 , PHP_HTTP_UNLOCK 96 /* subversion */ 97 , PHP_HTTP_REPORT 98 , PHP_HTTP_MKACTIVITY 99 , PHP_HTTP_CHECKOUT 100 , PHP_HTTP_MERGE 101 /* upnp */ 102 , PHP_HTTP_MSEARCH 103 , PHP_HTTP_NOTIFY 104 , PHP_HTTP_SUBSCRIBE 105 , PHP_HTTP_UNSUBSCRIBE 106 /* unknown, not implemented */ 107 , PHP_HTTP_NOT_IMPLEMENTED 108 }; 109 110 111 enum php_http_parser_type { PHP_HTTP_REQUEST, PHP_HTTP_RESPONSE, PHP_HTTP_BOTH }; 112 113 114 struct php_http_parser { 115 /** PRIVATE **/ 116 unsigned char type : 2; 117 unsigned char flags : 6; 118 unsigned char state; 119 unsigned char header_state; 120 unsigned char index; 121 122 uint32_t nread; 123 ssize_t content_length; 124 125 /** READ-ONLY **/ 126 unsigned short http_major; 127 unsigned short http_minor; 128 unsigned short status_code; /* responses only */ 129 unsigned char method; /* requests only */ 130 131 /* 1 = Upgrade header was present and the parser has exited because of that. 132 * 0 = No upgrade header present. 133 * Should be checked when http_parser_execute() returns in addition to 134 * error checking. 135 */ 136 char upgrade; 137 138 /** PUBLIC **/ 139 void *data; /* A pointer to get hook to the "connection" or "socket" object */ 140 }; 141 142 143 struct php_http_parser_settings { 144 php_http_cb on_message_begin; 145 php_http_data_cb on_path; 146 php_http_data_cb on_query_string; 147 php_http_data_cb on_url; 148 php_http_data_cb on_fragment; 149 php_http_data_cb on_header_field; 150 php_http_data_cb on_header_value; 151 php_http_cb on_headers_complete; 152 php_http_data_cb on_body; 153 php_http_cb on_message_complete; 154 }; 155 156 157 void php_http_parser_init(php_http_parser *parser, enum php_http_parser_type type); 158 159 160 size_t php_http_parser_execute(php_http_parser *parser, 161 const php_http_parser_settings *settings, 162 const char *data, 163 size_t len); 164 165 166 /* If php_http_should_keep_alive() in the on_headers_complete or 167 * on_message_complete callback returns true, then this will be should be 168 * the last message on the connection. 169 * If you are the server, respond with the "Connection: close" header. 170 * If you are the client, close the connection. 171 */ 172 int php_http_should_keep_alive(php_http_parser *parser); 173 174 /* Returns a string version of the HTTP method. */ 175 const char *php_http_method_str(enum php_http_method); 176 177 #ifdef __cplusplus 178 } 179 #endif 180 #endif 181