2 +--------------------------------------------------------------------+
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-2011, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
13 #include "php_http_api.h"
15 #include <ext/spl/spl_observer.h>
17 PHP_HTTP_API php_http_request_t
*php_http_request_init(php_http_request_t
*h
, php_http_request_ops_t
*ops
, php_http_resource_factory_t
*rf
, void *init_arg TSRMLS_DC
)
19 php_http_request_t
*free_h
= NULL
;
22 free_h
= h
= emalloc(sizeof(*h
));
24 memset(h
, 0, sizeof(*h
));
27 h
->rf
= rf
? rf
: php_http_resource_factory_init(NULL
, h
->ops
->rsrc
, h
, NULL
);
28 h
->buffer
= php_http_buffer_init(NULL
);
29 h
->parser
= php_http_message_parser_init(NULL TSRMLS_CC
);
30 h
->message
= php_http_message_init(NULL
, 0 TSRMLS_CC
);
32 TSRMLS_SET_CTX(h
->ts
);
35 if (!(h
= h
->ops
->init(h
, init_arg
))) {
36 php_http_error(HE_WARNING
, PHP_HTTP_E_REQUEST
, "Could not initialize request");
39 php_http_request_free(&free_h
);
47 PHP_HTTP_API
void php_http_request_dtor(php_http_request_t
*h
)
53 php_http_resource_factory_free(&h
->rf
);
55 php_http_message_parser_free(&h
->parser
);
56 php_http_message_free(&h
->message
);
57 php_http_buffer_free(&h
->buffer
);
60 PHP_HTTP_API
void php_http_request_free(php_http_request_t
**h
)
63 php_http_request_dtor(*h
);
69 PHP_HTTP_API php_http_request_t
*php_http_request_copy(php_http_request_t
*from
, php_http_request_t
*to
)
71 if (!from
->ops
->copy
) {
74 TSRMLS_FETCH_FROM_CTX(from
->ts
);
77 to
= ecalloc(1, sizeof(*to
));
82 php_http_resource_factory_addref(from
->rf
);
85 to
->rf
= php_http_resource_factory_init(NULL
, to
->ops
->rsrc
, to
, NULL
);
87 to
->buffer
= php_http_buffer_init(NULL
);
88 to
->parser
= php_http_message_parser_init(NULL TSRMLS_CC
);
89 to
->message
= php_http_message_init(NULL
, 0 TSRMLS_CC
);
91 TSRMLS_SET_CTX(to
->ts
);
93 return to
->ops
->copy(from
, to
);
97 PHP_HTTP_API STATUS
php_http_request_exec(php_http_request_t
*h
, php_http_request_method_t meth
, const char *url
, php_http_message_body_t
*body
)
100 return h
->ops
->exec(h
, meth
, url
, body
);
105 PHP_HTTP_API STATUS
php_http_request_reset(php_http_request_t
*h
)
108 return h
->ops
->reset(h
);
113 PHP_HTTP_API STATUS
php_http_request_setopt(php_http_request_t
*h
, php_http_request_setopt_opt_t opt
, void *arg
)
115 if (h
->ops
->setopt
) {
116 return h
->ops
->setopt(h
, opt
, arg
);
121 PHP_HTTP_API STATUS
php_http_request_getopt(php_http_request_t
*h
, php_http_request_getopt_opt_t opt
, void *arg
)
123 if (h
->ops
->getopt
) {
124 return h
->ops
->getopt(h
, opt
, arg
);
129 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpRequest, method, 0, req_args)
130 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpRequest, method, 0)
131 #define PHP_HTTP_REQUEST_ME(method, visibility) PHP_ME(HttpRequest, method, PHP_HTTP_ARGS(HttpRequest, method), visibility)
132 #define PHP_HTTP_REQUEST_ALIAS(method, func) PHP_HTTP_STATIC_ME_ALIAS(method, func, PHP_HTTP_ARGS(HttpRequest, method))
133 #define PHP_HTTP_REQUEST_MALIAS(me, al, vis) ZEND_FENTRY(me, ZEND_MN(HttpRequest_##al), PHP_HTTP_ARGS(HttpRequest, al), vis)
135 PHP_HTTP_EMPTY_ARGS(__construct
);
137 PHP_HTTP_EMPTY_ARGS(getOptions
);
138 PHP_HTTP_BEGIN_ARGS(setOptions
, 0)
139 PHP_HTTP_ARG_VAL(options
, 0)
142 PHP_HTTP_EMPTY_ARGS(getSslOptions
);
143 PHP_HTTP_BEGIN_ARGS(setSslOptions
, 0)
144 PHP_HTTP_ARG_VAL(ssl_options
, 0)
147 PHP_HTTP_BEGIN_ARGS(addSslOptions
, 0)
148 PHP_HTTP_ARG_VAL(ssl_optins
, 0)
151 PHP_HTTP_EMPTY_ARGS(getHeaders
);
152 PHP_HTTP_BEGIN_ARGS(setHeaders
, 0)
153 PHP_HTTP_ARG_VAL(headers
, 0)
156 PHP_HTTP_BEGIN_ARGS(addHeaders
, 1)
157 PHP_HTTP_ARG_VAL(headers
, 0)
160 PHP_HTTP_EMPTY_ARGS(getCookies
);
161 PHP_HTTP_BEGIN_ARGS(setCookies
, 0)
162 PHP_HTTP_ARG_VAL(cookies
, 0)
165 PHP_HTTP_BEGIN_ARGS(addCookies
, 1)
166 PHP_HTTP_ARG_VAL(cookies
, 0)
169 PHP_HTTP_EMPTY_ARGS(enableCookies
);
170 PHP_HTTP_BEGIN_ARGS(resetCookies
, 0)
171 PHP_HTTP_ARG_VAL(session_only
, 0)
173 PHP_HTTP_EMPTY_ARGS(flushCookies
);
175 PHP_HTTP_EMPTY_ARGS(getUrl
);
176 PHP_HTTP_BEGIN_ARGS(setUrl
, 1)
177 PHP_HTTP_ARG_VAL(url
, 0)
180 PHP_HTTP_EMPTY_ARGS(getMethod
);
181 PHP_HTTP_BEGIN_ARGS(setMethod
, 1)
182 PHP_HTTP_ARG_VAL(request_method
, 0)
185 PHP_HTTP_EMPTY_ARGS(getContentType
);
186 PHP_HTTP_BEGIN_ARGS(setContentType
, 1)
187 PHP_HTTP_ARG_VAL(content_type
, 0)
190 PHP_HTTP_EMPTY_ARGS(getQueryData
);
191 PHP_HTTP_BEGIN_ARGS(setQueryData
, 0)
192 PHP_HTTP_ARG_VAL(query_data
, 0)
195 PHP_HTTP_BEGIN_ARGS(addQueryData
, 1)
196 PHP_HTTP_ARG_VAL(query_data
, 0)
200 PHP_HTTP_EMPTY_ARGS(getBody
);
201 PHP_HTTP_BEGIN_ARGS(setBody
, 0)
202 PHP_HTTP_ARG_OBJ(http
\\Message
\\Body
, body
, 0)
205 PHP_HTTP_BEGIN_ARGS(addBody
, 1)
206 PHP_HTTP_ARG_OBJ(http
\\Message
\\Body
, body
, 0)
209 PHP_HTTP_BEGIN_ARGS(getResponseCookies
, 0)
210 PHP_HTTP_ARG_VAL(flags
, 0)
211 PHP_HTTP_ARG_VAL(allowed_extras
, 0)
214 PHP_HTTP_EMPTY_ARGS(getResponseBody
);
215 PHP_HTTP_EMPTY_ARGS(getResponseCode
);
216 PHP_HTTP_EMPTY_ARGS(getResponseStatus
);
217 PHP_HTTP_BEGIN_ARGS(getResponseHeader
, 0)
218 PHP_HTTP_ARG_VAL(header_name
, 0)
221 PHP_HTTP_EMPTY_ARGS(getMessageClass
);
222 PHP_HTTP_BEGIN_ARGS(setMessageClass
, 1)
223 PHP_HTTP_ARG_VAL(message_class_name
, 0)
226 PHP_HTTP_EMPTY_ARGS(getResponseMessage
);
227 PHP_HTTP_EMPTY_ARGS(getRequestMessage
);
228 PHP_HTTP_EMPTY_ARGS(getHistory
);
229 PHP_HTTP_EMPTY_ARGS(clearHistory
);
230 PHP_HTTP_EMPTY_ARGS(send
);
232 PHP_HTTP_EMPTY_ARGS(getObservers
);
233 PHP_HTTP_BEGIN_ARGS(attach
, 1)
234 PHP_HTTP_ARG_OBJ(SplObserver
, observer
, 0)
236 PHP_HTTP_BEGIN_ARGS(detach
, 1)
237 PHP_HTTP_ARG_OBJ(SplObserver
, observer
, 0)
239 PHP_HTTP_EMPTY_ARGS(notify
);
240 PHP_HTTP_EMPTY_ARGS(getProgress
);
241 PHP_HTTP_BEGIN_ARGS(getTransferInfo
, 0)
242 PHP_HTTP_ARG_VAL(name
, 0)
246 zend_class_entry
*php_http_request_class_entry
;
247 zend_function_entry php_http_request_method_entry
[] = {
248 PHP_HTTP_REQUEST_ME(__construct
, ZEND_ACC_PRIVATE
|ZEND_ACC_CTOR
)
250 PHP_HTTP_REQUEST_ME(getObservers
, ZEND_ACC_PUBLIC
)
251 PHP_HTTP_REQUEST_ME(notify
, ZEND_ACC_PUBLIC
)
252 PHP_HTTP_REQUEST_ME(attach
, ZEND_ACC_PUBLIC
)
253 PHP_HTTP_REQUEST_ME(detach
, ZEND_ACC_PUBLIC
)
254 PHP_HTTP_REQUEST_ME(getProgress
, ZEND_ACC_PUBLIC
)
255 PHP_HTTP_REQUEST_ME(getTransferInfo
, ZEND_ACC_PUBLIC
)
257 PHP_HTTP_REQUEST_ME(setOptions
, ZEND_ACC_PUBLIC
)
258 PHP_HTTP_REQUEST_ME(getOptions
, ZEND_ACC_PUBLIC
)
259 PHP_HTTP_REQUEST_ME(setSslOptions
, ZEND_ACC_PUBLIC
)
260 PHP_HTTP_REQUEST_ME(getSslOptions
, ZEND_ACC_PUBLIC
)
261 PHP_HTTP_REQUEST_ME(addSslOptions
, ZEND_ACC_PUBLIC
)
263 PHP_HTTP_REQUEST_ME(addHeaders
, ZEND_ACC_PUBLIC
)
264 PHP_HTTP_REQUEST_ME(getHeaders
, ZEND_ACC_PUBLIC
)
265 PHP_HTTP_REQUEST_ME(setHeaders
, ZEND_ACC_PUBLIC
)
267 PHP_HTTP_REQUEST_ME(addCookies
, ZEND_ACC_PUBLIC
)
268 PHP_HTTP_REQUEST_ME(getCookies
, ZEND_ACC_PUBLIC
)
269 PHP_HTTP_REQUEST_ME(setCookies
, ZEND_ACC_PUBLIC
)
271 PHP_HTTP_REQUEST_ME(enableCookies
, ZEND_ACC_PUBLIC
)
272 PHP_HTTP_REQUEST_ME(resetCookies
, ZEND_ACC_PUBLIC
)
273 PHP_HTTP_REQUEST_ME(flushCookies
, ZEND_ACC_PUBLIC
)
275 PHP_HTTP_REQUEST_ME(setMethod
, ZEND_ACC_PUBLIC
)
276 PHP_HTTP_REQUEST_ME(getMethod
, ZEND_ACC_PUBLIC
)
278 PHP_HTTP_REQUEST_ME(setUrl
, ZEND_ACC_PUBLIC
)
279 PHP_HTTP_REQUEST_ME(getUrl
, ZEND_ACC_PUBLIC
)
281 PHP_HTTP_REQUEST_ME(setContentType
, ZEND_ACC_PUBLIC
)
282 PHP_HTTP_REQUEST_ME(getContentType
, ZEND_ACC_PUBLIC
)
284 PHP_HTTP_REQUEST_ME(setQueryData
, ZEND_ACC_PUBLIC
)
285 PHP_HTTP_REQUEST_ME(getQueryData
, ZEND_ACC_PUBLIC
)
286 PHP_HTTP_REQUEST_ME(addQueryData
, ZEND_ACC_PUBLIC
)
288 PHP_HTTP_REQUEST_ME(setBody
, ZEND_ACC_PUBLIC
)
289 PHP_HTTP_REQUEST_ME(getBody
, ZEND_ACC_PUBLIC
)
290 PHP_HTTP_REQUEST_ME(addBody
, ZEND_ACC_PUBLIC
)
292 PHP_HTTP_REQUEST_ME(send
, ZEND_ACC_PUBLIC
)
294 PHP_HTTP_REQUEST_ME(getResponseHeader
, ZEND_ACC_PUBLIC
)
295 PHP_HTTP_REQUEST_ME(getResponseCookies
, ZEND_ACC_PUBLIC
)
296 PHP_HTTP_REQUEST_ME(getResponseCode
, ZEND_ACC_PUBLIC
)
297 PHP_HTTP_REQUEST_ME(getResponseStatus
, ZEND_ACC_PUBLIC
)
298 PHP_HTTP_REQUEST_ME(getResponseBody
, ZEND_ACC_PUBLIC
)
299 PHP_HTTP_REQUEST_ME(getResponseMessage
, ZEND_ACC_PUBLIC
)
300 PHP_HTTP_REQUEST_ME(getRequestMessage
, ZEND_ACC_PUBLIC
)
301 PHP_HTTP_REQUEST_ME(getHistory
, ZEND_ACC_PUBLIC
)
302 PHP_HTTP_REQUEST_ME(clearHistory
, ZEND_ACC_PUBLIC
)
304 PHP_HTTP_REQUEST_ME(getMessageClass
, ZEND_ACC_PUBLIC
)
305 PHP_HTTP_REQUEST_ME(setMessageClass
, ZEND_ACC_PUBLIC
)
309 static zend_object_handlers php_http_request_object_handlers
;
311 zend_object_value
php_http_request_object_new(zend_class_entry
*ce TSRMLS_DC
)
313 return php_http_request_object_new_ex(ce
, NULL
, NULL TSRMLS_CC
);
316 zend_object_value
php_http_request_object_new_ex(zend_class_entry
*ce
, php_http_request_t
*r
, php_http_request_object_t
**ptr TSRMLS_DC
)
318 zend_object_value ov
;
319 php_http_request_object_t
*o
;
321 o
= ecalloc(1, sizeof(php_http_request_object_t
));
322 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
323 object_properties_init((zend_object
*) o
, ce
);
325 if (!(o
->request
= r
)) {
326 o
->request
= php_http_request_init(NULL
, NULL
, NULL
, NULL TSRMLS_CC
);
333 ov
.handle
= zend_objects_store_put(o
, NULL
, php_http_request_object_free
, NULL TSRMLS_CC
);
334 ov
.handlers
= &php_http_request_object_handlers
;
339 zend_object_value
php_http_request_object_clone(zval
*this_ptr TSRMLS_DC
)
341 zend_object_value new_ov
;
342 php_http_request_object_t
*new_obj
, *old_obj
= zend_object_store_get_object(this_ptr TSRMLS_CC
);
344 new_ov
= php_http_request_object_new_ex(old_obj
->zo
.ce
, php_http_request_copy(old_obj
->request
, NULL
), &new_obj TSRMLS_CC
);
345 zend_objects_clone_members(&new_obj
->zo
, new_ov
, &old_obj
->zo
, Z_OBJ_HANDLE_P(this_ptr
) TSRMLS_CC
);
350 void php_http_request_object_free(void *object TSRMLS_DC
)
352 php_http_request_object_t
*o
= (php_http_request_object_t
*) object
;
354 php_http_request_free(&o
->request
);
355 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
359 static inline void php_http_request_object_check_request_content_type(zval
*this_ptr TSRMLS_DC
)
361 zval
*ctype
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("contentType"), 0 TSRMLS_CC
);
363 if (Z_STRLEN_P(ctype
)) {
364 zval
**headers
, *opts
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC
);
366 if ( (Z_TYPE_P(opts
) == IS_ARRAY
) &&
367 (SUCCESS
== zend_hash_find(Z_ARRVAL_P(opts
), ZEND_STRS("headers"), (void *) &headers
)) &&
368 (Z_TYPE_PP(headers
) == IS_ARRAY
)) {
371 /* only override if not already set */
372 if ((SUCCESS
!= zend_hash_find(Z_ARRVAL_PP(headers
), ZEND_STRS("Content-Type"), (void *) &ct_header
))) {
373 add_assoc_stringl(*headers
, "Content-Type", Z_STRVAL_P(ctype
), Z_STRLEN_P(ctype
), 1);
375 /* or not a string, zero length string or a string of spaces */
376 if ((Z_TYPE_PP(ct_header
) != IS_STRING
) || !Z_STRLEN_PP(ct_header
)) {
377 add_assoc_stringl(*headers
, "Content-Type", Z_STRVAL_P(ctype
), Z_STRLEN_P(ctype
), 1);
379 int i
, only_space
= 1;
381 /* check for spaces only */
382 for (i
= 0; i
< Z_STRLEN_PP(ct_header
); ++i
) {
383 if (!PHP_HTTP_IS_CTYPE(space
, Z_STRVAL_PP(ct_header
)[i
])) {
389 add_assoc_stringl(*headers
, "Content-Type", Z_STRVAL_P(ctype
), Z_STRLEN_P(ctype
), 1);
395 MAKE_STD_ZVAL(headers
);
397 add_assoc_stringl(headers
, "Content-Type", Z_STRVAL_P(ctype
), Z_STRLEN_P(ctype
), 1);
398 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "addheaders", NULL
, headers
);
399 zval_ptr_dtor(&headers
);
404 static inline zend_object_value
php_http_request_object_message(zval
*this_ptr
, php_http_message_t
*msg TSRMLS_DC
)
406 zend_object_value ov
;
407 zval
*zcn
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("messageClass"), 0 TSRMLS_CC
);
408 zend_class_entry
*class_entry
;
411 && (class_entry
= zend_fetch_class(Z_STRVAL_P(zcn
), Z_STRLEN_P(zcn
), 0 TSRMLS_CC
))
412 && (SUCCESS
== php_http_new(&ov
, class_entry
, (php_http_new_t
) php_http_message_object_new_ex
, php_http_message_class_entry
, msg
, NULL TSRMLS_CC
))) {
415 return php_http_message_object_new_ex(php_http_message_class_entry
, msg
, NULL TSRMLS_CC
);
419 STATUS
php_http_request_object_requesthandler(php_http_request_object_t
*obj
, zval
*this_ptr
, php_http_request_method_t
*meth
, char **url
, php_http_message_body_t
**body TSRMLS_DC
)
422 php_http_request_progress_t
*progress
;
424 /* reset request handle */
425 php_http_request_reset(obj
->request
);
426 /* reset transfer info */
427 zend_update_property_null(php_http_request_class_entry
, getThis(), ZEND_STRL("info") TSRMLS_CC
);
430 *meth
= (php_http_request_method_t
) Z_LVAL_P(zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("method"), 0 TSRMLS_CC
));
434 php_url
*tmp
, qdu
= {NULL
, NULL
, NULL
, NULL
, 0, NULL
, NULL
, NULL
};
435 zval
*zurl
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("url"), 0 TSRMLS_CC
);
436 zval
*zqdata
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("queryData"), 0 TSRMLS_CC
);
438 if (Z_STRLEN_P(zqdata
)) {
439 qdu
.query
= Z_STRVAL_P(zqdata
);
441 php_http_url(0, tmp
= php_url_parse(Z_STRVAL_P(zurl
)), &qdu
, NULL
, url
, NULL TSRMLS_CC
);
446 zval
*zbody
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("requestBody"), 0 TSRMLS_CC
);
448 if (Z_TYPE_P(zbody
) == IS_OBJECT
) {
449 *body
= ((php_http_message_body_object_t
*)zend_object_store_get_object(zbody TSRMLS_CC
))->body
;
451 php_stream_rewind(php_http_message_body_stream(*body
));
456 php_http_request_object_check_request_content_type(getThis() TSRMLS_CC
);
457 zoptions
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC
);
458 php_http_request_setopt(obj
->request
, PHP_HTTP_REQUEST_OPT_SETTINGS
, Z_ARRVAL_P(zoptions
));
460 if (SUCCESS
== php_http_request_getopt(obj
->request
, PHP_HTTP_REQUEST_OPT_PROGRESS_INFO
, &progress
)) {
461 if (!progress
->callback
) {
462 php_http_request_progress_callback_t
*callback
= emalloc(sizeof(*callback
));
464 callback
->type
= PHP_HTTP_REQUEST_PROGRESS_CALLBACK_USER
;
465 callback
->pass_state
= 0;
466 MAKE_STD_ZVAL(callback
->func
.user
);
467 array_init(callback
->func
.user
);
468 Z_ADDREF_P(getThis());
469 add_next_index_zval(callback
->func
.user
, getThis());
470 add_next_index_stringl(callback
->func
.user
, ZEND_STRL("notify"), 1);
472 php_http_request_setopt(obj
->request
, PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK
, callback
);
474 progress
->state
.info
= "start";
475 php_http_request_progress_notify(progress TSRMLS_CC
);
476 progress
->state
.started
= 1;
481 static inline void empty_response(zval
*this_ptr TSRMLS_DC
)
483 zend_update_property_null(php_http_request_class_entry
, getThis(), ZEND_STRL("responseMessage") TSRMLS_CC
);
484 zend_update_property_long(php_http_request_class_entry
, getThis(), ZEND_STRL("responseCode"), 0 TSRMLS_CC
);
485 zend_update_property_string(php_http_request_class_entry
, getThis(), ZEND_STRL("responseStatus"), "" TSRMLS_CC
);
488 STATUS
php_http_request_object_responsehandler(php_http_request_object_t
*obj
, zval
*this_ptr TSRMLS_DC
)
490 STATUS ret
= SUCCESS
;
492 php_http_message_t
*msg
;
493 php_http_request_progress_t
*progress
;
495 /* always fetch info */
498 php_http_request_getopt(obj
->request
, PHP_HTTP_REQUEST_OPT_TRANSFER_INFO
, Z_ARRVAL_P(info
));
499 zend_update_property(php_http_request_class_entry
, getThis(), ZEND_STRL("transferInfo"), info TSRMLS_CC
);
500 zval_ptr_dtor(&info
);
502 if ((msg
= obj
->request
->message
)) {
504 if (i_zend_is_true(zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("recordHistory"), 0 TSRMLS_CC
))) {
505 zval
*new_hist
, *old_hist
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("history"), 0 TSRMLS_CC
);
506 zend_object_value ov
= php_http_request_object_message(getThis(), php_http_message_copy(msg
, NULL
) TSRMLS_CC
);
508 MAKE_STD_ZVAL(new_hist
);
509 ZVAL_OBJVAL(new_hist
, ov
, 0);
511 if (Z_TYPE_P(old_hist
) == IS_OBJECT
) {
512 php_http_message_object_prepend(new_hist
, old_hist
, 1 TSRMLS_CC
);
515 zend_update_property(php_http_request_class_entry
, getThis(), ZEND_STRL("history"), new_hist TSRMLS_CC
);
516 zval_ptr_dtor(&new_hist
);
519 /* update response info */
520 if (PHP_HTTP_MESSAGE_TYPE(RESPONSE
, msg
)) {
523 zend_update_property_long(php_http_request_class_entry
, getThis(), ZEND_STRL("responseCode"), msg
->http
.info
.response
.code TSRMLS_CC
);
524 zend_update_property_string(php_http_request_class_entry
, getThis(), ZEND_STRL("responseStatus"), STR_PTR(msg
->http
.info
.response
.status
) TSRMLS_CC
);
526 MAKE_STD_ZVAL(message
);
527 ZVAL_OBJVAL(message
, php_http_request_object_message(getThis(), msg TSRMLS_CC
), 0);
528 zend_update_property(php_http_request_class_entry
, getThis(), ZEND_STRL("responseMessage"), message TSRMLS_CC
);
529 zval_ptr_dtor(&message
);
531 obj
->request
->message
= php_http_message_init(NULL
, 0 TSRMLS_CC
);
534 empty_response(getThis() TSRMLS_CC
);
537 /* update properties with empty values */
538 empty_response(getThis() TSRMLS_CC
);
541 while (msg
&& !PHP_HTTP_MESSAGE_TYPE(REQUEST
, msg
)) {
544 if (PHP_HTTP_MESSAGE_TYPE(REQUEST
, msg
)) {
547 MAKE_STD_ZVAL(message
);
548 ZVAL_OBJVAL(message
, php_http_request_object_message(getThis(), php_http_message_copy_ex(msg
, NULL
, 0) TSRMLS_CC
), 0);
549 zend_update_property(php_http_request_class_entry
, getThis(), ZEND_STRL("requestMessage"), message TSRMLS_CC
);
550 zval_ptr_dtor(&message
);
553 if (SUCCESS
== php_http_request_getopt(obj
->request
, PHP_HTTP_REQUEST_OPT_PROGRESS_INFO
, &progress
)) {
554 progress
->state
.info
= "finished";
555 progress
->state
.finished
= 1;
556 php_http_request_progress_notify(progress TSRMLS_CC
);
558 php_http_request_setopt(obj
->request
, PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK
, NULL
);
563 static int apply_pretty_key(void *pDest TSRMLS_DC
, int num_args
, va_list args
, zend_hash_key
*hash_key
)
565 zval
**zpp
= pDest
, *arr
= va_arg(args
, zval
*);
567 if (hash_key
->arKey
&& hash_key
->nKeyLength
> 1) {
568 char *tmp
= php_http_pretty_key(estrndup(hash_key
->arKey
, hash_key
->nKeyLength
- 1), hash_key
->nKeyLength
- 1, 1, 0);
571 add_assoc_zval_ex(arr
, tmp
, hash_key
->nKeyLength
, *zpp
);
574 return ZEND_HASH_APPLY_KEEP
;
577 static inline void php_http_request_object_set_options_subr(INTERNAL_FUNCTION_PARAMETERS
, char *key
, size_t len
, int overwrite
, int prettify_keys
)
579 zval
*old_opts
, *new_opts
, *opts
= NULL
, **entry
= NULL
;
581 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &opts
)) {
582 MAKE_STD_ZVAL(new_opts
);
583 array_init(new_opts
);
584 old_opts
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC
);
585 if (Z_TYPE_P(old_opts
) == IS_ARRAY
) {
586 array_copy(Z_ARRVAL_P(old_opts
), Z_ARRVAL_P(new_opts
));
589 if (SUCCESS
== zend_symtable_find(Z_ARRVAL_P(new_opts
), key
, len
, (void *) &entry
)) {
591 zend_hash_clean(Z_ARRVAL_PP(entry
));
593 if (opts
&& zend_hash_num_elements(Z_ARRVAL_P(opts
))) {
595 array_copy(Z_ARRVAL_P(opts
), Z_ARRVAL_PP(entry
));
597 array_join(Z_ARRVAL_P(opts
), Z_ARRVAL_PP(entry
), 0, prettify_keys
? ARRAY_JOIN_PRETTIFY
: 0);
605 array_init_size(tmp
, zend_hash_num_elements(Z_ARRVAL_P(opts
)));
606 zend_hash_apply_with_arguments(Z_ARRVAL_P(opts
) TSRMLS_CC
, apply_pretty_key
, 1, tmp
);
611 add_assoc_zval_ex(new_opts
, key
, len
, opts
);
613 zend_update_property(php_http_request_class_entry
, getThis(), ZEND_STRL("options"), new_opts TSRMLS_CC
);
614 zval_ptr_dtor(&new_opts
);
617 RETVAL_ZVAL(getThis(), 1, 0);
620 static inline void php_http_request_object_get_options_subr(INTERNAL_FUNCTION_PARAMETERS
, char *key
, size_t len
)
622 if (SUCCESS
== zend_parse_parameters_none()) {
623 zval
*opts
, **options
;
625 opts
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC
);
626 array_init(return_value
);
628 if ( (Z_TYPE_P(opts
) == IS_ARRAY
) &&
629 (SUCCESS
== zend_symtable_find(Z_ARRVAL_P(opts
), key
, len
, (void *) &options
))) {
630 convert_to_array(*options
);
631 array_copy(Z_ARRVAL_PP(options
), Z_ARRVAL_P(return_value
));
637 PHP_METHOD(HttpRequest
, __construct
)
639 with_error_handling(EH_THROW
, php_http_exception_class_entry
) {
640 zend_parse_parameters_none();
641 } end_error_handling();
644 PHP_METHOD(HttpRequest
, getObservers
)
646 with_error_handling(EH_THROW
, php_http_exception_class_entry
) {
647 if (SUCCESS
== zend_parse_parameters_none()) {
648 RETVAL_PROP(php_http_request_class_entry
, "observers");
650 } end_error_handling();
653 static int notify(zend_object_iterator
*iter
, void *puser TSRMLS_DC
)
655 zval
**observer
= NULL
;
657 iter
->funcs
->get_current_data(iter
, &observer TSRMLS_CC
);
661 zend_call_method_with_1_params(observer
, NULL
, NULL
, "update", &retval
, puser
);
662 zval_ptr_dtor(&retval
);
668 PHP_METHOD(HttpRequest
, notify
)
670 if (SUCCESS
== zend_parse_parameters_none()) {
671 zval
*observers
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC
);
673 if (Z_TYPE_P(observers
) == IS_OBJECT
) {
674 Z_ADDREF_P(getThis());
675 spl_iterator_apply(observers
, notify
, getThis() TSRMLS_CC
);
676 zval_ptr_dtor(&getThis());
680 RETVAL_ZVAL(getThis(), 1, 0);
683 PHP_METHOD(HttpRequest
, attach
)
687 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &observer
, spl_ce_SplObserver
)) {
688 zval
*retval
, *observers
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC
);
689 zend_call_method_with_1_params(&observers
, NULL
, NULL
, "attach", &retval
, observer
);
690 zval_ptr_dtor(&retval
);
693 RETVAL_ZVAL(getThis(), 1, 0);
696 PHP_METHOD(HttpRequest
, detach
)
700 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &observer
, spl_ce_SplObserver
)) {
701 zval
*retval
, *observers
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC
);
702 zend_call_method_with_1_params(&observers
, NULL
, NULL
, "detach", &retval
, observer
);
703 zval_ptr_dtor(&retval
);
706 RETVAL_ZVAL(getThis(), 1, 0);
709 PHP_METHOD(HttpRequest
, getProgress
)
711 if (SUCCESS
== zend_parse_parameters_none()) {
712 php_http_request_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
713 php_http_request_progress_t
*progress
;
715 php_http_request_getopt(obj
->request
, PHP_HTTP_REQUEST_OPT_PROGRESS_INFO
, &progress
);
716 object_init(return_value
);
717 add_property_bool(return_value
, "started", progress
->state
.started
);
718 add_property_bool(return_value
, "finished", progress
->state
.finished
);
719 add_property_string(return_value
, "info", STR_PTR(progress
->state
.info
), 1);
720 add_property_double(return_value
, "dltotal", progress
->state
.dl
.total
);
721 add_property_double(return_value
, "dlnow", progress
->state
.dl
.now
);
722 add_property_double(return_value
, "ultotal", progress
->state
.ul
.total
);
723 add_property_double(return_value
, "ulnow", progress
->state
.ul
.now
);
727 PHP_METHOD(HttpRequest
, getTransferInfo
)
729 char *info_name
= NULL
;
732 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s", &info_name
, &info_len
)) {
733 zval
**infop
, *temp
= NULL
, *info
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("transferInfo"), 0 TSRMLS_CC
);
735 /* request completed? */
736 if (Z_TYPE_P(info
) != IS_ARRAY
) {
737 php_http_request_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
741 php_http_request_getopt(obj
->request
, PHP_HTTP_REQUEST_OPT_TRANSFER_INFO
, Z_ARRVAL_P(temp
));
745 if (info_len
&& info_name
) {
746 if (SUCCESS
== zend_symtable_find(Z_ARRVAL_P(info
), php_http_pretty_key(info_name
, info_len
, 0, 0), info_len
+ 1, (void *) &infop
)) {
747 RETVAL_ZVAL(*infop
, 1, 0);
749 php_http_error(HE_NOTICE
, PHP_HTTP_E_INVALID_PARAM
, "Could not find transfer info named %s", info_name
);
753 RETVAL_ZVAL(info
, 1, 0);
757 zval_ptr_dtor(&temp
);
764 PHP_METHOD(HttpRequest
, setOptions
)
766 php_http_array_hashkey_t key
= php_http_array_hashkey_init(0);
768 zval
*opts
= NULL
, *old_opts
, *new_opts
, *add_opts
, **opt
;
770 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a!/", &opts
)) {
774 MAKE_STD_ZVAL(new_opts
);
775 array_init(new_opts
);
777 if (!opts
|| !zend_hash_num_elements(Z_ARRVAL_P(opts
))) {
778 zend_update_property(php_http_request_class_entry
, getThis(), ZEND_STRL("options"), new_opts TSRMLS_CC
);
779 zval_ptr_dtor(&new_opts
);
781 MAKE_STD_ZVAL(add_opts
);
782 array_init(add_opts
);
783 /* some options need extra attention -- thus cannot use array_merge() directly */
784 FOREACH_KEYVAL(pos
, opts
, key
, opt
) {
785 if (key
.type
== HASH_KEY_IS_STRING
) {
786 #define KEYMATCH(k, s) ((sizeof(s)==k.len) && !strcasecmp(k.str, s))
787 if (KEYMATCH(key
, "headers")) {
788 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "addheaders", NULL
, *opt
);
789 } else if (KEYMATCH(key
, "cookies")) {
790 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "addcookies", NULL
, *opt
);
791 } else if (KEYMATCH(key
, "ssl")) {
792 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "addssloptions", NULL
, *opt
);
793 } else if (KEYMATCH(key
, "url") || KEYMATCH(key
, "uri")) {
794 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "seturl", NULL
, *opt
);
795 } else if (KEYMATCH(key
, "method")) {
796 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "setmethod", NULL
, *opt
);
797 } else if (KEYMATCH(key
, "flushcookies")) {
798 if (i_zend_is_true(*opt
)) {
799 php_http_request_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
801 php_http_request_setopt(obj
->request
, PHP_HTTP_REQUEST_OPT_COOKIES_FLUSH
, NULL
);
803 } else if (KEYMATCH(key
, "resetcookies")) {
804 php_http_request_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
806 php_http_request_setopt(obj
->request
, PHP_HTTP_REQUEST_OPT_COOKIES_RESET
, NULL
);
807 } else if (KEYMATCH(key
, "enablecookies")) {
808 php_http_request_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
810 php_http_request_setopt(obj
->request
, PHP_HTTP_REQUEST_OPT_COOKIES_ENABLE
, NULL
);
811 } else if (KEYMATCH(key
, "recordHistory")) {
812 zend_update_property(php_http_request_class_entry
, getThis(), ZEND_STRL("recordHistory"), *opt TSRMLS_CC
);
813 } else if (KEYMATCH(key
, "messageClass")) {
814 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "setmessageclass", NULL
, *opt
);
815 } else if (Z_TYPE_PP(opt
) == IS_NULL
) {
816 old_opts
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC
);
817 if (Z_TYPE_P(old_opts
) == IS_ARRAY
) {
818 zend_symtable_del(Z_ARRVAL_P(old_opts
), key
.str
, key
.len
);
822 add_assoc_zval_ex(add_opts
, key
.str
, key
.len
, *opt
);
827 old_opts
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC
);
828 if (Z_TYPE_P(old_opts
) == IS_ARRAY
) {
829 array_copy(Z_ARRVAL_P(old_opts
), Z_ARRVAL_P(new_opts
));
831 array_join(Z_ARRVAL_P(add_opts
), Z_ARRVAL_P(new_opts
), 0, 0);
832 zend_update_property(php_http_request_class_entry
, getThis(), ZEND_STRL("options"), new_opts TSRMLS_CC
);
833 zval_ptr_dtor(&new_opts
);
834 zval_ptr_dtor(&add_opts
);
837 RETVAL_ZVAL(getThis(), 1, 0);
842 PHP_METHOD(HttpRequest
, getOptions
)
844 if (SUCCESS
== zend_parse_parameters_none()) {
845 RETURN_PROP(php_http_request_class_entry
, "options");
850 PHP_METHOD(HttpRequest
, setSslOptions
)
852 php_http_request_object_set_options_subr(INTERNAL_FUNCTION_PARAM_PASSTHRU
, ZEND_STRS("ssl"), 1, 0);
855 PHP_METHOD(HttpRequest
, addSslOptions
)
857 php_http_request_object_set_options_subr(INTERNAL_FUNCTION_PARAM_PASSTHRU
, ZEND_STRS("ssl"), 0, 0);
860 PHP_METHOD(HttpRequest
, getSslOptions
)
862 php_http_request_object_get_options_subr(INTERNAL_FUNCTION_PARAM_PASSTHRU
, ZEND_STRS("ssl"));
865 PHP_METHOD(HttpRequest
, addHeaders
)
867 php_http_request_object_set_options_subr(INTERNAL_FUNCTION_PARAM_PASSTHRU
, ZEND_STRS("headers"), 0, 1);
870 PHP_METHOD(HttpRequest
, setHeaders
)
872 php_http_request_object_set_options_subr(INTERNAL_FUNCTION_PARAM_PASSTHRU
, ZEND_STRS("headers"), 1, 1);
875 PHP_METHOD(HttpRequest
, getHeaders
)
877 php_http_request_object_get_options_subr(INTERNAL_FUNCTION_PARAM_PASSTHRU
, ZEND_STRS("headers"));
880 PHP_METHOD(HttpRequest
, setCookies
)
882 php_http_request_object_set_options_subr(INTERNAL_FUNCTION_PARAM_PASSTHRU
, ZEND_STRS("cookies"), 1, 0);
885 PHP_METHOD(HttpRequest
, addCookies
)
887 php_http_request_object_set_options_subr(INTERNAL_FUNCTION_PARAM_PASSTHRU
, ZEND_STRS("cookies"), 0, 0);
890 PHP_METHOD(HttpRequest
, getCookies
)
892 php_http_request_object_get_options_subr(INTERNAL_FUNCTION_PARAM_PASSTHRU
, ZEND_STRS("cookies"));
895 PHP_METHOD(HttpRequest
, enableCookies
)
897 if (SUCCESS
== zend_parse_parameters_none()){
898 php_http_request_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
900 php_http_request_setopt(obj
->request
, PHP_HTTP_REQUEST_OPT_COOKIES_ENABLE
, NULL
);
902 RETVAL_ZVAL(getThis(), 1, 0);
905 PHP_METHOD(HttpRequest
, resetCookies
)
907 zend_bool session_only
= 0;
909 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|b", &session_only
)) {
910 php_http_request_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
912 php_http_request_setopt(obj
->request
, PHP_HTTP_REQUEST_OPT_COOKIES_RESET_SESSION
, NULL
);
914 php_http_request_setopt(obj
->request
, PHP_HTTP_REQUEST_OPT_COOKIES_RESET
, NULL
);
917 RETVAL_ZVAL(getThis(), 1, 0);
920 PHP_METHOD(HttpRequest
, flushCookies
)
922 if (SUCCESS
== zend_parse_parameters_none()) {
923 php_http_request_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
925 php_http_request_setopt(obj
->request
, PHP_HTTP_REQUEST_OPT_COOKIES_FLUSH
, NULL
);
927 RETVAL_ZVAL(getThis(), 1, 0);
930 PHP_METHOD(HttpRequest
, setUrl
)
932 char *url_str
= NULL
;
935 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &url_str
, &url_len
)) {
936 zend_update_property_stringl(php_http_request_class_entry
, getThis(), ZEND_STRL("url"), url_str
, url_len TSRMLS_CC
);
938 RETVAL_ZVAL(getThis(), 1, 0);
941 PHP_METHOD(HttpRequest
, getUrl
)
943 if (SUCCESS
== zend_parse_parameters_none()) {
944 RETURN_PROP(php_http_request_class_entry
, "url");
949 PHP_METHOD(HttpRequest
, setMethod
)
953 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &meth
)) {
954 zend_update_property_long(php_http_request_class_entry
, getThis(), ZEND_STRL("method"), meth TSRMLS_CC
);
956 RETVAL_ZVAL(getThis(), 1, 0);
959 PHP_METHOD(HttpRequest
, getMethod
)
961 if (SUCCESS
== zend_parse_parameters_none()) {
962 RETURN_PROP(php_http_request_class_entry
, "method");
967 PHP_METHOD(HttpRequest
, setContentType
)
972 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &ctype
, &ct_len
)) {
976 PHP_HTTP_CHECK_CONTENT_TYPE(ctype
, invalid
= 1);
980 zend_update_property_stringl(php_http_request_class_entry
, getThis(), ZEND_STRL("contentType"), ctype
, ct_len TSRMLS_CC
);
983 RETVAL_ZVAL(getThis(), 1, 0);
986 PHP_METHOD(HttpRequest
, getContentType
)
988 if (SUCCESS
== zend_parse_parameters_none()) {
989 RETURN_PROP(php_http_request_class_entry
, "contentType");
994 PHP_METHOD(HttpRequest
, setQueryData
)
998 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z!", &qdata
)) {
999 if ((!qdata
) || Z_TYPE_P(qdata
) == IS_NULL
) {
1000 zend_update_property_stringl(php_http_request_class_entry
, getThis(), ZEND_STRL("queryData"), "", 0 TSRMLS_CC
);
1001 } else if ((Z_TYPE_P(qdata
) == IS_ARRAY
) || (Z_TYPE_P(qdata
) == IS_OBJECT
)) {
1002 char *query_data_str
= NULL
;
1003 size_t query_data_len
;
1005 if (SUCCESS
== php_http_url_encode_hash(HASH_OF(qdata
), NULL
, 0, &query_data_str
, &query_data_len TSRMLS_CC
)) {
1006 zend_update_property_stringl(php_http_request_class_entry
, getThis(), ZEND_STRL("queryData"), query_data_str
, query_data_len TSRMLS_CC
);
1007 efree(query_data_str
);
1010 zval
*data
= php_http_ztyp(IS_STRING
, qdata
);
1012 zend_update_property_stringl(php_http_request_class_entry
, getThis(), ZEND_STRL("queryData"), Z_STRVAL_P(data
), Z_STRLEN_P(data
) TSRMLS_CC
);
1013 zval_ptr_dtor(&data
);
1016 RETVAL_ZVAL(getThis(), 1, 0);
1019 PHP_METHOD(HttpRequest
, getQueryData
)
1021 if (SUCCESS
== zend_parse_parameters_none()) {
1022 RETURN_PROP(php_http_request_class_entry
, "queryData");
1027 PHP_METHOD(HttpRequest
, addQueryData
)
1031 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "a/", &qdata
)) {
1032 char *query_data_str
= NULL
;
1033 size_t query_data_len
= 0;
1034 zval
*old_qdata
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("queryData"), 0 TSRMLS_CC
);
1036 if (SUCCESS
== php_http_url_encode_hash(HASH_OF(qdata
), Z_STRVAL_P(old_qdata
), Z_STRLEN_P(old_qdata
), &query_data_str
, &query_data_len TSRMLS_CC
)) {
1037 zend_update_property_stringl(php_http_request_class_entry
, getThis(), ZEND_STRL("queryData"), query_data_str
, query_data_len TSRMLS_CC
);
1038 efree(query_data_str
);
1041 RETVAL_ZVAL(getThis(), 1, 0);
1045 PHP_METHOD(HttpRequest
, setBody
)
1049 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|O!", &body
, php_http_message_body_class_entry
)) {
1050 if (body
&& Z_TYPE_P(body
) != IS_NULL
) {
1051 zend_update_property(php_http_request_class_entry
, getThis(), ZEND_STRL("requestBody"), body TSRMLS_CC
);
1053 zend_update_property_null(php_http_request_class_entry
, getThis(), ZEND_STRL("requestBody") TSRMLS_CC
);
1056 RETVAL_ZVAL(getThis(), 1, 0);
1059 PHP_METHOD(HttpRequest
, addBody
)
1063 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &new_body
, php_http_message_body_class_entry
)) {
1064 zval
*old_body
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("requestBody"), 0 TSRMLS_CC
);
1066 if (Z_TYPE_P(old_body
) == IS_OBJECT
) {
1067 php_http_message_body_object_t
*old_obj
= zend_object_store_get_object(old_body TSRMLS_CC
);
1068 php_http_message_body_object_t
*new_obj
= zend_object_store_get_object(new_body TSRMLS_CC
);
1070 php_http_message_body_to_callback(old_obj
->body
, (php_http_pass_callback_t
) php_http_message_body_append
, new_obj
->body
, 0, 0);
1072 zend_update_property(php_http_request_class_entry
, getThis(), ZEND_STRL("requestBody"), new_body TSRMLS_CC
);
1075 RETVAL_ZVAL(getThis(), 1, 0);
1078 PHP_METHOD(HttpRequest
, getBody
)
1080 if (SUCCESS
== zend_parse_parameters_none()) {
1081 RETURN_PROP(php_http_request_class_entry
, "requestBody");
1086 PHP_METHOD(HttpRequest
, getResponseHeader
)
1089 char *header_name
= NULL
;
1092 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s", &header_name
, &header_len
)) {
1093 zval
*message
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("responseMessage"), 0 TSRMLS_CC
);
1095 if (Z_TYPE_P(message
) == IS_OBJECT
) {
1096 php_http_message_object_t
*msg
= zend_object_store_get_object(message TSRMLS_CC
);
1099 if ((header
= php_http_message_header(msg
->message
, header_name
, header_len
+ 1, 0))) {
1100 RETURN_ZVAL(header
, 1, 1);
1103 array_init(return_value
);
1104 zend_hash_copy(Z_ARRVAL_P(return_value
), &msg
->message
->hdrs
, (copy_ctor_func_t
) zval_add_ref
, NULL
, sizeof(zval
*));
1112 PHP_METHOD(HttpRequest
, getResponseCookies
)
1115 zval
*allowed_extras_array
= NULL
;
1117 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|la!", &flags
, &allowed_extras_array
)) {
1119 php_http_array_hashkey_t key
= php_http_array_hashkey_init(0);
1120 char **allowed_extras
= NULL
;
1121 zval
**header
= NULL
, **entry
= NULL
, *message
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("responseMessage"), 0 TSRMLS_CC
);
1122 HashPosition pos
, pos1
, pos2
;
1124 if (Z_TYPE_P(message
) == IS_OBJECT
) {
1125 php_http_message_object_t
*msg
= zend_object_store_get_object(message TSRMLS_CC
);
1127 array_init(return_value
);
1129 if (allowed_extras_array
) {
1130 allowed_extras
= ecalloc(zend_hash_num_elements(Z_ARRVAL_P(allowed_extras_array
)) + 1, sizeof(char *));
1131 FOREACH_VAL(pos
, allowed_extras_array
, entry
) {
1132 zval
*data
= php_http_ztyp(IS_STRING
, *entry
);
1133 allowed_extras
[i
++] = estrndup(Z_STRVAL_P(data
), Z_STRLEN_P(data
));
1134 zval_ptr_dtor(&data
);
1138 FOREACH_HASH_KEYVAL(pos1
, &msg
->message
->hdrs
, key
, header
) {
1139 if (key
.type
== HASH_KEY_IS_STRING
&& !strcasecmp(key
.str
, "Set-Cookie")) {
1140 php_http_cookie_list_t
*list
;
1142 if (Z_TYPE_PP(header
) == IS_ARRAY
) {
1143 zval
**single_header
;
1145 FOREACH_VAL(pos2
, *header
, single_header
) {
1146 zval
*data
= php_http_ztyp(IS_STRING
, *single_header
);
1148 if ((list
= php_http_cookie_list_parse(NULL
, Z_STRVAL_P(data
), Z_STRLEN_P(data
), flags
, allowed_extras TSRMLS_CC
))) {
1151 MAKE_STD_ZVAL(cookie
);
1152 ZVAL_OBJVAL(cookie
, php_http_cookie_object_new_ex(php_http_cookie_class_entry
, list
, NULL TSRMLS_CC
), 0);
1153 add_next_index_zval(return_value
, cookie
);
1155 zval_ptr_dtor(&data
);
1158 zval
*data
= php_http_ztyp(IS_STRING
, *header
);
1159 if ((list
= php_http_cookie_list_parse(NULL
, Z_STRVAL_P(data
), Z_STRLEN_P(data
), flags
, allowed_extras TSRMLS_CC
))) {
1162 MAKE_STD_ZVAL(cookie
);
1163 ZVAL_OBJVAL(cookie
, php_http_cookie_object_new_ex(php_http_cookie_class_entry
, list
, NULL TSRMLS_CC
), 0);
1164 add_next_index_zval(return_value
, cookie
);
1166 zval_ptr_dtor(&data
);
1171 if (allowed_extras
) {
1172 for (i
= 0; allowed_extras
[i
]; ++i
) {
1173 efree(allowed_extras
[i
]);
1175 efree(allowed_extras
);
1184 PHP_METHOD(HttpRequest
, getResponseBody
)
1186 with_error_handling(EH_THROW
, php_http_exception_class_entry
) {
1187 if (SUCCESS
== zend_parse_parameters_none()) {
1188 zval
*message
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("responseMessage"), 0 TSRMLS_CC
);
1190 if (Z_TYPE_P(message
) == IS_OBJECT
) {
1191 RETURN_OBJVAL(((php_http_message_object_t
*)zend_object_store_get_object(message TSRMLS_CC
))->body
, 1);
1193 php_http_error(HE_WARNING
, PHP_HTTP_E_RUNTIME
, "HttpRequest does not contain a response message");
1196 } end_error_handling();
1199 PHP_METHOD(HttpRequest
, getResponseCode
)
1201 if (SUCCESS
== zend_parse_parameters_none()) {
1202 RETURN_PROP(php_http_request_class_entry
, "responseCode");
1207 PHP_METHOD(HttpRequest
, getResponseStatus
)
1209 if (SUCCESS
== zend_parse_parameters_none()) {
1210 RETURN_PROP(php_http_request_class_entry
, "responseStatus");
1215 PHP_METHOD(HttpRequest
, getResponseMessage
)
1217 with_error_handling(EH_THROW
, php_http_exception_class_entry
) {
1218 if (SUCCESS
== zend_parse_parameters_none()) {
1219 zval
*message
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("responseMessage"), 0 TSRMLS_CC
);
1221 if (Z_TYPE_P(message
) == IS_OBJECT
) {
1222 RETVAL_OBJECT(message
, 1);
1224 php_http_error(HE_WARNING
, PHP_HTTP_E_RUNTIME
, "HttpRequest does not contain a response message");
1227 } end_error_handling();
1230 PHP_METHOD(HttpRequest
, getRequestMessage
)
1232 with_error_handling(EH_THROW
, php_http_exception_class_entry
) {
1233 if (SUCCESS
== zend_parse_parameters_none()) {
1234 zval
*message
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("requestMessage"), 0 TSRMLS_CC
);
1236 if (Z_TYPE_P(message
) == IS_OBJECT
) {
1237 RETVAL_OBJECT(message
, 1);
1239 php_http_error(HE_WARNING
, PHP_HTTP_E_RUNTIME
, "HttpRequest does not contain a request message");
1242 } end_error_handling();
1245 PHP_METHOD(HttpRequest
, getHistory
)
1247 with_error_handling(EH_THROW
, php_http_exception_class_entry
) {
1248 if (SUCCESS
== zend_parse_parameters_none()) {
1249 zval
*hist
= zend_read_property(php_http_request_class_entry
, getThis(), ZEND_STRL("history"), 0 TSRMLS_CC
);
1251 if (Z_TYPE_P(hist
) == IS_OBJECT
) {
1252 RETVAL_OBJECT(hist
, 1);
1254 php_http_error(HE_WARNING
, PHP_HTTP_E_RUNTIME
, "The history is empty");
1257 } end_error_handling();
1260 PHP_METHOD(HttpRequest
, clearHistory
)
1262 if (SUCCESS
== zend_parse_parameters_none()) {
1263 zend_update_property_null(php_http_request_class_entry
, getThis(), ZEND_STRL("history") TSRMLS_CC
);
1265 RETVAL_ZVAL(getThis(), 1, 0);
1268 PHP_METHOD(HttpRequest
, getMessageClass
)
1270 if (SUCCESS
== zend_parse_parameters_none()) {
1271 RETURN_PROP(php_http_request_class_entry
, "messageClass");
1276 PHP_METHOD(HttpRequest
, setMessageClass
)
1281 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &cn
, &cl
)) {
1282 zend_update_property_stringl(php_http_request_class_entry
, getThis(), ZEND_STRL("messageClass"), cn
, cl TSRMLS_CC
);
1284 RETVAL_ZVAL(getThis(), 1, 0);
1287 PHP_METHOD(HttpRequest
, send
)
1291 with_error_handling(EH_THROW
, php_http_exception_class_entry
) {
1292 if (SUCCESS
== zend_parse_parameters_none()) {
1293 php_http_request_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1294 php_http_request_method_t meth
= PHP_HTTP_NO_REQUEST_METHOD
;
1295 php_http_message_body_t
*body
= NULL
;
1298 if (SUCCESS
== php_http_request_object_requesthandler(obj
, getThis(), &meth
, &url
, &body TSRMLS_CC
)) {
1299 php_http_request_exec(obj
->request
, meth
, url
, body
);
1300 if (SUCCESS
== php_http_request_object_responsehandler(obj
, getThis() TSRMLS_CC
)) {
1301 RETVAL_PROP(php_http_request_class_entry
, "responseMessage");
1303 php_http_error(HE_WARNING
, PHP_HTTP_E_REQUEST
, "Failed to handle response");
1306 php_http_error(HE_WARNING
, PHP_HTTP_E_REQUEST
, "Failed to handle request");
1311 } end_error_handling();
1314 PHP_MINIT_FUNCTION(http_request
)
1316 PHP_HTTP_REGISTER_CLASS(http
, Request
, http_request
, php_http_object_class_entry
, 0);
1317 php_http_request_class_entry
->create_object
= php_http_request_object_new
;
1318 memcpy(&php_http_request_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
1319 php_http_request_object_handlers
.clone_obj
= php_http_request_object_clone
;
1321 zend_class_implements(php_http_request_class_entry TSRMLS_CC
, 1, spl_ce_SplSubject
);
1323 zend_declare_property_null(php_http_request_class_entry
, ZEND_STRL("observers"), ZEND_ACC_PRIVATE TSRMLS_CC
);
1324 zend_declare_property_null(php_http_request_class_entry
, ZEND_STRL("options"), ZEND_ACC_PRIVATE TSRMLS_CC
);
1325 zend_declare_property_null(php_http_request_class_entry
, ZEND_STRL("transferInfo"), ZEND_ACC_PRIVATE TSRMLS_CC
);
1326 zend_declare_property_null(php_http_request_class_entry
, ZEND_STRL("responseMessage"), ZEND_ACC_PRIVATE TSRMLS_CC
);
1327 zend_declare_property_long(php_http_request_class_entry
, ZEND_STRL("responseCode"), 0, ZEND_ACC_PRIVATE TSRMLS_CC
);
1328 zend_declare_property_string(php_http_request_class_entry
, ZEND_STRL("responseStatus"), "", ZEND_ACC_PRIVATE TSRMLS_CC
);
1329 zend_declare_property_null(php_http_request_class_entry
, ZEND_STRL("requestMessage"), ZEND_ACC_PRIVATE TSRMLS_CC
);
1330 zend_declare_property_long(php_http_request_class_entry
, ZEND_STRL("method"), PHP_HTTP_GET
, ZEND_ACC_PRIVATE TSRMLS_CC
);
1331 zend_declare_property_string(php_http_request_class_entry
, ZEND_STRL("url"), "", ZEND_ACC_PRIVATE TSRMLS_CC
);
1332 zend_declare_property_string(php_http_request_class_entry
, ZEND_STRL("contentType"), "", ZEND_ACC_PRIVATE TSRMLS_CC
);
1333 zend_declare_property_string(php_http_request_class_entry
, ZEND_STRL("requestBody"), "", ZEND_ACC_PRIVATE TSRMLS_CC
);
1334 zend_declare_property_string(php_http_request_class_entry
, ZEND_STRL("queryData"), "", ZEND_ACC_PRIVATE TSRMLS_CC
);
1335 zend_declare_property_null(php_http_request_class_entry
, ZEND_STRL("history"), ZEND_ACC_PRIVATE TSRMLS_CC
);
1336 zend_declare_property_bool(php_http_request_class_entry
, ZEND_STRL("recordHistory"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
1337 zend_declare_property_string(php_http_request_class_entry
, ZEND_STRL("messageClass"), "", ZEND_ACC_PRIVATE TSRMLS_CC
);
1347 * vim600: noet sw=4 ts=4 fdm=marker
1348 * vim<600: noet sw=4 ts=4