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
void _http_message_dtor(http_message
*message
)
33 zend_hash_destroy(&message
->hdrs
);
34 phpstr_dtor(PHPSTR(message
));
38 if (message
->type
== HTTP_MSG_REQUEST
) {
39 if (message
->info
.request
.method
) {
40 efree(message
->info
.request
.method
);
42 if (message
->info
.request
.URI
) {
43 efree(message
->info
.request
.URI
);
49 PHP_HTTP_API
void _http_message_free(http_message
*message
)
52 if (message
->nested
) {
53 http_message_free(message
->nested
);
55 http_message_dtor(message
);
60 PHP_HTTP_API http_message
*_http_message_init_ex(http_message
*message
, http_message_type type
)
63 message
= ecalloc(1, sizeof(http_message
));
67 message
->nested
= NULL
;
68 phpstr_init(&message
->body
);
69 zend_hash_init(&message
->hdrs
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
74 PHP_HTTP_API http_message
*_http_message_parse_ex(char *message
, size_t length
, zend_bool dup TSRMLS_DC
)
76 char *message_start
= message
, *body
= NULL
;
77 size_t message_length
= length
, header_length
= 0;
80 if (length
< HTTP_MSG_MIN_SIZE
) {
87 if (!(message_start
= strstr(message
, HTTP_CRLF
))) {
91 msg
= http_message_init();
94 msg
->raw
= dup
? estrndup(message
, length
) : message
;
97 if (!strncmp(message
, "HTTP/1.", lenof("HTTP/1."))) {
98 msg
->type
= HTTP_MSG_RESPONSE
;
99 msg
->info
.response
.http_version
= atof(message
+ lenof("HTTP/"));
100 msg
->info
.response
.status
= atoi(message
+ lenof("HTTP/1.1 "));
103 if (!strncmp(message_start
- lenof("HTTP/1.1"), "HTTP/1.", lenof("HTTP/1."))) {
104 const char *method_sep_uri
= strchr(message
, ' ');
106 msg
->type
= HTTP_MSG_REQUEST
;
107 msg
->info
.request
.http_version
= atof(message_start
- lenof("1.1"));
108 msg
->info
.request
.method
= estrndup(message
, method_sep_uri
- message
);
109 msg
->info
.request
.URI
= estrndup(method_sep_uri
+ 1, message_start
- method_sep_uri
- 1 - lenof(" HTTP/1.1"));
111 http_message_free(msg
);
115 message_start
+= lenof(HTTP_CRLF
);
116 message_length
-= message_start
- message
;
118 if (body
= strstr(message_start
, HTTP_CRLF HTTP_CRLF
)) {
119 body
+= lenof(HTTP_CRLF HTTP_CRLF
);
120 header_length
= body
- message_start
;
121 phpstr_from_string_ex(PHPSTR(msg
), body
, message_length
- header_length
);
123 header_length
= message_length
;
126 if (SUCCESS
!= http_parse_headers_ex(message_start
, header_length
, &msg
->hdrs
, 1)) {
127 http_message_free(msg
);
133 PHP_HTTP_API
void _http_message_tostring(http_message
*msg
, char **string
, size_t *length
)
140 phpstr_init_ex(&str
, msg
->len
, 1);
145 case HTTP_MSG_REQUEST
:
146 phpstr_appendf(&str
, "%s %s HTTP/%1.1f" HTTP_CRLF
,
147 msg
->info
.request
.method
,
148 msg
->info
.request
.URI
,
149 msg
->info
.request
.http_version
);
152 case HTTP_MSG_RESPONSE
:
153 phpstr_appendf(&str
, "HTTP/%1.1f %d" HTTP_CRLF
,
154 msg
->info
.response
.http_version
,
155 msg
->info
.response
.status
);
159 FOREACH_HASH_KEYVAL(&msg
->hdrs
, key
, idx
, header
) {
161 switch (Z_TYPE_PP(header
))
164 phpstr_appendf(&str
, "%s: %s" HTTP_CRLF
, key
, Z_STRVAL_PP(header
));
169 zval
**single_header
;
171 FOREACH_VAL(*header
, single_header
) {
172 phpstr_appendf(&str
, "%s: %s" HTTP_CRLF
, key
, Z_STRVAL_PP(single_header
));
182 phpstr_appends(&str
, HTTP_CRLF
);
183 phpstr_append(&str
, PHPSTR_VAL(msg
), PHPSTR_LEN(msg
));
186 data
= phpstr_data(&str
, string
, length
);