Line data Source code
1 : /*
2 : +--------------------------------------------------------------------+
3 : | PECL :: http |
4 : +--------------------------------------------------------------------+
5 : | Redistribution and use in source and binary forms, with or without |
6 : | modification, are permitted provided that the conditions mentioned |
7 : | in the accompanying LICENSE file are met. |
8 : +--------------------------------------------------------------------+
9 : | Copyright (c) 2004-2014, Michael Wallner <mike@php.net> |
10 : +--------------------------------------------------------------------+
11 : */
12 :
13 : #include "php_http_api.h"
14 :
15 : static void message_headers(php_http_message_t *msg, php_http_buffer_t *str);
16 :
17 126 : zend_bool php_http_message_info_callback(php_http_message_t **message, HashTable **headers, php_http_info_t *info TSRMLS_DC)
18 : {
19 126 : php_http_message_t *old = *message;
20 :
21 : /* advance message */
22 126 : if (!old || old->type || zend_hash_num_elements(&old->hdrs)) {
23 48 : (*message) = php_http_message_init(NULL, 0, NULL TSRMLS_CC);
24 48 : (*message)->parent = old;
25 48 : if (headers) {
26 48 : (*headers) = &((*message)->hdrs);
27 : }
28 : }
29 :
30 126 : if (info) {
31 125 : php_http_message_set_info(*message, info);
32 : }
33 :
34 126 : return old != *message;
35 : }
36 :
37 358 : php_http_message_t *php_http_message_init(php_http_message_t *message, php_http_message_type_t type, php_http_message_body_t *body TSRMLS_DC)
38 : {
39 358 : if (!message) {
40 358 : message = emalloc(sizeof(*message));
41 : }
42 358 : memset(message, 0, sizeof(*message));
43 : TSRMLS_SET_CTX(message->ts);
44 :
45 358 : php_http_message_set_type(message, type);
46 358 : message->http.version.major = 1;
47 358 : message->http.version.minor = 1;
48 358 : zend_hash_init(&message->hdrs, 0, NULL, ZVAL_PTR_DTOR, 0);
49 358 : message->body = body ? body : php_http_message_body_init(NULL, NULL TSRMLS_CC);
50 :
51 358 : return message;
52 : }
53 :
54 36 : php_http_message_t *php_http_message_init_env(php_http_message_t *message, php_http_message_type_t type TSRMLS_DC)
55 : {
56 36 : int free_msg = !message;
57 : zval *sval, tval;
58 : php_http_message_body_t *mbody;
59 :
60 36 : switch (type) {
61 : case PHP_HTTP_REQUEST:
62 12 : mbody = php_http_env_get_request_body(TSRMLS_C);
63 12 : php_http_message_body_addref(mbody);
64 12 : message = php_http_message_init(message, type, mbody TSRMLS_CC);
65 12 : if ((sval = php_http_env_get_server_var(ZEND_STRL("SERVER_PROTOCOL"), 1 TSRMLS_CC)) && !strncmp(Z_STRVAL_P(sval), "HTTP/", lenof("HTTP/"))) {
66 0 : php_http_version_parse(&message->http.version, Z_STRVAL_P(sval) TSRMLS_CC);
67 : }
68 12 : if ((sval = php_http_env_get_server_var(ZEND_STRL("REQUEST_METHOD"), 1 TSRMLS_CC))) {
69 12 : message->http.info.request.method = estrdup(Z_STRVAL_P(sval));
70 : }
71 12 : if ((sval = php_http_env_get_server_var(ZEND_STRL("REQUEST_URI"), 1 TSRMLS_CC))) {
72 0 : message->http.info.request.url = php_http_url_parse(Z_STRVAL_P(sval), Z_STRLEN_P(sval), ~0 TSRMLS_CC);
73 : }
74 :
75 12 : php_http_env_get_request_headers(&message->hdrs TSRMLS_CC);
76 12 : break;
77 :
78 : case PHP_HTTP_RESPONSE:
79 24 : message = php_http_message_init(NULL, type, NULL TSRMLS_CC);
80 24 : if (!SG(sapi_headers).http_status_line || !php_http_info_parse((php_http_info_t *) &message->http, SG(sapi_headers).http_status_line TSRMLS_CC)) {
81 24 : if (!(message->http.info.response.code = SG(sapi_headers).http_response_code)) {
82 11 : message->http.info.response.code = 200;
83 : }
84 24 : message->http.info.response.status = estrdup(php_http_env_get_response_status_for_code(message->http.info.response.code));
85 : }
86 :
87 24 : php_http_env_get_response_headers(&message->hdrs TSRMLS_CC);
88 : #if PHP_VERSION_ID >= 50400
89 24 : if (php_output_get_level(TSRMLS_C)) {
90 2 : if (php_output_get_status(TSRMLS_C) & PHP_OUTPUT_SENT) {
91 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch response body, output has already been sent at %s:%d", php_output_get_start_filename(TSRMLS_C), php_output_get_start_lineno(TSRMLS_C));
92 1 : goto error;
93 1 : } else if (SUCCESS != php_output_get_contents(&tval TSRMLS_CC)) {
94 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch response body");
95 0 : goto error;
96 : } else {
97 1 : php_http_message_body_append(message->body, Z_STRVAL(tval), Z_STRLEN(tval));
98 1 : zval_dtor(&tval);
99 : }
100 : }
101 : #else
102 : if (OG(ob_nesting_level)) {
103 : if (php_get_output_start_filename(TSRMLS_C)) {
104 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch response body, output has already been sent at %s:%d", php_get_output_start_filename(TSRMLS_C), php_get_output_start_lineno(TSRMLS_C));
105 : goto error;
106 : } else if (SUCCESS != php_ob_get_buffer(&tval TSRMLS_CC)) {
107 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch response body");
108 : goto error;
109 : } else {
110 : php_http_message_body_append(message->body, Z_STRVAL(tval), Z_STRLEN(tval));
111 : zval_dtor(&tval);
112 : }
113 : }
114 : #endif
115 23 : break;
116 :
117 : default:
118 : error:
119 1 : if (free_msg) {
120 1 : if (message) {
121 1 : php_http_message_free(&message);
122 : }
123 : } else {
124 0 : message = NULL;
125 : }
126 1 : break;
127 : }
128 :
129 36 : return message;
130 : }
131 :
132 41 : php_http_message_t *php_http_message_parse(php_http_message_t *msg, const char *str, size_t len, zend_bool greedy TSRMLS_DC)
133 : {
134 : php_http_message_parser_t p;
135 : php_http_buffer_t buf;
136 41 : unsigned flags = PHP_HTTP_MESSAGE_PARSER_CLEANUP;
137 : int free_msg;
138 :
139 41 : php_http_buffer_from_string_ex(&buf, str, len);
140 41 : php_http_message_parser_init(&p TSRMLS_CC);
141 :
142 41 : if ((free_msg = !msg)) {
143 41 : msg = php_http_message_init(NULL, 0, NULL TSRMLS_CC);
144 : }
145 :
146 41 : if (greedy) {
147 41 : flags |= PHP_HTTP_MESSAGE_PARSER_GREEDY;
148 : }
149 41 : if (PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE == php_http_message_parser_parse(&p, &buf, flags, &msg)) {
150 6 : if (free_msg) {
151 6 : php_http_message_free(&msg);
152 : }
153 6 : msg = NULL;
154 : }
155 :
156 41 : php_http_message_parser_dtor(&p);
157 41 : php_http_buffer_dtor(&buf);
158 :
159 41 : return msg;
160 : }
161 :
162 853 : zval *php_http_message_header(php_http_message_t *msg, const char *key_str, size_t key_len, int join)
163 : {
164 853 : zval *ret = NULL, **header;
165 : char *key;
166 : ALLOCA_FLAG(free_key);
167 :
168 853 : key = do_alloca(key_len + 1, free_key);
169 853 : memcpy(key, key_str, key_len);
170 853 : key[key_len] = '\0';
171 853 : php_http_pretty_key(key, key_len, 1, 1);
172 :
173 853 : if (SUCCESS == zend_symtable_find(&msg->hdrs, key, key_len + 1, (void *) &header)) {
174 88 : if (join && Z_TYPE_PP(header) == IS_ARRAY) {
175 : TSRMLS_FETCH_FROM_CTX(msg->ts);
176 :
177 0 : ret = php_http_header_value_to_string(*header TSRMLS_CC);
178 : } else {
179 88 : Z_ADDREF_PP(header);
180 88 : ret = *header;
181 : }
182 : }
183 :
184 853 : free_alloca(key, free_key);
185 :
186 853 : return ret;
187 : }
188 :
189 2 : zend_bool php_http_message_is_multipart(php_http_message_t *msg, char **boundary)
190 : {
191 2 : zval *ct = php_http_message_header(msg, ZEND_STRL("Content-Type"), 1);
192 2 : zend_bool is_multipart = 0;
193 : TSRMLS_FETCH_FROM_CTX(msg->ts);
194 :
195 2 : if (ct) {
196 : php_http_params_opts_t popts;
197 : HashTable params;
198 :
199 2 : ZEND_INIT_SYMTABLE(¶ms);
200 2 : php_http_params_opts_default_get(&popts);
201 2 : popts.input.str = Z_STRVAL_P(ct);
202 2 : popts.input.len = Z_STRLEN_P(ct);
203 :
204 2 : if (php_http_params_parse(¶ms, &popts TSRMLS_CC)) {
205 : zval **cur, **arg;
206 : char *ct_str;
207 :
208 2 : zend_hash_internal_pointer_reset(¶ms);
209 :
210 2 : if (SUCCESS == zend_hash_get_current_data(¶ms, (void *) &cur)
211 2 : && Z_TYPE_PP(cur) == IS_ARRAY
212 2 : && HASH_KEY_IS_STRING == zend_hash_get_current_key(¶ms, &ct_str, NULL, 0)
213 : ) {
214 2 : if (php_http_match(ct_str, "multipart", PHP_HTTP_MATCH_WORD)) {
215 2 : is_multipart = 1;
216 :
217 : /* get boundary */
218 2 : if (boundary
219 2 : && SUCCESS == zend_hash_find(Z_ARRVAL_PP(cur), ZEND_STRS("arguments"), (void *) &arg)
220 2 : && Z_TYPE_PP(arg) == IS_ARRAY
221 : ) {
222 : zval **val;
223 : HashPosition pos;
224 2 : php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
225 :
226 4 : FOREACH_KEYVAL(pos, *arg, key, val) {
227 2 : if (key.type == HASH_KEY_IS_STRING && !strcasecmp(key.str, "boundary")) {
228 2 : zval *bnd = php_http_ztyp(IS_STRING, *val);
229 :
230 2 : if (Z_STRLEN_P(bnd)) {
231 2 : *boundary = estrndup(Z_STRVAL_P(bnd), Z_STRLEN_P(bnd));
232 : }
233 2 : zval_ptr_dtor(&bnd);
234 : }
235 : }
236 : }
237 : }
238 : }
239 : }
240 2 : zend_hash_destroy(¶ms);
241 2 : zval_ptr_dtor(&ct);
242 : }
243 :
244 2 : return is_multipart;
245 : }
246 :
247 : /* */
248 649 : void php_http_message_set_type(php_http_message_t *message, php_http_message_type_t type)
249 : {
250 : /* just act if different */
251 649 : if (type != message->type) {
252 :
253 : /* free request info */
254 331 : switch (message->type) {
255 : case PHP_HTTP_REQUEST:
256 1 : PTR_FREE(message->http.info.request.method);
257 1 : PTR_FREE(message->http.info.request.url);
258 1 : break;
259 :
260 : case PHP_HTTP_RESPONSE:
261 1 : PTR_FREE(message->http.info.response.status);
262 1 : break;
263 :
264 : default:
265 329 : break;
266 : }
267 :
268 331 : message->type = type;
269 331 : memset(&message->http, 0, sizeof(message->http));
270 : }
271 649 : }
272 :
273 241 : void php_http_message_set_info(php_http_message_t *message, php_http_info_t *info)
274 : {
275 241 : php_http_message_set_type(message, info->type);
276 241 : message->http.version = info->http.version;
277 241 : switch (message->type) {
278 : case PHP_HTTP_REQUEST:
279 149 : PTR_SET(PHP_HTTP_INFO(message).request.url, PHP_HTTP_INFO(info).request.url ? php_http_url_copy(PHP_HTTP_INFO(info).request.url, 0) : NULL);
280 149 : PTR_SET(PHP_HTTP_INFO(message).request.method, PHP_HTTP_INFO(info).request.method ? estrdup(PHP_HTTP_INFO(info).request.method) : NULL);
281 149 : break;
282 :
283 : case PHP_HTTP_RESPONSE:
284 92 : PHP_HTTP_INFO(message).response.code = PHP_HTTP_INFO(info).response.code;
285 92 : PTR_SET(PHP_HTTP_INFO(message).response.status, PHP_HTTP_INFO(info).response.status ? estrdup(PHP_HTTP_INFO(info).response.status) : NULL);
286 92 : break;
287 :
288 : default:
289 0 : break;
290 : }
291 241 : }
292 :
293 226 : void php_http_message_update_headers(php_http_message_t *msg)
294 : {
295 : zval *h;
296 : size_t size;
297 :
298 226 : if (php_http_message_body_stream(msg->body)->readfilters.head) {
299 : /* if a read stream filter is attached to the body the caller must also care for the headers */
300 226 : } else if ((h = php_http_message_header(msg, ZEND_STRL("Content-Range"), 0))) {
301 : /* don't mess around with a Content-Range message */
302 3 : zval_ptr_dtor(&h);
303 223 : } else if ((size = php_http_message_body_size(msg->body))) {
304 54 : MAKE_STD_ZVAL(h);
305 54 : ZVAL_LONG(h, size);
306 54 : zend_hash_update(&msg->hdrs, "Content-Length", sizeof("Content-Length"), &h, sizeof(zval *), NULL);
307 :
308 54 : if (msg->body->boundary) {
309 : char *str;
310 : size_t len;
311 :
312 2 : if (!(h = php_http_message_header(msg, ZEND_STRL("Content-Type"), 1))) {
313 2 : len = spprintf(&str, 0, "multipart/form-data; boundary=\"%s\"", msg->body->boundary);
314 2 : MAKE_STD_ZVAL(h);
315 2 : ZVAL_STRINGL(h, str, len, 0);
316 2 : zend_hash_update(&msg->hdrs, "Content-Type", sizeof("Content-Type"), &h, sizeof(zval *), NULL);
317 0 : } else if (!php_http_match(Z_STRVAL_P(h), "boundary=", PHP_HTTP_MATCH_WORD)) {
318 0 : zval_dtor(h);
319 0 : Z_STRLEN_P(h) = spprintf(&Z_STRVAL_P(h), 0, "%s; boundary=\"%s\"", Z_STRVAL_P(h), msg->body->boundary);
320 0 : zend_hash_update(&msg->hdrs, "Content-Type", sizeof("Content-Type"), &h, sizeof(zval *), NULL);
321 : } else {
322 0 : zval_ptr_dtor(&h);
323 : }
324 : }
325 169 : } else if ((h = php_http_message_header(msg, ZEND_STRL("Content-Length"), 1))) {
326 8 : zval *h_cpy = php_http_ztyp(IS_LONG, h);
327 :
328 8 : zval_ptr_dtor(&h);
329 8 : if (Z_LVAL_P(h_cpy)) {
330 : /* body->size == 0, so get rid of old Content-Length */
331 3 : zend_hash_del(&msg->hdrs, "Content-Length", sizeof("Content-Length"));
332 : }
333 8 : zval_ptr_dtor(&h_cpy);
334 : }
335 226 : }
336 :
337 114 : static void message_headers(php_http_message_t *msg, php_http_buffer_t *str)
338 : {
339 114 : char *tmp = NULL;
340 : TSRMLS_FETCH_FROM_CTX(msg->ts);
341 :
342 114 : switch (msg->type) {
343 : case PHP_HTTP_REQUEST:
344 44 : php_http_buffer_appendf(str, PHP_HTTP_INFO_REQUEST_FMT_ARGS(&msg->http, tmp, PHP_HTTP_CRLF));
345 44 : PTR_FREE(tmp);
346 44 : break;
347 :
348 : case PHP_HTTP_RESPONSE:
349 60 : php_http_buffer_appendf(str, PHP_HTTP_INFO_RESPONSE_FMT_ARGS(&msg->http, tmp, PHP_HTTP_CRLF));
350 60 : PTR_FREE(tmp);
351 60 : break;
352 :
353 : default:
354 10 : break;
355 : }
356 :
357 114 : php_http_message_update_headers(msg);
358 114 : php_http_header_to_string(str, &msg->hdrs TSRMLS_CC);
359 114 : }
360 :
361 44 : void php_http_message_to_callback(php_http_message_t *msg, php_http_pass_callback_t cb, void *cb_arg)
362 : {
363 : php_http_buffer_t str;
364 :
365 44 : php_http_buffer_init_ex(&str, 0x1000, 0);
366 44 : message_headers(msg, &str);
367 44 : cb(cb_arg, str.data, str.used);
368 44 : php_http_buffer_dtor(&str);
369 :
370 44 : if (php_http_message_body_size(msg->body)) {
371 11 : cb(cb_arg, ZEND_STRL(PHP_HTTP_CRLF));
372 11 : php_http_message_body_to_callback(msg->body, cb, cb_arg, 0, 0);
373 : }
374 44 : }
375 :
376 70 : void php_http_message_to_string(php_http_message_t *msg, char **string, size_t *length)
377 : {
378 : php_http_buffer_t str;
379 : char *data;
380 :
381 70 : php_http_buffer_init_ex(&str, 0x1000, 0);
382 70 : message_headers(msg, &str);
383 70 : if (php_http_message_body_size(msg->body)) {
384 15 : php_http_buffer_appends(&str, PHP_HTTP_CRLF);
385 15 : php_http_message_body_to_callback(msg->body, (php_http_pass_callback_t) php_http_buffer_append, &str, 0, 0);
386 : }
387 :
388 70 : data = php_http_buffer_data(&str, string, length);
389 70 : if (!string) {
390 0 : efree(data);
391 : }
392 :
393 70 : php_http_buffer_dtor(&str);
394 70 : }
395 :
396 12 : void php_http_message_serialize(php_http_message_t *message, char **string, size_t *length)
397 : {
398 : char *buf;
399 : php_http_buffer_t str;
400 : php_http_message_t *msg;
401 :
402 12 : php_http_buffer_init(&str);
403 :
404 12 : msg = message = php_http_message_reverse(message);
405 : do {
406 39 : php_http_message_to_callback(message, (php_http_pass_callback_t) php_http_buffer_append, &str);
407 39 : php_http_buffer_appends(&str, PHP_HTTP_CRLF);
408 39 : } while ((message = message->parent));
409 12 : php_http_message_reverse(msg);
410 :
411 12 : buf = php_http_buffer_data(&str, string, length);
412 12 : if (!string) {
413 0 : efree(buf);
414 : }
415 :
416 12 : php_http_buffer_dtor(&str);
417 12 : }
418 :
419 24 : php_http_message_t *php_http_message_reverse(php_http_message_t *msg)
420 : {
421 24 : int i, c = 0;
422 :
423 24 : php_http_message_count(c, msg);
424 :
425 24 : if (c > 1) {
426 12 : php_http_message_t *tmp = msg, **arr;
427 :
428 12 : arr = ecalloc(c, sizeof(**arr));
429 78 : for (i = 0; i < c; ++i) {
430 66 : arr[i] = tmp;
431 66 : tmp = tmp->parent;
432 : }
433 12 : arr[0]->parent = NULL;
434 66 : for (i = 0; i < c-1; ++i) {
435 54 : arr[i+1]->parent = arr[i];
436 : }
437 :
438 12 : msg = arr[c-1];
439 12 : efree(arr);
440 : }
441 :
442 24 : return msg;
443 : }
444 :
445 2 : php_http_message_t *php_http_message_zip(php_http_message_t *one, php_http_message_t *two)
446 : {
447 2 : php_http_message_t *dst = php_http_message_copy(one, NULL), *src = php_http_message_copy(two, NULL), *tmp_dst, *tmp_src, *ret = dst;
448 :
449 6 : while(dst && src) {
450 2 : tmp_dst = dst->parent;
451 2 : tmp_src = src->parent;
452 2 : dst->parent = src;
453 2 : if (tmp_dst) {
454 0 : src->parent = tmp_dst;
455 : }
456 2 : src = tmp_src;
457 2 : dst = tmp_dst;
458 : }
459 :
460 2 : return ret;
461 : }
462 :
463 114 : php_http_message_t *php_http_message_copy_ex(php_http_message_t *from, php_http_message_t *to, zend_bool parents)
464 : {
465 114 : php_http_message_t *temp, *copy = NULL;
466 : php_http_info_t info;
467 : TSRMLS_FETCH_FROM_CTX(from->ts);
468 :
469 114 : if (from) {
470 114 : info.type = from->type;
471 114 : info.http = from->http;
472 :
473 114 : copy = temp = php_http_message_init(to, 0, php_http_message_body_copy(from->body, NULL) TSRMLS_CC);
474 114 : php_http_message_set_info(temp, &info);
475 114 : zend_hash_copy(&temp->hdrs, &from->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
476 :
477 228 : if (parents) while (from->parent) {
478 1 : info.type = from->parent->type;
479 1 : info.http = from->parent->http;
480 :
481 1 : temp->parent = php_http_message_init(NULL, 0, php_http_message_body_copy(from->parent->body, NULL) TSRMLS_CC);
482 1 : php_http_message_set_info(temp->parent, &info);
483 1 : zend_hash_copy(&temp->parent->hdrs, &from->parent->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
484 :
485 1 : temp = temp->parent;
486 1 : from = from->parent;
487 : }
488 : }
489 :
490 114 : return copy;
491 : }
492 :
493 113 : php_http_message_t *php_http_message_copy(php_http_message_t *from, php_http_message_t *to)
494 : {
495 113 : return php_http_message_copy_ex(from, to, 1);
496 : }
497 :
498 395 : void php_http_message_dtor(php_http_message_t *message)
499 : {
500 395 : if (message) {
501 358 : zend_hash_destroy(&message->hdrs);
502 358 : php_http_message_body_free(&message->body);
503 :
504 358 : switch (message->type) {
505 : case PHP_HTTP_REQUEST:
506 214 : PTR_SET(message->http.info.request.method, NULL);
507 214 : PTR_SET(message->http.info.request.url, NULL);
508 214 : break;
509 :
510 : case PHP_HTTP_RESPONSE:
511 115 : PTR_SET(message->http.info.response.status, NULL);
512 115 : break;
513 :
514 : default:
515 29 : break;
516 : }
517 : }
518 395 : }
519 :
520 164 : void php_http_message_free(php_http_message_t **message)
521 : {
522 164 : if (*message) {
523 20 : if ((*message)->parent) {
524 0 : php_http_message_free(&(*message)->parent);
525 : }
526 20 : php_http_message_dtor(*message);
527 20 : efree(*message);
528 20 : *message = NULL;
529 : }
530 164 : }
531 :
532 : static zval *php_http_message_object_read_prop(zval *object, zval *member, int type PHP_HTTP_ZEND_LITERAL_DC TSRMLS_DC);
533 : static void php_http_message_object_write_prop(zval *object, zval *member, zval *value PHP_HTTP_ZEND_LITERAL_DC TSRMLS_DC);
534 : static HashTable *php_http_message_object_get_props(zval *object TSRMLS_DC);
535 :
536 : static zend_object_handlers php_http_message_object_handlers;
537 : static HashTable php_http_message_object_prophandlers;
538 :
539 : typedef void (*php_http_message_object_prophandler_func_t)(php_http_message_object_t *o, zval *v TSRMLS_DC);
540 :
541 : typedef struct php_http_message_object_prophandler {
542 : php_http_message_object_prophandler_func_t read;
543 : php_http_message_object_prophandler_func_t write;
544 : } php_http_message_object_prophandler_t;
545 :
546 3366 : static STATUS php_http_message_object_add_prophandler(const char *prop_str, size_t prop_len, php_http_message_object_prophandler_func_t read, php_http_message_object_prophandler_func_t write) {
547 3366 : php_http_message_object_prophandler_t h = { read, write };
548 3366 : return zend_hash_add(&php_http_message_object_prophandlers, prop_str, prop_len + 1, (void *) &h, sizeof(h), NULL);
549 : }
550 717 : static STATUS php_http_message_object_get_prophandler(const char *prop_str, size_t prop_len, php_http_message_object_prophandler_t **handler) {
551 717 : return zend_hash_find(&php_http_message_object_prophandlers, prop_str, prop_len + 1, (void *) handler);
552 : }
553 2 : static void php_http_message_object_prophandler_get_type(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) {
554 2 : RETVAL_LONG(obj->message->type);
555 2 : }
556 2 : static void php_http_message_object_prophandler_set_type(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
557 2 : zval *cpy = php_http_ztyp(IS_LONG, value);
558 2 : php_http_message_set_type(obj->message, Z_LVAL_P(cpy));
559 2 : zval_ptr_dtor(&cpy);
560 2 : }
561 2 : static void php_http_message_object_prophandler_get_request_method(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) {
562 2 : if (PHP_HTTP_MESSAGE_TYPE(REQUEST, obj->message) && obj->message->http.info.request.method) {
563 1 : RETVAL_STRING(obj->message->http.info.request.method, 1);
564 : } else {
565 1 : RETVAL_NULL();
566 : }
567 2 : }
568 1 : static void php_http_message_object_prophandler_set_request_method(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
569 1 : if (PHP_HTTP_MESSAGE_TYPE(REQUEST, obj->message)) {
570 1 : zval *cpy = php_http_ztyp(IS_STRING, value);
571 1 : PTR_SET(obj->message->http.info.request.method, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
572 1 : zval_ptr_dtor(&cpy);
573 : }
574 1 : }
575 2 : static void php_http_message_object_prophandler_get_request_url(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) {
576 : char *url_str;
577 : size_t url_len;
578 :
579 2 : if (PHP_HTTP_MESSAGE_TYPE(REQUEST, obj->message) && obj->message->http.info.request.url && php_http_url_to_string(obj->message->http.info.request.url, &url_str, &url_len, 0)) {
580 1 : RETVAL_STRINGL(url_str, url_len, 0);
581 : } else {
582 1 : RETVAL_NULL();
583 : }
584 2 : }
585 1 : static void php_http_message_object_prophandler_set_request_url(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
586 1 : if (PHP_HTTP_MESSAGE_TYPE(REQUEST, obj->message)) {
587 1 : PTR_SET(obj->message->http.info.request.url, php_http_url_from_zval(value, ~0 TSRMLS_CC));
588 : }
589 1 : }
590 4 : static void php_http_message_object_prophandler_get_response_status(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) {
591 4 : if (PHP_HTTP_MESSAGE_TYPE(RESPONSE, obj->message) && obj->message->http.info.response.status) {
592 3 : RETVAL_STRING(obj->message->http.info.response.status, 1);
593 : } else {
594 1 : RETVAL_NULL();
595 : }
596 4 : }
597 1 : static void php_http_message_object_prophandler_set_response_status(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
598 1 : if (PHP_HTTP_MESSAGE_TYPE(RESPONSE, obj->message)) {
599 1 : zval *cpy = php_http_ztyp(IS_STRING, value);
600 1 : PTR_SET(obj->message->http.info.response.status, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
601 1 : zval_ptr_dtor(&cpy);
602 : }
603 1 : }
604 24 : static void php_http_message_object_prophandler_get_response_code(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) {
605 24 : if (PHP_HTTP_MESSAGE_TYPE(RESPONSE, obj->message)) {
606 23 : RETVAL_LONG(obj->message->http.info.response.code);
607 : } else {
608 1 : RETVAL_NULL();
609 : }
610 24 : }
611 1 : static void php_http_message_object_prophandler_set_response_code(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
612 1 : if (PHP_HTTP_MESSAGE_TYPE(RESPONSE, obj->message)) {
613 1 : zval *cpy = php_http_ztyp(IS_LONG, value);
614 1 : obj->message->http.info.response.code = Z_LVAL_P(cpy);
615 1 : PTR_SET(obj->message->http.info.response.status, estrdup(php_http_env_get_response_status_for_code(obj->message->http.info.response.code)));
616 1 : zval_ptr_dtor(&cpy);
617 : }
618 1 : }
619 24 : static void php_http_message_object_prophandler_get_http_version(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) {
620 : char *version_str;
621 : size_t version_len;
622 :
623 24 : php_http_version_to_string(&obj->message->http.version, &version_str, &version_len, NULL, NULL TSRMLS_CC);
624 24 : RETVAL_STRINGL(version_str, version_len, 0);
625 24 : }
626 1 : static void php_http_message_object_prophandler_set_http_version(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
627 1 : zval *cpy = php_http_ztyp(IS_STRING, value);
628 1 : php_http_version_parse(&obj->message->http.version, Z_STRVAL_P(cpy) TSRMLS_CC);
629 1 : zval_ptr_dtor(&cpy);
630 1 : }
631 43 : static void php_http_message_object_prophandler_get_headers(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) {
632 43 : array_init(return_value);
633 43 : zend_hash_copy(Z_ARRVAL_P(return_value), &obj->message->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
634 43 : }
635 9 : static void php_http_message_object_prophandler_set_headers(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
636 9 : zval *cpy = php_http_ztyp(IS_ARRAY, value);
637 :
638 9 : zend_hash_clean(&obj->message->hdrs);
639 9 : zend_hash_copy(&obj->message->hdrs, Z_ARRVAL_P(cpy), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
640 9 : zval_ptr_dtor(&cpy);
641 9 : }
642 93 : static void php_http_message_object_prophandler_get_body(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) {
643 93 : if (obj->body) {
644 82 : RETVAL_OBJVAL(obj->body->zv, 1);
645 : } else {
646 11 : RETVAL_NULL();
647 : }
648 93 : }
649 18 : static void php_http_message_object_prophandler_set_body(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
650 18 : php_http_message_object_set_body(obj, value TSRMLS_CC);
651 18 : }
652 2 : static void php_http_message_object_prophandler_get_parent_message(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) {
653 2 : if (obj->message->parent) {
654 1 : RETVAL_OBJVAL(obj->parent->zv, 1);
655 : } else {
656 1 : RETVAL_NULL();
657 : }
658 2 : }
659 1 : static void php_http_message_object_prophandler_set_parent_message(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
660 1 : if (Z_TYPE_P(value) == IS_OBJECT && instanceof_function(Z_OBJCE_P(value), php_http_message_class_entry TSRMLS_CC)) {
661 1 : php_http_message_object_t *parent_obj = zend_object_store_get_object(value TSRMLS_CC);
662 :
663 1 : if (obj->message->parent) {
664 0 : zend_objects_store_del_ref_by_handle(obj->parent->zv.handle TSRMLS_CC);
665 : }
666 1 : Z_OBJ_ADDREF_P(value);
667 1 : obj->parent = parent_obj;
668 1 : obj->message->parent = parent_obj->message;
669 : }
670 1 : }
671 :
672 : #define PHP_HTTP_MESSAGE_OBJECT_INIT(obj) \
673 : do { \
674 : if (!obj->message) { \
675 : obj->message = php_http_message_init(NULL, 0, NULL TSRMLS_CC); \
676 : } \
677 : } while(0)
678 :
679 :
680 2 : void php_http_message_object_reverse(zval *this_ptr, zval *return_value TSRMLS_DC)
681 : {
682 2 : int i = 0;
683 2 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
684 :
685 2 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
686 :
687 : /* count */
688 2 : php_http_message_count(i, obj->message);
689 :
690 2 : if (i > 1) {
691 : php_http_message_object_t **objects;
692 : int last;
693 :
694 2 : objects = ecalloc(i, sizeof(**objects));
695 :
696 : /* we are the first message */
697 2 : objects[0] = obj;
698 :
699 : /* fetch parents */
700 12 : for (i = 1; obj->parent; ++i) {
701 10 : objects[i] = obj = obj->parent;
702 : }
703 :
704 : /* reorder parents */
705 12 : for (last = --i; i; --i) {
706 10 : objects[i]->message->parent = objects[i-1]->message;
707 10 : objects[i]->parent = objects[i-1];
708 : }
709 :
710 2 : objects[0]->message->parent = NULL;
711 2 : objects[0]->parent = NULL;
712 :
713 : /* add ref, because we previously have not been a parent message */
714 2 : Z_OBJ_ADDREF_P(getThis());
715 2 : RETVAL_OBJVAL(objects[last]->zv, 0);
716 :
717 2 : efree(objects);
718 : } else {
719 0 : RETURN_ZVAL(getThis(), 1, 0);
720 : }
721 : }
722 :
723 55 : void php_http_message_object_prepend(zval *this_ptr, zval *prepend, zend_bool top TSRMLS_DC)
724 : {
725 : zval m;
726 55 : php_http_message_t *save_parent_msg = NULL;
727 55 : php_http_message_object_t *save_parent_obj = NULL, *obj = zend_object_store_get_object(this_ptr TSRMLS_CC);
728 55 : php_http_message_object_t *prepend_obj = zend_object_store_get_object(prepend TSRMLS_CC);
729 :
730 55 : INIT_PZVAL(&m);
731 55 : m.type = IS_OBJECT;
732 :
733 55 : if (!top) {
734 0 : save_parent_obj = obj->parent;
735 0 : save_parent_msg = obj->message->parent;
736 : } else {
737 : /* iterate to the most parent object */
738 111 : while (obj->parent) {
739 1 : obj = obj->parent;
740 : }
741 : }
742 :
743 : /* prepend */
744 55 : obj->parent = prepend_obj;
745 55 : obj->message->parent = prepend_obj->message;
746 :
747 : /* add ref */
748 55 : zend_objects_store_add_ref(prepend TSRMLS_CC);
749 :
750 55 : if (!top) {
751 0 : prepend_obj->parent = save_parent_obj;
752 0 : prepend_obj->message->parent = save_parent_msg;
753 : }
754 55 : }
755 :
756 19 : STATUS php_http_message_object_set_body(php_http_message_object_t *msg_obj, zval *zbody TSRMLS_DC)
757 : {
758 19 : zval *tmp = NULL;
759 : php_stream *s;
760 : zend_object_value ov;
761 : php_http_message_body_t *body;
762 : php_http_message_body_object_t *body_obj;
763 :
764 19 : switch (Z_TYPE_P(zbody)) {
765 : case IS_RESOURCE:
766 1 : php_stream_from_zval_no_verify(s, &zbody);
767 1 : if (!s) {
768 0 : php_http_throw(unexpected_val, "The stream is not a valid resource", NULL);
769 0 : return FAILURE;
770 : }
771 :
772 : is_resource:
773 :
774 2 : body = php_http_message_body_init(NULL, s TSRMLS_CC);
775 2 : if (SUCCESS != php_http_new(&ov, php_http_message_body_class_entry, (php_http_new_t) php_http_message_body_object_new_ex, NULL, body, NULL TSRMLS_CC)) {
776 0 : php_http_message_body_free(&body);
777 0 : return FAILURE;
778 : }
779 2 : MAKE_STD_ZVAL(tmp);
780 2 : ZVAL_OBJVAL(tmp, ov, 0);
781 2 : zbody = tmp;
782 2 : break;
783 :
784 : case IS_OBJECT:
785 17 : if (instanceof_function(Z_OBJCE_P(zbody), php_http_message_body_class_entry TSRMLS_CC)) {
786 17 : Z_OBJ_ADDREF_P(zbody);
787 17 : break;
788 : }
789 : /* no break */
790 :
791 : default:
792 1 : tmp = php_http_ztyp(IS_STRING, zbody);
793 1 : s = php_stream_temp_new();
794 1 : php_stream_write(s, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
795 1 : zval_ptr_dtor(&tmp);
796 1 : tmp = NULL;
797 1 : goto is_resource;
798 :
799 : }
800 :
801 19 : body_obj = zend_object_store_get_object(zbody TSRMLS_CC);
802 19 : if (!body_obj->body) {
803 3 : body_obj->body = php_http_message_body_init(NULL, NULL TSRMLS_CC);
804 : }
805 19 : if (msg_obj->body) {
806 4 : zend_objects_store_del_ref_by_handle(msg_obj->body->zv.handle TSRMLS_CC);
807 : }
808 19 : if (msg_obj->message) {
809 19 : php_http_message_body_free(&msg_obj->message->body);
810 19 : msg_obj->message->body = php_http_message_body_init(&body_obj->body, NULL TSRMLS_CC);
811 : } else {
812 0 : msg_obj->message = php_http_message_init(NULL, 0, php_http_message_body_init(&body_obj->body, NULL TSRMLS_CC) TSRMLS_CC);
813 : }
814 19 : msg_obj->body = body_obj;
815 :
816 19 : if (tmp) {
817 2 : FREE_ZVAL(tmp);
818 : }
819 19 : return SUCCESS;
820 : }
821 :
822 18 : STATUS php_http_message_object_init_body_object(php_http_message_object_t *obj)
823 : {
824 : TSRMLS_FETCH_FROM_CTX(obj->message->ts);
825 :
826 18 : php_http_message_body_addref(obj->message->body);
827 18 : return php_http_new(NULL, php_http_message_body_class_entry, (php_http_new_t) php_http_message_body_object_new_ex, NULL, obj->message->body, (void *) &obj->body TSRMLS_CC);
828 : }
829 :
830 149 : zend_object_value php_http_message_object_new(zend_class_entry *ce TSRMLS_DC)
831 : {
832 149 : return php_http_message_object_new_ex(ce, NULL, NULL TSRMLS_CC);
833 : }
834 :
835 339 : zend_object_value php_http_message_object_new_ex(zend_class_entry *ce, php_http_message_t *msg, php_http_message_object_t **ptr TSRMLS_DC)
836 : {
837 : php_http_message_object_t *o;
838 :
839 339 : o = ecalloc(1, sizeof(php_http_message_object_t));
840 339 : zend_object_std_init((zend_object *) o, ce TSRMLS_CC);
841 339 : object_properties_init((zend_object *) o, ce);
842 :
843 339 : if (ptr) {
844 80 : *ptr = o;
845 : }
846 :
847 339 : if (msg) {
848 190 : o->message = msg;
849 190 : if (msg->parent) {
850 17 : php_http_message_object_new_ex(ce, msg->parent, &o->parent TSRMLS_CC);
851 : }
852 190 : php_http_message_body_object_new_ex(php_http_message_body_class_entry, php_http_message_body_init(&msg->body, NULL TSRMLS_CC), &o->body TSRMLS_CC);
853 : }
854 :
855 339 : o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_http_message_object_free, NULL TSRMLS_CC);
856 339 : o->zv.handlers = &php_http_message_object_handlers;
857 :
858 339 : return o->zv;
859 : }
860 :
861 3 : zend_object_value php_http_message_object_clone(zval *this_ptr TSRMLS_DC)
862 : {
863 : zend_object_value new_ov;
864 3 : php_http_message_object_t *new_obj = NULL;
865 3 : php_http_message_object_t *old_obj = zend_object_store_get_object(this_ptr TSRMLS_CC);
866 :
867 3 : new_ov = php_http_message_object_new_ex(old_obj->zo.ce, php_http_message_copy(old_obj->message, NULL), &new_obj TSRMLS_CC);
868 3 : zend_objects_clone_members(&new_obj->zo, new_ov, &old_obj->zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
869 :
870 3 : return new_ov;
871 : }
872 :
873 339 : void php_http_message_object_free(void *object TSRMLS_DC)
874 : {
875 339 : php_http_message_object_t *o = (php_http_message_object_t *) object;
876 :
877 339 : if (o->iterator) {
878 0 : zval_ptr_dtor(&o->iterator);
879 0 : o->iterator = NULL;
880 : }
881 339 : if (o->message) {
882 : /* do NOT free recursivly */
883 338 : php_http_message_dtor(o->message);
884 338 : efree(o->message);
885 338 : o->message = NULL;
886 : }
887 339 : if (o->parent) {
888 87 : zend_objects_store_del_ref_by_handle(o->parent->zv.handle TSRMLS_CC);
889 87 : o->parent = NULL;
890 : }
891 339 : if (o->body) {
892 222 : zend_objects_store_del_ref_by_handle(o->body->zv.handle TSRMLS_CC);
893 222 : o->body = NULL;
894 : }
895 339 : zend_object_std_dtor((zend_object *) o TSRMLS_CC);
896 339 : efree(o);
897 339 : }
898 :
899 534 : static zval *php_http_message_object_read_prop(zval *object, zval *member, int type PHP_HTTP_ZEND_LITERAL_DC TSRMLS_DC)
900 : {
901 534 : php_http_message_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
902 : php_http_message_object_prophandler_t *handler;
903 534 : zval *return_value, *copy = php_http_ztyp(IS_STRING, member);
904 :
905 534 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
906 :
907 534 : if (SUCCESS == php_http_message_object_get_prophandler(Z_STRVAL_P(copy), Z_STRLEN_P(copy), &handler)) {
908 204 : ALLOC_ZVAL(return_value);
909 204 : Z_SET_REFCOUNT_P(return_value, 0);
910 204 : Z_UNSET_ISREF_P(return_value);
911 :
912 204 : if (type == BP_VAR_R) {
913 196 : handler->read(obj, return_value TSRMLS_CC);
914 : } else {
915 8 : php_property_proxy_t *proxy = php_property_proxy_init(object, Z_STRVAL_P(copy), Z_STRLEN_P(copy) TSRMLS_CC);
916 8 : RETVAL_OBJVAL(php_property_proxy_object_new_ex(php_property_proxy_get_class_entry(), proxy, NULL TSRMLS_CC), 0);
917 : }
918 : } else {
919 330 : return_value = zend_get_std_object_handlers()->read_property(object, member, type PHP_HTTP_ZEND_LITERAL_CC TSRMLS_CC);
920 : }
921 :
922 534 : zval_ptr_dtor(©);
923 :
924 534 : return return_value;
925 : }
926 :
927 183 : static void php_http_message_object_write_prop(zval *object, zval *member, zval *value PHP_HTTP_ZEND_LITERAL_DC TSRMLS_DC)
928 : {
929 183 : php_http_message_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
930 : php_http_message_object_prophandler_t *handler;
931 183 : zval *copy = php_http_ztyp(IS_STRING, member);
932 :
933 183 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
934 :
935 183 : if (SUCCESS == php_http_message_object_get_prophandler(Z_STRVAL_P(copy), Z_STRLEN_P(copy), &handler)) {
936 20 : handler->write(obj, value TSRMLS_CC);
937 : } else {
938 163 : zend_get_std_object_handlers()->write_property(object, member, value PHP_HTTP_ZEND_LITERAL_CC TSRMLS_CC);
939 : }
940 :
941 183 : zval_ptr_dtor(©);
942 183 : }
943 :
944 4 : static HashTable *php_http_message_object_get_props(zval *object TSRMLS_DC)
945 : {
946 : zval *headers;
947 4 : php_http_message_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
948 4 : HashTable *props = zend_get_std_object_handlers()->get_properties(object TSRMLS_CC);
949 : zval array, *parent, *body;
950 4 : char *ver_str, *url_str = NULL;
951 4 : size_t ver_len, url_len = 0;
952 :
953 4 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
954 4 : INIT_PZVAL_ARRAY(&array, props);
955 :
956 : #define ASSOC_PROP(ptype, n, val) \
957 : do { \
958 : zend_property_info *pi; \
959 : if (SUCCESS == zend_hash_find(&obj->zo.ce->properties_info, n, sizeof(n), (void *) &pi)) { \
960 : add_assoc_ ##ptype## _ex(&array, pi->name, pi->name_length + 1, val); \
961 : } \
962 : } while(0) \
963 :
964 : #define ASSOC_STRING(name, val) ASSOC_STRINGL(name, val, strlen(val))
965 : #define ASSOC_STRINGL(name, val, len) ASSOC_STRINGL_EX(name, val, len, 1)
966 : #define ASSOC_STRINGL_EX(n, val, len, cpy) \
967 : do { \
968 : zend_property_info *pi; \
969 : if (SUCCESS == zend_hash_find(&obj->zo.ce->properties_info, n, sizeof(n), (void *) &pi)) { \
970 : add_assoc_stringl_ex(&array, pi->name, pi->name_length + 1, val, len, cpy); \
971 : } \
972 : } while(0)
973 :
974 4 : ASSOC_PROP(long, "type", obj->message->type);
975 4 : ver_len = spprintf(&ver_str, 0, "%u.%u", obj->message->http.version.major, obj->message->http.version.minor);
976 4 : ASSOC_STRINGL_EX("httpVersion", ver_str, ver_len, 0);
977 :
978 4 : switch (obj->message->type) {
979 : case PHP_HTTP_REQUEST:
980 3 : ASSOC_PROP(long, "responseCode", 0);
981 3 : ASSOC_STRINGL("responseStatus", "", 0);
982 3 : ASSOC_STRING("requestMethod", STR_PTR(obj->message->http.info.request.method));
983 3 : if (obj->message->http.info.request.url) {
984 2 : php_http_url_to_string(obj->message->http.info.request.url, &url_str, &url_len, 0);
985 2 : ASSOC_STRINGL_EX("requestUrl", url_str, url_len, 0);
986 : } else {
987 1 : ASSOC_STRINGL("requestUrl", "", 0);
988 : }
989 :
990 3 : break;
991 :
992 : case PHP_HTTP_RESPONSE:
993 0 : ASSOC_PROP(long, "responseCode", obj->message->http.info.response.code);
994 0 : ASSOC_STRING("responseStatus", STR_PTR(obj->message->http.info.response.status));
995 0 : ASSOC_STRINGL("requestMethod", "", 0);
996 0 : ASSOC_STRINGL("requestUrl", "", 0);
997 0 : break;
998 :
999 : case PHP_HTTP_NONE:
1000 : default:
1001 1 : ASSOC_PROP(long, "responseCode", 0);
1002 1 : ASSOC_STRINGL("responseStatus", "", 0);
1003 1 : ASSOC_STRINGL("requestMethod", "", 0);
1004 1 : ASSOC_STRINGL("requestUrl", "", 0);
1005 1 : break;
1006 : }
1007 :
1008 4 : MAKE_STD_ZVAL(headers);
1009 4 : array_init(headers);
1010 4 : zend_hash_copy(Z_ARRVAL_P(headers), &obj->message->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
1011 4 : ASSOC_PROP(zval, "headers", headers);
1012 :
1013 4 : MAKE_STD_ZVAL(body);
1014 4 : if (obj->body) {
1015 1 : ZVAL_OBJVAL(body, obj->body->zv, 1);
1016 : } else {
1017 3 : ZVAL_NULL(body);
1018 : }
1019 4 : ASSOC_PROP(zval, "body", body);
1020 :
1021 4 : MAKE_STD_ZVAL(parent);
1022 4 : if (obj->message->parent) {
1023 0 : ZVAL_OBJVAL(parent, obj->parent->zv, 1);
1024 : } else {
1025 4 : ZVAL_NULL(parent);
1026 : }
1027 4 : ASSOC_PROP(zval, "parentMessage", parent);
1028 :
1029 4 : return props;
1030 : }
1031 :
1032 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage___construct, 0, 0, 0)
1033 : ZEND_ARG_INFO(0, message)
1034 : ZEND_ARG_INFO(0, greedy)
1035 : ZEND_END_ARG_INFO();
1036 57 : static PHP_METHOD(HttpMessage, __construct)
1037 : {
1038 57 : zend_bool greedy = 1;
1039 57 : zval *zmessage = NULL;
1040 57 : php_http_message_t *msg = NULL;
1041 57 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1042 : zend_error_handling zeh;
1043 :
1044 57 : php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!b", &zmessage, &greedy), invalid_arg, return);
1045 :
1046 57 : zend_replace_error_handling(EH_THROW, php_http_exception_bad_message_class_entry, &zeh TSRMLS_CC);
1047 65 : if (zmessage && Z_TYPE_P(zmessage) == IS_RESOURCE) {
1048 : php_stream *s;
1049 : php_http_message_parser_t p;
1050 : zend_error_handling zeh;
1051 :
1052 8 : zend_replace_error_handling(EH_THROW, php_http_exception_unexpected_val_class_entry, &zeh TSRMLS_CC);
1053 8 : php_stream_from_zval(s, &zmessage);
1054 8 : zend_restore_error_handling(&zeh TSRMLS_CC);
1055 :
1056 8 : if (s && php_http_message_parser_init(&p TSRMLS_CC)) {
1057 8 : unsigned flags = (greedy ? PHP_HTTP_MESSAGE_PARSER_GREEDY : 0);
1058 : php_http_buffer_t buf;
1059 :
1060 8 : php_http_buffer_init_ex(&buf, 0x1000, PHP_HTTP_BUFFER_INIT_PREALLOC);
1061 8 : if (PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE == php_http_message_parser_parse_stream(&p, &buf, s, flags, &msg)) {
1062 0 : if (!EG(exception)) {
1063 0 : php_http_throw(bad_message, "Could not parse message from stream", NULL);
1064 : }
1065 : }
1066 8 : php_http_buffer_dtor(&buf);
1067 8 : php_http_message_parser_dtor(&p);
1068 : }
1069 :
1070 8 : if (!msg && !EG(exception)) {
1071 1 : php_http_throw(bad_message, "Empty message received from stream", NULL);
1072 : }
1073 49 : } else if (zmessage) {
1074 36 : zmessage = php_http_ztyp(IS_STRING, zmessage);
1075 36 : msg = php_http_message_parse(NULL, Z_STRVAL_P(zmessage), Z_STRLEN_P(zmessage), greedy TSRMLS_CC);
1076 :
1077 36 : if (!msg && !EG(exception)) {
1078 0 : php_http_throw(bad_message, "Could not parse message: %.*s", MIN(25, Z_STRLEN_P(zmessage)), Z_STRVAL_P(zmessage));
1079 : }
1080 36 : zval_ptr_dtor(&zmessage);
1081 : }
1082 :
1083 57 : if (msg) {
1084 37 : php_http_message_dtor(obj->message);
1085 37 : obj->message = msg;
1086 37 : if (obj->message->parent) {
1087 14 : php_http_message_object_new_ex(Z_OBJCE_P(getThis()), obj->message->parent, &obj->parent TSRMLS_CC);
1088 : }
1089 : }
1090 57 : zend_restore_error_handling(&zeh TSRMLS_CC);
1091 57 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1092 : }
1093 :
1094 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getBody, 0, 0, 0)
1095 : ZEND_END_ARG_INFO();
1096 131097 : static PHP_METHOD(HttpMessage, getBody)
1097 : {
1098 : php_http_message_object_t *obj;
1099 :
1100 262194 : php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return);
1101 :
1102 131097 : obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1103 :
1104 131097 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1105 :
1106 131097 : if (!obj->body) {
1107 15 : php_http_message_object_init_body_object(obj);
1108 :
1109 : }
1110 131097 : if (obj->body) {
1111 131097 : RETVAL_OBJVAL(obj->body->zv, 1);
1112 : }
1113 : }
1114 :
1115 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setBody, 0, 0, 1)
1116 : ZEND_ARG_OBJ_INFO(0, body, http\\Message\\Body, 0)
1117 : ZEND_END_ARG_INFO();
1118 15 : static PHP_METHOD(HttpMessage, setBody)
1119 : {
1120 : zval *zbody;
1121 :
1122 15 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zbody, php_http_message_body_class_entry)) {
1123 15 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1124 :
1125 15 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1126 15 : php_http_message_object_prophandler_set_body(obj, zbody TSRMLS_CC);
1127 : }
1128 15 : RETVAL_ZVAL(getThis(), 1, 0);
1129 15 : }
1130 :
1131 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_addBody, 0, 0, 1)
1132 : ZEND_ARG_OBJ_INFO(0, body, http\\Message\\Body, 0)
1133 : ZEND_END_ARG_INFO();
1134 2 : static PHP_METHOD(HttpMessage, addBody)
1135 : {
1136 : zval *new_body;
1137 :
1138 2 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &new_body, php_http_message_body_class_entry)) {
1139 2 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1140 2 : php_http_message_body_object_t *new_obj = zend_object_store_get_object(new_body TSRMLS_CC);
1141 :
1142 2 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1143 2 : php_http_message_body_to_callback(new_obj->body, (php_http_pass_callback_t) php_http_message_body_append, obj->message->body, 0, 0);
1144 : }
1145 2 : RETVAL_ZVAL(getThis(), 1, 0);
1146 2 : }
1147 :
1148 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getHeader, 0, 0, 1)
1149 : ZEND_ARG_INFO(0, header)
1150 : ZEND_ARG_INFO(0, into_class)
1151 : ZEND_END_ARG_INFO();
1152 5 : static PHP_METHOD(HttpMessage, getHeader)
1153 : {
1154 : char *header_str;
1155 : int header_len;
1156 5 : zend_class_entry *header_ce = NULL;
1157 :
1158 5 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|C!", &header_str, &header_len, &header_ce)) {
1159 5 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1160 : zval *header;
1161 :
1162 5 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1163 :
1164 5 : if ((header = php_http_message_header(obj->message, header_str, header_len, 0))) {
1165 2 : if (!header_ce) {
1166 4 : RETURN_ZVAL(header, 1, 1);
1167 0 : } else if (instanceof_function(header_ce, php_http_header_class_entry TSRMLS_CC)) {
1168 : php_http_object_method_t cb;
1169 : zval *header_name, **argv[2];
1170 :
1171 0 : MAKE_STD_ZVAL(header_name);
1172 0 : ZVAL_STRINGL(header_name, header_str, header_len, 1);
1173 :
1174 0 : argv[0] = &header_name;
1175 0 : argv[1] = &header;
1176 :
1177 0 : object_init_ex(return_value, header_ce);
1178 0 : php_http_object_method_init(&cb, return_value, ZEND_STRL("__construct") TSRMLS_CC);
1179 0 : php_http_object_method_call(&cb, return_value, NULL, 2, argv TSRMLS_CC);
1180 0 : php_http_object_method_dtor(&cb);
1181 :
1182 0 : zval_ptr_dtor(&header_name);
1183 0 : zval_ptr_dtor(&header);
1184 :
1185 0 : return;
1186 : } else {
1187 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class '%s' is not as descendant of http\\Header", header_ce->name);
1188 : }
1189 : }
1190 : }
1191 3 : RETURN_FALSE;
1192 : }
1193 :
1194 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getHeaders, 0, 0, 0)
1195 : ZEND_END_ARG_INFO();
1196 16 : static PHP_METHOD(HttpMessage, getHeaders)
1197 : {
1198 16 : if (SUCCESS == zend_parse_parameters_none()) {
1199 16 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1200 :
1201 16 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1202 :
1203 16 : array_init(return_value);
1204 16 : array_copy(&obj->message->hdrs, Z_ARRVAL_P(return_value));
1205 : }
1206 16 : }
1207 :
1208 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setHeader, 0, 0, 1)
1209 : ZEND_ARG_INFO(0, header)
1210 : ZEND_ARG_INFO(0, value)
1211 : ZEND_END_ARG_INFO();
1212 6 : static PHP_METHOD(HttpMessage, setHeader)
1213 : {
1214 6 : zval *zvalue = NULL;
1215 : char *name_str;
1216 : int name_len;
1217 :
1218 6 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z!", &name_str, &name_len, &zvalue)) {
1219 6 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1220 6 : char *name = php_http_pretty_key(estrndup(name_str, name_len), name_len, 1, 1);
1221 :
1222 6 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1223 :
1224 6 : if (!zvalue) {
1225 0 : zend_symtable_del(&obj->message->hdrs, name, name_len + 1);
1226 : } else {
1227 6 : Z_ADDREF_P(zvalue);
1228 6 : zend_symtable_update(&obj->message->hdrs, name, name_len + 1, &zvalue, sizeof(void *), NULL);
1229 : }
1230 6 : efree(name);
1231 : }
1232 6 : RETVAL_ZVAL(getThis(), 1, 0);
1233 6 : }
1234 :
1235 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setHeaders, 0, 0, 1)
1236 : ZEND_ARG_ARRAY_INFO(0, headers, 1)
1237 : ZEND_END_ARG_INFO();
1238 1 : static PHP_METHOD(HttpMessage, setHeaders)
1239 : {
1240 1 : zval *new_headers = NULL;
1241 :
1242 1 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!", &new_headers)) {
1243 1 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1244 :
1245 1 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1246 :
1247 1 : zend_hash_clean(&obj->message->hdrs);
1248 1 : if (new_headers) {
1249 1 : array_join(Z_ARRVAL_P(new_headers), &obj->message->hdrs, 0, ARRAY_JOIN_PRETTIFY|ARRAY_JOIN_STRONLY);
1250 : }
1251 : }
1252 1 : RETVAL_ZVAL(getThis(), 1, 0);
1253 1 : }
1254 :
1255 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_addHeader, 0, 0, 2)
1256 : ZEND_ARG_INFO(0, header)
1257 : ZEND_ARG_INFO(0, value)
1258 : ZEND_END_ARG_INFO();
1259 14 : static PHP_METHOD(HttpMessage, addHeader)
1260 : {
1261 : zval *zvalue;
1262 : char *name_str;
1263 : int name_len;
1264 :
1265 14 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name_str, &name_len, &zvalue)) {
1266 14 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1267 14 : char *name = php_http_pretty_key(estrndup(name_str, name_len), name_len, 1, 1);
1268 : zval *header;
1269 :
1270 14 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1271 :
1272 14 : Z_ADDREF_P(zvalue);
1273 14 : if ((header = php_http_message_header(obj->message, name, name_len, 0))) {
1274 3 : convert_to_array(header);
1275 3 : zend_hash_next_index_insert(Z_ARRVAL_P(header), &zvalue, sizeof(void *), NULL);
1276 3 : zval_ptr_dtor(&header);
1277 : } else {
1278 11 : zend_symtable_update(&obj->message->hdrs, name, name_len + 1, &zvalue, sizeof(void *), NULL);
1279 : }
1280 14 : efree(name);
1281 : }
1282 14 : RETVAL_ZVAL(getThis(), 1, 0);
1283 14 : }
1284 :
1285 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_addHeaders, 0, 0, 1)
1286 : ZEND_ARG_ARRAY_INFO(0, headers, 0)
1287 : ZEND_ARG_INFO(0, append)
1288 : ZEND_END_ARG_INFO();
1289 2 : static PHP_METHOD(HttpMessage, addHeaders)
1290 : {
1291 : zval *new_headers;
1292 2 : zend_bool append = 0;
1293 :
1294 2 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &new_headers, &append)) {
1295 2 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1296 :
1297 2 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1298 :
1299 2 : array_join(Z_ARRVAL_P(new_headers), &obj->message->hdrs, append, ARRAY_JOIN_STRONLY|ARRAY_JOIN_PRETTIFY);
1300 : }
1301 2 : RETVAL_ZVAL(getThis(), 1, 0);
1302 2 : }
1303 :
1304 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getType, 0, 0, 0)
1305 : ZEND_END_ARG_INFO();
1306 12 : static PHP_METHOD(HttpMessage, getType)
1307 : {
1308 12 : if (SUCCESS == zend_parse_parameters_none()) {
1309 12 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1310 :
1311 12 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1312 :
1313 12 : RETURN_LONG(obj->message->type);
1314 : }
1315 : }
1316 :
1317 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setType, 0, 0, 1)
1318 : ZEND_ARG_INFO(0, type)
1319 : ZEND_END_ARG_INFO();
1320 2 : static PHP_METHOD(HttpMessage, setType)
1321 : {
1322 : long type;
1323 :
1324 2 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &type)) {
1325 2 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1326 :
1327 2 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1328 :
1329 2 : php_http_message_set_type(obj->message, type);
1330 : }
1331 2 : RETVAL_ZVAL(getThis(), 1, 0);
1332 2 : }
1333 :
1334 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getInfo, 0, 0, 0)
1335 : ZEND_END_ARG_INFO();
1336 3 : static PHP_METHOD(HttpMessage, getInfo)
1337 : {
1338 3 : if (SUCCESS == zend_parse_parameters_none()) {
1339 3 : char *tmp = NULL;
1340 3 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1341 :
1342 3 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1343 :
1344 3 : switch (obj->message->type) {
1345 : case PHP_HTTP_REQUEST:
1346 1 : Z_STRLEN_P(return_value) = spprintf(&Z_STRVAL_P(return_value), 0, PHP_HTTP_INFO_REQUEST_FMT_ARGS(&obj->message->http, tmp, ""));
1347 1 : PTR_FREE(tmp);
1348 1 : break;
1349 : case PHP_HTTP_RESPONSE:
1350 2 : Z_STRLEN_P(return_value) = spprintf(&Z_STRVAL_P(return_value), 0, PHP_HTTP_INFO_RESPONSE_FMT_ARGS(&obj->message->http, tmp, ""));
1351 2 : PTR_FREE(tmp);
1352 2 : break;
1353 : default:
1354 0 : RETURN_NULL();
1355 : break;
1356 : }
1357 3 : Z_TYPE_P(return_value) = IS_STRING;
1358 3 : return;
1359 : }
1360 : }
1361 :
1362 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setInfo, 0, 0, 1)
1363 : ZEND_ARG_INFO(0, http_info)
1364 : ZEND_END_ARG_INFO();
1365 1 : static PHP_METHOD(HttpMessage, setInfo)
1366 : {
1367 : char *str;
1368 : int len;
1369 : php_http_message_object_t *obj;
1370 : php_http_info_t inf;
1371 :
1372 1 : php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len), invalid_arg, return);
1373 :
1374 1 : obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1375 1 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1376 :
1377 1 : if (!php_http_info_parse(&inf, str TSRMLS_CC)) {
1378 0 : php_http_throw(bad_header, "Could not parse message info '%s'", str);
1379 0 : return;
1380 : }
1381 :
1382 1 : php_http_message_set_info(obj->message, &inf);
1383 1 : php_http_info_dtor(&inf);
1384 :
1385 1 : RETVAL_ZVAL(getThis(), 1, 0);
1386 : }
1387 :
1388 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getHttpVersion, 0, 0, 0)
1389 : ZEND_END_ARG_INFO();
1390 14 : static PHP_METHOD(HttpMessage, getHttpVersion)
1391 : {
1392 14 : if (SUCCESS == zend_parse_parameters_none()) {
1393 : char *str;
1394 : size_t len;
1395 14 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1396 :
1397 14 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1398 :
1399 14 : php_http_version_to_string(&obj->message->http.version, &str, &len, NULL, NULL TSRMLS_CC);
1400 14 : RETURN_STRINGL(str, len, 0);
1401 : }
1402 : }
1403 :
1404 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setHttpVersion, 0, 0, 1)
1405 : ZEND_ARG_INFO(0, http_version)
1406 : ZEND_END_ARG_INFO();
1407 3 : static PHP_METHOD(HttpMessage, setHttpVersion)
1408 : {
1409 : char *v_str;
1410 : int v_len;
1411 : php_http_version_t version;
1412 : php_http_message_object_t *obj;
1413 :
1414 3 : php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &v_str, &v_len), invalid_arg, return);
1415 :
1416 3 : obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1417 3 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1418 :
1419 3 : php_http_expect(php_http_version_parse(&version, v_str TSRMLS_CC), unexpected_val, return);
1420 :
1421 2 : obj->message->http.version = version;
1422 :
1423 2 : RETVAL_ZVAL(getThis(), 1, 0);
1424 : }
1425 :
1426 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getResponseCode, 0, 0, 0)
1427 : ZEND_END_ARG_INFO();
1428 13 : static PHP_METHOD(HttpMessage, getResponseCode)
1429 : {
1430 13 : if (SUCCESS == zend_parse_parameters_none()) {
1431 13 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1432 :
1433 13 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1434 :
1435 13 : if (obj->message->type != PHP_HTTP_RESPONSE) {
1436 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "http\\Message is not if type response");
1437 0 : RETURN_FALSE;
1438 : }
1439 :
1440 13 : RETURN_LONG(obj->message->http.info.response.code);
1441 : }
1442 : }
1443 :
1444 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setResponseCode, 0, 0, 1)
1445 : ZEND_ARG_INFO(0, response_code)
1446 : ZEND_ARG_INFO(0, strict)
1447 : ZEND_END_ARG_INFO();
1448 2 : static PHP_METHOD(HttpMessage, setResponseCode)
1449 : {
1450 : long code;
1451 2 : zend_bool strict = 1;
1452 : php_http_message_object_t *obj;
1453 :
1454 2 : php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|b", &code, &strict), invalid_arg, return);
1455 :
1456 2 : obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1457 :
1458 2 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1459 :
1460 2 : if (obj->message->type != PHP_HTTP_RESPONSE) {
1461 0 : php_http_throw(bad_method_call, "http\\Message is not of type response", NULL);
1462 0 : return;
1463 : }
1464 :
1465 2 : if (strict && (code < 100 || code > 599)) {
1466 0 : php_http_throw(invalid_arg, "Invalid response code (100-599): %ld", code);
1467 0 : return;
1468 : }
1469 :
1470 2 : obj->message->http.info.response.code = code;
1471 2 : PTR_SET(obj->message->http.info.response.status, estrdup(php_http_env_get_response_status_for_code(code)));
1472 :
1473 2 : RETVAL_ZVAL(getThis(), 1, 0);
1474 : }
1475 :
1476 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getResponseStatus, 0, 0, 0)
1477 : ZEND_END_ARG_INFO();
1478 12 : static PHP_METHOD(HttpMessage, getResponseStatus)
1479 : {
1480 12 : if (SUCCESS == zend_parse_parameters_none()) {
1481 12 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1482 :
1483 12 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1484 :
1485 12 : if (obj->message->type != PHP_HTTP_RESPONSE) {
1486 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "http\\Message is not of type response");
1487 : }
1488 :
1489 12 : if (obj->message->http.info.response.status) {
1490 12 : RETURN_STRING(obj->message->http.info.response.status, 1);
1491 : } else {
1492 0 : RETURN_EMPTY_STRING();
1493 : }
1494 : }
1495 : }
1496 :
1497 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setResponseStatus, 0, 0, 1)
1498 : ZEND_ARG_INFO(0, response_status)
1499 : ZEND_END_ARG_INFO();
1500 1 : static PHP_METHOD(HttpMessage, setResponseStatus)
1501 : {
1502 : char *status;
1503 : int status_len;
1504 : php_http_message_object_t *obj;
1505 :
1506 2 : php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &status, &status_len), invalid_arg, return);
1507 :
1508 1 : obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1509 :
1510 1 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1511 :
1512 1 : if (obj->message->type != PHP_HTTP_RESPONSE) {
1513 0 : php_http_throw(bad_method_call, "http\\Message is not of type response", NULL);
1514 : }
1515 :
1516 1 : PTR_SET(obj->message->http.info.response.status, estrndup(status, status_len));
1517 1 : RETVAL_ZVAL(getThis(), 1, 0);
1518 : }
1519 :
1520 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getRequestMethod, 0, 0, 0)
1521 : ZEND_END_ARG_INFO();
1522 3 : static PHP_METHOD(HttpMessage, getRequestMethod)
1523 : {
1524 3 : if (SUCCESS == zend_parse_parameters_none()) {
1525 3 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1526 :
1527 3 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1528 :
1529 3 : if (obj->message->type != PHP_HTTP_REQUEST) {
1530 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "http\\Message is not of type request");
1531 0 : RETURN_FALSE;
1532 : }
1533 :
1534 3 : if (obj->message->http.info.request.method) {
1535 3 : RETURN_STRING(obj->message->http.info.request.method, 1);
1536 : } else {
1537 0 : RETURN_EMPTY_STRING();
1538 : }
1539 : }
1540 : }
1541 :
1542 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setRequestMethod, 0, 0, 1)
1543 : ZEND_ARG_INFO(0, request_method)
1544 : ZEND_END_ARG_INFO();
1545 2 : static PHP_METHOD(HttpMessage, setRequestMethod)
1546 : {
1547 : char *method;
1548 : int method_len;
1549 : php_http_message_object_t *obj;
1550 :
1551 2 : php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &method, &method_len), invalid_arg, return);
1552 :
1553 2 : obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1554 :
1555 2 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1556 :
1557 2 : if (obj->message->type != PHP_HTTP_REQUEST) {
1558 0 : php_http_throw(bad_method_call, "http\\Message is not of type request", NULL);
1559 0 : return;
1560 : }
1561 :
1562 2 : if (method_len < 1) {
1563 0 : php_http_throw(invalid_arg, "Cannot set http\\Message's request method to an empty string", NULL);
1564 0 : return;
1565 : }
1566 :
1567 2 : PTR_SET(obj->message->http.info.request.method, estrndup(method, method_len));
1568 2 : RETVAL_ZVAL(getThis(), 1, 0);
1569 : }
1570 :
1571 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getRequestUrl, 0, 0, 0)
1572 : ZEND_END_ARG_INFO();
1573 3 : static PHP_METHOD(HttpMessage, getRequestUrl)
1574 : {
1575 3 : if (SUCCESS == zend_parse_parameters_none()) {
1576 3 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1577 :
1578 3 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1579 :
1580 3 : if (obj->message->type != PHP_HTTP_REQUEST) {
1581 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "http\\Message is not of type request");
1582 0 : RETURN_FALSE;
1583 : }
1584 :
1585 3 : if (obj->message->http.info.request.url) {
1586 : char *url_str;
1587 : size_t url_len;
1588 :
1589 3 : php_http_url_to_string(obj->message->http.info.request.url, &url_str, &url_len, 0);
1590 3 : RETURN_STRINGL(url_str, url_len, 0);
1591 : } else {
1592 0 : RETURN_EMPTY_STRING();
1593 : }
1594 : }
1595 : }
1596 :
1597 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_setRequestUrl, 0, 0, 1)
1598 : ZEND_ARG_INFO(0, url)
1599 : ZEND_END_ARG_INFO();
1600 4 : static PHP_METHOD(HttpMessage, setRequestUrl)
1601 : {
1602 : zval *zurl;
1603 : php_http_url_t *url;
1604 : php_http_message_object_t *obj;
1605 : zend_error_handling zeh;
1606 :
1607 4 : php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zurl), invalid_arg, return);
1608 :
1609 4 : obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1610 :
1611 4 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1612 :
1613 4 : if (obj->message->type != PHP_HTTP_REQUEST) {
1614 1 : php_http_throw(bad_method_call, "http\\Message is not of type request", NULL);
1615 1 : return;
1616 : }
1617 :
1618 3 : zend_replace_error_handling(EH_THROW, php_http_exception_bad_url_class_entry, &zeh TSRMLS_CC);
1619 3 : url = php_http_url_from_zval(zurl, ~0 TSRMLS_CC);
1620 3 : zend_restore_error_handling(&zeh TSRMLS_CC);
1621 :
1622 3 : if (php_http_url_is_empty(url)) {
1623 1 : php_http_url_free(&url);
1624 1 : php_http_throw(invalid_arg, "Cannot set http\\Message's request url to an empty string", NULL);
1625 : } else {
1626 2 : PTR_SET(obj->message->http.info.request.url, url);
1627 : }
1628 :
1629 3 : RETVAL_ZVAL(getThis(), 1, 0);
1630 : }
1631 :
1632 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_getParentMessage, 0, 0, 0)
1633 : ZEND_END_ARG_INFO();
1634 11 : static PHP_METHOD(HttpMessage, getParentMessage)
1635 : {
1636 : php_http_message_object_t *obj;
1637 :
1638 11 : php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return);
1639 :
1640 11 : obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1641 :
1642 11 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1643 :
1644 11 : if (!obj->message->parent) {
1645 1 : php_http_throw(unexpected_val, "http\\Message has not parent message", NULL);
1646 1 : return;
1647 : }
1648 :
1649 10 : RETVAL_OBJVAL(obj->parent->zv, 1);
1650 : }
1651 :
1652 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage___toString, 0, 0, 0)
1653 : ZEND_END_ARG_INFO();
1654 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_toString, 0, 0, 0)
1655 : ZEND_ARG_INFO(0, include_parent)
1656 : ZEND_END_ARG_INFO();
1657 77 : static PHP_METHOD(HttpMessage, toString)
1658 : {
1659 77 : zend_bool include_parent = 0;
1660 :
1661 77 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &include_parent)) {
1662 77 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1663 : char *string;
1664 : size_t length;
1665 :
1666 77 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1667 :
1668 77 : if (include_parent) {
1669 7 : php_http_message_serialize(obj->message, &string, &length);
1670 : } else {
1671 70 : php_http_message_to_string(obj->message, &string, &length);
1672 : }
1673 77 : if (string) {
1674 77 : RETURN_STRINGL(string, length, 0);
1675 : }
1676 : }
1677 0 : RETURN_EMPTY_STRING();
1678 : }
1679 :
1680 : #ifdef ZTS
1681 : static size_t write_to_stream(void *s, const char *str, size_t len)
1682 : {
1683 : TSRMLS_FETCH();
1684 : return php_stream_write(s, str, len);
1685 : }
1686 : #else
1687 : # define write_to_stream (php_http_pass_callback_t)_php_stream_write
1688 : #endif
1689 :
1690 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_toStream, 0, 0, 1)
1691 : ZEND_ARG_INFO(0, stream)
1692 : ZEND_END_ARG_INFO();
1693 2 : static PHP_METHOD(HttpMessage, toStream)
1694 : {
1695 : zval *zstream;
1696 :
1697 2 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zstream)) {
1698 2 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1699 : php_stream *s;
1700 :
1701 2 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1702 :
1703 2 : php_stream_from_zval(s, &zstream);
1704 2 : php_http_message_to_callback(obj->message, write_to_stream, s);
1705 : }
1706 : }
1707 :
1708 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_toCallback, 0, 0, 1)
1709 : ZEND_ARG_INFO(0, callback)
1710 : ZEND_END_ARG_INFO();
1711 1 : static PHP_METHOD(HttpMessage, toCallback)
1712 : {
1713 : php_http_pass_fcall_arg_t fcd;
1714 :
1715 1 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", &fcd.fci, &fcd.fcc)) {
1716 1 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1717 :
1718 1 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1719 :
1720 1 : fcd.fcz = getThis();
1721 1 : Z_ADDREF_P(fcd.fcz);
1722 : TSRMLS_SET_CTX(fcd.ts);
1723 :
1724 1 : php_http_message_to_callback(obj->message, php_http_pass_fcall_callback, &fcd);
1725 1 : zend_fcall_info_args_clear(&fcd.fci, 1);
1726 :
1727 1 : zval_ptr_dtor(&fcd.fcz);
1728 1 : RETURN_ZVAL(getThis(), 1, 0);
1729 : }
1730 : }
1731 :
1732 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_serialize, 0, 0, 0)
1733 : ZEND_END_ARG_INFO();
1734 5 : static PHP_METHOD(HttpMessage, serialize)
1735 : {
1736 5 : if (SUCCESS == zend_parse_parameters_none()) {
1737 5 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1738 : char *string;
1739 : size_t length;
1740 :
1741 5 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1742 :
1743 5 : php_http_message_serialize(obj->message, &string, &length);
1744 5 : RETURN_STRINGL(string, length, 0);
1745 : }
1746 0 : RETURN_EMPTY_STRING();
1747 : }
1748 :
1749 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_unserialize, 0, 0, 1)
1750 : ZEND_ARG_INFO(0, serialized)
1751 : ZEND_END_ARG_INFO();
1752 5 : static PHP_METHOD(HttpMessage, unserialize)
1753 : {
1754 : int length;
1755 : char *serialized;
1756 :
1757 5 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &length)) {
1758 5 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1759 : php_http_message_t *msg;
1760 :
1761 5 : if (obj->message) {
1762 0 : php_http_message_dtor(obj->message);
1763 0 : efree(obj->message);
1764 : }
1765 5 : if ((msg = php_http_message_parse(NULL, serialized, (size_t) length, 1 TSRMLS_CC))) {
1766 5 : obj->message = msg;
1767 : } else {
1768 0 : obj->message = php_http_message_init(NULL, 0, NULL TSRMLS_CC);
1769 0 : php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not unserialize http\\Message");
1770 : }
1771 : }
1772 5 : }
1773 :
1774 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_detach, 0, 0, 0)
1775 : ZEND_END_ARG_INFO();
1776 1 : static PHP_METHOD(HttpMessage, detach)
1777 : {
1778 : php_http_message_object_t *obj;
1779 :
1780 2 : php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return);
1781 :
1782 1 : obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1783 :
1784 1 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1785 :
1786 1 : RETVAL_OBJVAL(php_http_message_object_new_ex(obj->zo.ce, php_http_message_copy_ex(obj->message, NULL, 0), NULL TSRMLS_CC), 0);
1787 : }
1788 :
1789 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_prepend, 0, 0, 1)
1790 : ZEND_ARG_OBJ_INFO(0, message, http\\Message, 0)
1791 : ZEND_ARG_INFO(0, top)
1792 : ZEND_END_ARG_INFO();
1793 9 : static PHP_METHOD(HttpMessage, prepend)
1794 : {
1795 : zval *prepend;
1796 9 : zend_bool top = 1;
1797 : php_http_message_t *msg[2];
1798 : php_http_message_object_t *obj, *prepend_obj;
1799 :
1800 9 : php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &prepend, php_http_message_class_entry, &top), invalid_arg, return);
1801 :
1802 9 : obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1803 9 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1804 9 : prepend_obj = zend_object_store_get_object(prepend TSRMLS_CC);
1805 9 : PHP_HTTP_MESSAGE_OBJECT_INIT(prepend_obj);
1806 :
1807 : /* safety check */
1808 18 : for (msg[0] = obj->message; msg[0]; msg[0] = msg[0]->parent) {
1809 47 : for (msg[1] = prepend_obj->message; msg[1]; msg[1] = msg[1]->parent) {
1810 38 : if (msg[0] == msg[1]) {
1811 1 : php_http_throw(unexpected_val, "Cannot prepend a message located within the same message chain", NULL);
1812 1 : return;
1813 : }
1814 : }
1815 : }
1816 :
1817 8 : php_http_message_object_prepend(getThis(), prepend, top TSRMLS_CC);
1818 8 : RETURN_ZVAL(getThis(), 1, 0);
1819 : }
1820 :
1821 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_reverse, 0, 0, 0)
1822 : ZEND_END_ARG_INFO();
1823 2 : static PHP_METHOD(HttpMessage, reverse)
1824 : {
1825 4 : php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return);
1826 :
1827 2 : php_http_message_object_reverse(getThis(), return_value TSRMLS_CC);
1828 : }
1829 :
1830 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_isMultipart, 0, 0, 0)
1831 : ZEND_ARG_INFO(1, boundary)
1832 : ZEND_END_ARG_INFO();
1833 1 : static PHP_METHOD(HttpMessage, isMultipart)
1834 : {
1835 1 : zval *zboundary = NULL;
1836 :
1837 1 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &zboundary)) {
1838 1 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1839 1 : char *boundary = NULL;
1840 :
1841 1 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1842 :
1843 1 : RETVAL_BOOL(php_http_message_is_multipart(obj->message, zboundary ? &boundary : NULL));
1844 :
1845 1 : if (zboundary && boundary) {
1846 1 : zval_dtor(zboundary);
1847 1 : ZVAL_STRING(zboundary, boundary, 0);
1848 : }
1849 : }
1850 1 : }
1851 :
1852 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_splitMultipartBody, 0, 0, 0)
1853 : ZEND_END_ARG_INFO();
1854 1 : static PHP_METHOD(HttpMessage, splitMultipartBody)
1855 : {
1856 : php_http_message_object_t *obj;
1857 : php_http_message_t *msg;
1858 1 : char *boundary = NULL;
1859 :
1860 1 : php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return);
1861 :
1862 1 : obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1863 :
1864 1 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1865 :
1866 1 : if (!php_http_message_is_multipart(obj->message, &boundary)) {
1867 0 : php_http_throw(bad_method_call, "http\\Message is not a multipart message", NULL);
1868 0 : return;
1869 : }
1870 :
1871 1 : php_http_expect(msg = php_http_message_body_split(obj->message->body, boundary), bad_message, return);
1872 :
1873 1 : PTR_FREE(boundary);
1874 :
1875 1 : RETURN_OBJVAL(php_http_message_object_new_ex(php_http_message_class_entry, msg, NULL TSRMLS_CC), 0);
1876 : }
1877 :
1878 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_count, 0, 0, 0)
1879 : ZEND_END_ARG_INFO();
1880 4 : static PHP_METHOD(HttpMessage, count)
1881 : {
1882 4 : long count_mode = -1;
1883 :
1884 4 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &count_mode)) {
1885 4 : long i = 0;
1886 4 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1887 :
1888 4 : PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
1889 :
1890 4 : php_http_message_count(i, obj->message);
1891 4 : RETURN_LONG(i);
1892 : }
1893 : }
1894 :
1895 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_rewind, 0, 0, 0)
1896 : ZEND_END_ARG_INFO();
1897 1 : static PHP_METHOD(HttpMessage, rewind)
1898 : {
1899 1 : if (SUCCESS == zend_parse_parameters_none()) {
1900 1 : zval *zobj = getThis();
1901 1 : php_http_message_object_t *obj = zend_object_store_get_object(zobj TSRMLS_CC);
1902 :
1903 1 : if (obj->iterator) {
1904 0 : zval_ptr_dtor(&obj->iterator);
1905 : }
1906 1 : Z_ADDREF_P(zobj);
1907 1 : obj->iterator = zobj;
1908 : }
1909 1 : }
1910 :
1911 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_valid, 0, 0, 0)
1912 : ZEND_END_ARG_INFO();
1913 3 : static PHP_METHOD(HttpMessage, valid)
1914 : {
1915 3 : if (SUCCESS == zend_parse_parameters_none()) {
1916 3 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1917 :
1918 3 : RETURN_BOOL(obj->iterator != NULL);
1919 : }
1920 : }
1921 :
1922 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_next, 0, 0, 0)
1923 : ZEND_END_ARG_INFO();
1924 2 : static PHP_METHOD(HttpMessage, next)
1925 : {
1926 2 : if (SUCCESS == zend_parse_parameters_none()) {
1927 2 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1928 :
1929 2 : if (obj->iterator) {
1930 2 : php_http_message_object_t *itr = zend_object_store_get_object(obj->iterator TSRMLS_CC);
1931 :
1932 3 : if (itr && itr->parent) {
1933 1 : zval *old = obj->iterator;
1934 1 : MAKE_STD_ZVAL(obj->iterator);
1935 1 : ZVAL_OBJVAL(obj->iterator, itr->parent->zv, 1);
1936 1 : zval_ptr_dtor(&old);
1937 : } else {
1938 1 : zval_ptr_dtor(&obj->iterator);
1939 1 : obj->iterator = NULL;
1940 : }
1941 : }
1942 : }
1943 2 : }
1944 :
1945 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_key, 0, 0, 0)
1946 : ZEND_END_ARG_INFO();
1947 2 : static PHP_METHOD(HttpMessage, key)
1948 : {
1949 2 : if (SUCCESS == zend_parse_parameters_none()) {
1950 2 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1951 :
1952 2 : RETURN_LONG(obj->iterator ? obj->iterator->value.obj.handle:0);
1953 : }
1954 : }
1955 :
1956 : ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_current, 0, 0, 0)
1957 : ZEND_END_ARG_INFO();
1958 2 : static PHP_METHOD(HttpMessage, current)
1959 : {
1960 2 : if (SUCCESS == zend_parse_parameters_none()) {
1961 2 : php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1962 :
1963 2 : if (obj->iterator) {
1964 2 : RETURN_ZVAL(obj->iterator, 1, 0);
1965 : }
1966 : }
1967 : }
1968 :
1969 : static zend_function_entry php_http_message_methods[] = {
1970 : PHP_ME(HttpMessage, __construct, ai_HttpMessage___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
1971 : PHP_ME(HttpMessage, getBody, ai_HttpMessage_getBody, ZEND_ACC_PUBLIC)
1972 : PHP_ME(HttpMessage, setBody, ai_HttpMessage_setBody, ZEND_ACC_PUBLIC)
1973 : PHP_ME(HttpMessage, addBody, ai_HttpMessage_addBody, ZEND_ACC_PUBLIC)
1974 : PHP_ME(HttpMessage, getHeader, ai_HttpMessage_getHeader, ZEND_ACC_PUBLIC)
1975 : PHP_ME(HttpMessage, setHeader, ai_HttpMessage_setHeader, ZEND_ACC_PUBLIC)
1976 : PHP_ME(HttpMessage, addHeader, ai_HttpMessage_addHeader, ZEND_ACC_PUBLIC)
1977 : PHP_ME(HttpMessage, getHeaders, ai_HttpMessage_getHeaders, ZEND_ACC_PUBLIC)
1978 : PHP_ME(HttpMessage, setHeaders, ai_HttpMessage_setHeaders, ZEND_ACC_PUBLIC)
1979 : PHP_ME(HttpMessage, addHeaders, ai_HttpMessage_addHeaders, ZEND_ACC_PUBLIC)
1980 : PHP_ME(HttpMessage, getType, ai_HttpMessage_getType, ZEND_ACC_PUBLIC)
1981 : PHP_ME(HttpMessage, setType, ai_HttpMessage_setType, ZEND_ACC_PUBLIC)
1982 : PHP_ME(HttpMessage, getInfo, ai_HttpMessage_getInfo, ZEND_ACC_PUBLIC)
1983 : PHP_ME(HttpMessage, setInfo, ai_HttpMessage_setInfo, ZEND_ACC_PUBLIC)
1984 : PHP_ME(HttpMessage, getResponseCode, ai_HttpMessage_getResponseCode, ZEND_ACC_PUBLIC)
1985 : PHP_ME(HttpMessage, setResponseCode, ai_HttpMessage_setResponseCode, ZEND_ACC_PUBLIC)
1986 : PHP_ME(HttpMessage, getResponseStatus, ai_HttpMessage_getResponseStatus, ZEND_ACC_PUBLIC)
1987 : PHP_ME(HttpMessage, setResponseStatus, ai_HttpMessage_setResponseStatus, ZEND_ACC_PUBLIC)
1988 : PHP_ME(HttpMessage, getRequestMethod, ai_HttpMessage_getRequestMethod, ZEND_ACC_PUBLIC)
1989 : PHP_ME(HttpMessage, setRequestMethod, ai_HttpMessage_setRequestMethod, ZEND_ACC_PUBLIC)
1990 : PHP_ME(HttpMessage, getRequestUrl, ai_HttpMessage_getRequestUrl, ZEND_ACC_PUBLIC)
1991 : PHP_ME(HttpMessage, setRequestUrl, ai_HttpMessage_setRequestUrl, ZEND_ACC_PUBLIC)
1992 : PHP_ME(HttpMessage, getHttpVersion, ai_HttpMessage_getHttpVersion, ZEND_ACC_PUBLIC)
1993 : PHP_ME(HttpMessage, setHttpVersion, ai_HttpMessage_setHttpVersion, ZEND_ACC_PUBLIC)
1994 : PHP_ME(HttpMessage, getParentMessage, ai_HttpMessage_getParentMessage, ZEND_ACC_PUBLIC)
1995 : PHP_ME(HttpMessage, toString, ai_HttpMessage_toString, ZEND_ACC_PUBLIC)
1996 : PHP_ME(HttpMessage, toCallback, ai_HttpMessage_toCallback, ZEND_ACC_PUBLIC)
1997 : PHP_ME(HttpMessage, toStream, ai_HttpMessage_toStream, ZEND_ACC_PUBLIC)
1998 :
1999 : /* implements Countable */
2000 : PHP_ME(HttpMessage, count, ai_HttpMessage_count, ZEND_ACC_PUBLIC)
2001 :
2002 : /* implements Serializable */
2003 : PHP_ME(HttpMessage, serialize, ai_HttpMessage_serialize, ZEND_ACC_PUBLIC)
2004 : PHP_ME(HttpMessage, unserialize, ai_HttpMessage_unserialize, ZEND_ACC_PUBLIC)
2005 :
2006 : /* implements Iterator */
2007 : PHP_ME(HttpMessage, rewind, ai_HttpMessage_rewind, ZEND_ACC_PUBLIC)
2008 : PHP_ME(HttpMessage, valid, ai_HttpMessage_valid, ZEND_ACC_PUBLIC)
2009 : PHP_ME(HttpMessage, current, ai_HttpMessage_current, ZEND_ACC_PUBLIC)
2010 : PHP_ME(HttpMessage, key, ai_HttpMessage_key, ZEND_ACC_PUBLIC)
2011 : PHP_ME(HttpMessage, next, ai_HttpMessage_next, ZEND_ACC_PUBLIC)
2012 :
2013 : ZEND_MALIAS(HttpMessage, __toString, toString, ai_HttpMessage___toString, ZEND_ACC_PUBLIC)
2014 :
2015 : PHP_ME(HttpMessage, detach, ai_HttpMessage_detach, ZEND_ACC_PUBLIC)
2016 : PHP_ME(HttpMessage, prepend, ai_HttpMessage_prepend, ZEND_ACC_PUBLIC)
2017 : PHP_ME(HttpMessage, reverse, ai_HttpMessage_reverse, ZEND_ACC_PUBLIC)
2018 :
2019 : PHP_ME(HttpMessage, isMultipart, ai_HttpMessage_isMultipart, ZEND_ACC_PUBLIC)
2020 : PHP_ME(HttpMessage, splitMultipartBody, ai_HttpMessage_splitMultipartBody, ZEND_ACC_PUBLIC)
2021 :
2022 : EMPTY_FUNCTION_ENTRY
2023 : };
2024 :
2025 : zend_class_entry *php_http_message_class_entry;
2026 :
2027 374 : PHP_MINIT_FUNCTION(http_message)
2028 : {
2029 374 : zend_class_entry ce = {0};
2030 :
2031 374 : INIT_NS_CLASS_ENTRY(ce, "http", "Message", php_http_message_methods);
2032 374 : php_http_message_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
2033 374 : php_http_message_class_entry->create_object = php_http_message_object_new;
2034 374 : memcpy(&php_http_message_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2035 374 : php_http_message_object_handlers.clone_obj = php_http_message_object_clone;
2036 374 : php_http_message_object_handlers.read_property = php_http_message_object_read_prop;
2037 374 : php_http_message_object_handlers.write_property = php_http_message_object_write_prop;
2038 374 : php_http_message_object_handlers.get_properties = php_http_message_object_get_props;
2039 374 : php_http_message_object_handlers.get_property_ptr_ptr = NULL;
2040 :
2041 374 : zend_class_implements(php_http_message_class_entry TSRMLS_CC, 3, spl_ce_Countable, zend_ce_serializable, zend_ce_iterator);
2042 :
2043 374 : zend_hash_init(&php_http_message_object_prophandlers, 9, NULL, NULL, 1);
2044 374 : zend_declare_property_long(php_http_message_class_entry, ZEND_STRL("type"), PHP_HTTP_NONE, ZEND_ACC_PROTECTED TSRMLS_CC);
2045 374 : php_http_message_object_add_prophandler(ZEND_STRL("type"), php_http_message_object_prophandler_get_type, php_http_message_object_prophandler_set_type);
2046 374 : zend_declare_property_null(php_http_message_class_entry, ZEND_STRL("body"), ZEND_ACC_PROTECTED TSRMLS_CC);
2047 374 : php_http_message_object_add_prophandler(ZEND_STRL("body"), php_http_message_object_prophandler_get_body, php_http_message_object_prophandler_set_body);
2048 374 : zend_declare_property_string(php_http_message_class_entry, ZEND_STRL("requestMethod"), "", ZEND_ACC_PROTECTED TSRMLS_CC);
2049 374 : php_http_message_object_add_prophandler(ZEND_STRL("requestMethod"), php_http_message_object_prophandler_get_request_method, php_http_message_object_prophandler_set_request_method);
2050 374 : zend_declare_property_string(php_http_message_class_entry, ZEND_STRL("requestUrl"), "", ZEND_ACC_PROTECTED TSRMLS_CC);
2051 374 : php_http_message_object_add_prophandler(ZEND_STRL("requestUrl"), php_http_message_object_prophandler_get_request_url, php_http_message_object_prophandler_set_request_url);
2052 374 : zend_declare_property_string(php_http_message_class_entry, ZEND_STRL("responseStatus"), "", ZEND_ACC_PROTECTED TSRMLS_CC);
2053 374 : php_http_message_object_add_prophandler(ZEND_STRL("responseStatus"), php_http_message_object_prophandler_get_response_status, php_http_message_object_prophandler_set_response_status);
2054 374 : zend_declare_property_long(php_http_message_class_entry, ZEND_STRL("responseCode"), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
2055 374 : php_http_message_object_add_prophandler(ZEND_STRL("responseCode"), php_http_message_object_prophandler_get_response_code, php_http_message_object_prophandler_set_response_code);
2056 374 : zend_declare_property_null(php_http_message_class_entry, ZEND_STRL("httpVersion"), ZEND_ACC_PROTECTED TSRMLS_CC);
2057 374 : php_http_message_object_add_prophandler(ZEND_STRL("httpVersion"), php_http_message_object_prophandler_get_http_version, php_http_message_object_prophandler_set_http_version);
2058 374 : zend_declare_property_null(php_http_message_class_entry, ZEND_STRL("headers"), ZEND_ACC_PROTECTED TSRMLS_CC);
2059 374 : php_http_message_object_add_prophandler(ZEND_STRL("headers"), php_http_message_object_prophandler_get_headers, php_http_message_object_prophandler_set_headers);
2060 374 : zend_declare_property_null(php_http_message_class_entry, ZEND_STRL("parentMessage"), ZEND_ACC_PROTECTED TSRMLS_CC);
2061 374 : php_http_message_object_add_prophandler(ZEND_STRL("parentMessage"), php_http_message_object_prophandler_get_parent_message, php_http_message_object_prophandler_set_parent_message);
2062 :
2063 374 : zend_declare_class_constant_long(php_http_message_class_entry, ZEND_STRL("TYPE_NONE"), PHP_HTTP_NONE TSRMLS_CC);
2064 374 : zend_declare_class_constant_long(php_http_message_class_entry, ZEND_STRL("TYPE_REQUEST"), PHP_HTTP_REQUEST TSRMLS_CC);
2065 374 : zend_declare_class_constant_long(php_http_message_class_entry, ZEND_STRL("TYPE_RESPONSE"), PHP_HTTP_RESPONSE TSRMLS_CC);
2066 :
2067 374 : return SUCCESS;
2068 : }
2069 :
2070 374 : PHP_MSHUTDOWN_FUNCTION(http_message)
2071 : {
2072 374 : zend_hash_destroy(&php_http_message_object_prophandlers);
2073 :
2074 374 : return SUCCESS;
2075 : }
2076 :
2077 : /*
2078 : * Local variables:
2079 : * tab-width: 4
2080 : * c-basic-offset: 4
2081 : * End:
2082 : * vim600: noet sw=4 ts=4 fdm=marker
2083 : * vim<600: noet sw=4 ts=4
2084 : */
2085 :
|