2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.0 of the PHP license, that |
6 | is bundled with this package in the file LICENSE, and is available |
7 | through the world-wide-web at http://www.php.net/license/3_0.txt. |
8 | If you did not receive a copy of the PHP license and are unable to |
9 | obtain it through the world-wide-web, please send a note to |
10 | license@php.net so we can mail you a copy immediately. |
11 +----------------------------------------------------------------------+
12 | Copyright (c) 2004-2005 Michael Wallner <mike@php.net> |
13 +----------------------------------------------------------------------+
24 #include "php_http_std_defs.h"
25 #include "php_http_message_api.h"
26 #include "php_http_headers_api.h"
28 #include "phpstr/phpstr.h"
30 PHP_HTTP_API http_message
*_http_message_init_ex(http_message
*message
, http_message_type type
)
33 message
= ecalloc(1, sizeof(http_message
));
37 message
->nested
= NULL
;
38 phpstr_init(&message
->body
);
39 zend_hash_init(&message
->hdrs
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
44 PHP_HTTP_API http_message
*_http_message_parse_ex(char *message
, size_t message_length
, zend_bool dup TSRMLS_DC
)
47 size_t header_length
= 0;
50 if (message_length
< HTTP_MSG_MIN_SIZE
) {
58 msg
= http_message_new();
59 msg
->len
= message_length
;
60 msg
->raw
= dup
? estrndup(message
, message_length
) : message
;
62 if (body
= strstr(message
, HTTP_CRLF HTTP_CRLF
)) {
63 body
+= lenof(HTTP_CRLF HTTP_CRLF
);
64 header_length
= body
- message
;
66 header_length
= message_length
;
69 http_parse_headers_cb(message
, header_length
, &msg
->hdrs
, 1, http_message_parse_headers_callback
, (void **) &msg
);
72 phpstr_from_string_ex(PHPSTR(msg
), body
, message_length
- header_length
);
78 PHP_HTTP_API
void _http_message_parse_headers_callback(void **message
, char *http_line
, size_t line_length
, HashTable
**headers TSRMLS_DC
)
80 http_message
*old
= (http_message
*) *message
;
83 if (old
->type
|| zend_hash_num_elements(&old
->hdrs
) || PHPSTR_LEN(old
)) {
84 new = http_message_new();
88 *headers
= &new->hdrs
;
94 if (!strncmp(http_line
, "HTTP/1.", lenof("HTTP/1."))) {
95 new->type
= HTTP_MSG_RESPONSE
;
96 new->info
.response
.http_version
= atof(http_line
+ lenof("HTTP/"));
97 new->info
.response
.status
= atoi(http_line
+ lenof("HTTP/1.1 "));
100 if (!strncmp(http_line
+ line_length
- lenof("HTTP/1.1"), "HTTP/1.", lenof("HTTP/1."))) {
101 const char *method_sep_uri
= strchr(http_line
, ' ');
103 new->type
= HTTP_MSG_REQUEST
;
104 new->info
.request
.http_version
= atof(http_line
+ line_length
- lenof("1.1"));
105 new->info
.request
.method
= estrndup(http_line
, method_sep_uri
- http_line
);
106 new->info
.request
.URI
= estrndup(method_sep_uri
+ 1, http_line
+ line_length
- method_sep_uri
- 1 - lenof(" HTTP/1.1"));
110 PHP_HTTP_API
void _http_message_tostring(http_message
*msg
, char **string
, size_t *length
)
117 phpstr_init_ex(&str
, msg
->len
, 1);
118 /* set sane alloc size */
123 case HTTP_MSG_REQUEST
:
124 phpstr_appendf(&str
, "%s %s HTTP/%1.1f" HTTP_CRLF
,
125 msg
->info
.request
.method
,
126 msg
->info
.request
.URI
,
127 msg
->info
.request
.http_version
);
130 case HTTP_MSG_RESPONSE
:
131 phpstr_appendf(&str
, "HTTP/%1.1f %d" HTTP_CRLF
,
132 msg
->info
.response
.http_version
,
133 msg
->info
.response
.status
);
137 FOREACH_HASH_KEYVAL(&msg
->hdrs
, key
, idx
, header
) {
139 zval
**single_header
;
141 switch (Z_TYPE_PP(header
))
144 phpstr_appendf(&str
, "%s: %s" HTTP_CRLF
, key
, Z_STRVAL_PP(header
));
148 FOREACH_VAL(*header
, single_header
) {
149 phpstr_appendf(&str
, "%s: %s" HTTP_CRLF
, key
, Z_STRVAL_PP(single_header
));
158 phpstr_appends(&str
, HTTP_CRLF
);
159 phpstr_append(&str
, PHPSTR_VAL(msg
), PHPSTR_LEN(msg
));
161 data
= phpstr_data(&str
, string
, length
);
169 PHP_HTTP_API
void _http_message_dtor(http_message
*message
)
172 zend_hash_destroy(&message
->hdrs
);
173 phpstr_dtor(PHPSTR(message
));
177 if (message
->type
== HTTP_MSG_REQUEST
) {
178 if (message
->info
.request
.method
) {
179 efree(message
->info
.request
.method
);
181 if (message
->info
.request
.URI
) {
182 efree(message
->info
.request
.URI
);
188 PHP_HTTP_API
void _http_message_free(http_message
*message
)
191 if (message
->nested
) {
192 http_message_free(message
->nested
);
194 http_message_dtor(message
);
204 * vim600: noet sw=4 ts=4 fdm=marker
205 * vim<600: noet sw=4 ts=4