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