xref: /PHP-5.5/sapi/cli/php_http_parser.h (revision aa133ea2)
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