2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.0 of the PHP license, that |
6 | is bundled with this package in the file LICENSE, and is available |
7 | through the world-wide-web at http://www.php.net/license/3_0.txt. |
8 | If you did not receive a copy of the PHP license and are unable to |
9 | obtain it through the world-wide-web, please send a note to |
10 | license@php.net so we can mail you a copy immediately. |
11 +----------------------------------------------------------------------+
12 | Copyright (c) 2004-2005 Michael Wallner <mike@php.net> |
13 +----------------------------------------------------------------------+
24 #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
26 #include "php_http_std_defs.h"
27 #include "php_http_requestpool_object.h"
28 #include "php_http_request_pool_api.h"
29 #include "php_http_request_object.h"
30 #include "php_http_exception_object.h"
33 # include <winsock2.h>
35 #include <curl/curl.h>
37 #define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpRequestPool, method, 0, req_args)
38 #define HTTP_EMPTY_ARGS(method, ret_ref) HTTP_EMPTY_ARGS_EX(HttpRequestPool, method, ret_ref)
39 #define HTTP_REQPOOL_ME(method, visibility) PHP_ME(HttpRequestPool, method, HTTP_ARGS(HttpRequestPool, method), visibility)
41 HTTP_BEGIN_ARGS_AR(HttpRequestPool
, __construct
, 0, 0)
42 HTTP_ARG_OBJ(HttpRequest
, request0
, 0)
43 HTTP_ARG_OBJ(HttpRequest
, request1
, 0)
44 HTTP_ARG_OBJ(HttpRequest
, requestN
, 0)
47 HTTP_EMPTY_ARGS(__destruct
, 0);
48 HTTP_EMPTY_ARGS(reset
, 0);
50 HTTP_BEGIN_ARGS(attach
, 1)
51 HTTP_ARG_OBJ(HttpRequest
, request
, 0)
54 HTTP_BEGIN_ARGS(detach
, 1)
55 HTTP_ARG_OBJ(HttpRequest
, request
, 0)
58 HTTP_EMPTY_ARGS(send
, 0);
59 HTTP_EMPTY_ARGS(socketSend
, 0);
60 HTTP_EMPTY_ARGS(socketSelect
, 0);
61 HTTP_EMPTY_ARGS(socketRead
, 0);
64 #define http_requestpool_object_declare_default_properties() _http_requestpool_object_declare_default_properties(TSRMLS_C)
65 static inline void _http_requestpool_object_declare_default_properties(TSRMLS_D
);
67 zend_class_entry
*http_requestpool_object_ce
;
68 zend_function_entry http_requestpool_object_fe
[] = {
69 HTTP_REQPOOL_ME(__construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
70 HTTP_REQPOOL_ME(__destruct
, ZEND_ACC_PUBLIC
|ZEND_ACC_DTOR
)
71 HTTP_REQPOOL_ME(attach
, ZEND_ACC_PUBLIC
)
72 HTTP_REQPOOL_ME(detach
, ZEND_ACC_PUBLIC
)
73 HTTP_REQPOOL_ME(send
, ZEND_ACC_PUBLIC
)
74 HTTP_REQPOOL_ME(reset
, ZEND_ACC_PUBLIC
)
76 HTTP_REQPOOL_ME(socketSend
, ZEND_ACC_PROTECTED
)
77 HTTP_REQPOOL_ME(socketSelect
, ZEND_ACC_PROTECTED
)
78 HTTP_REQPOOL_ME(socketRead
, ZEND_ACC_PROTECTED
)
82 static zend_object_handlers http_requestpool_object_handlers
;
84 void _http_requestpool_object_init(INIT_FUNC_ARGS
)
86 HTTP_REGISTER_CLASS_EX(HttpRequestPool
, http_requestpool_object
, NULL
, 0);
89 zend_object_value
_http_requestpool_object_new(zend_class_entry
*ce TSRMLS_DC
)
92 http_requestpool_object
*o
;
94 o
= ecalloc(1, sizeof(http_requestpool_object
));
97 http_request_pool_init(&o
->pool
);
99 ALLOC_HASHTABLE(OBJ_PROP(o
));
100 zend_hash_init(OBJ_PROP(o
), 0, NULL
, ZVAL_PTR_DTOR
, 0);
101 zend_hash_copy(OBJ_PROP(o
), &ce
->default_properties
, (copy_ctor_func_t
) zval_add_ref
, NULL
, sizeof(zval
*));
103 ov
.handle
= zend_objects_store_put(o
, (zend_objects_store_dtor_t
) zend_objects_destroy_object
, http_requestpool_object_free
, NULL TSRMLS_CC
);
104 ov
.handlers
= &http_requestpool_object_handlers
;
109 static inline void _http_requestpool_object_declare_default_properties(TSRMLS_D
)
111 zend_class_entry
*ce
= http_requestpool_object_ce
;
113 DCL_PROP_N(PROTECTED
, pool
);
116 void _http_requestpool_object_free(zend_object
*object TSRMLS_DC
)
118 http_requestpool_object
*o
= (http_requestpool_object
*) object
;
121 zend_hash_destroy(OBJ_PROP(o
));
122 FREE_HASHTABLE(OBJ_PROP(o
));
124 http_request_pool_dtor(&o
->pool
);
128 /* ### USERLAND ### */
130 /* {{{ proto void HttpRequestPool::__construct([HttpRequest request[, ...]])
132 * Instantiate a new HttpRequestPool object. An HttpRequestPool is
133 * able to send several HttpRequests in parallel.
138 * $urls = array('www.php.net', 'pecl.php.net', 'pear.php.net')
139 * $pool = new HttpRequestPool;
140 * foreach ($urls as $url) {
141 * $req[$url] = new HttpRequest("http://$url", HTTP_HEAD);
142 * $pool->attach($req[$url]);
145 * foreach ($urls as $url) {
146 * printf("%s (%s) is %s\n",
147 * $url, $req[$url]->getResponseInfo('effective_url'),
148 * $r->getResponseCode() == 200 ? 'alive' : 'not alive'
154 PHP_METHOD(HttpRequestPool
, __construct
)
156 int argc
= ZEND_NUM_ARGS();
157 zval
***argv
= safe_emalloc(argc
, sizeof(zval
*), 0);
158 getObject(http_requestpool_object
, obj
);
160 if (SUCCESS
== zend_get_parameters_array_ex(argc
, argv
)) {
163 for (i
= 0; i
< argc
; ++i
) {
164 if (Z_TYPE_PP(argv
[i
]) == IS_OBJECT
&& instanceof_function(Z_OBJCE_PP(argv
[i
]), http_request_object_ce TSRMLS_CC
)) {
165 http_request_pool_attach(&obj
->pool
, *(argv
[i
]));
173 /* {{{ proto void HttpRequestPool::__destruct()
175 * Clean up HttpRequestPool object.
177 PHP_METHOD(HttpRequestPool
, __destruct
)
179 getObject(http_requestpool_object
, obj
);
183 http_request_pool_detach_all(&obj
->pool
);
187 /* {{{ proto void HttpRequestPool::reset()
189 * Detach all attached HttpRequest objects.
191 PHP_METHOD(HttpRequestPool
, reset
)
193 getObject(http_requestpool_object
, obj
);
197 http_request_pool_detach_all(&obj
->pool
);
200 /* {{{ proto bool HttpRequestPool::attach(HttpRequest request)
202 * Attach an HttpRequest object to this HttpRequestPool.
203 * NOTE: set all options prior attaching!
205 PHP_METHOD(HttpRequestPool
, attach
)
208 STATUS status
= FAILURE
;
209 getObject(http_requestpool_object
, obj
);
212 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &request
, http_request_object_ce
)) {
213 status
= http_request_pool_attach(&obj
->pool
, request
);
216 RETURN_SUCCESS(status
);
220 /* {{{ proto bool HttpRequestPool::detach(HttpRequest request)
222 * Detach an HttpRequest object from this HttpRequestPool.
224 PHP_METHOD(HttpRequestPool
, detach
)
227 STATUS status
= FAILURE
;
228 getObject(http_requestpool_object
, obj
);
231 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &request
, http_request_object_ce
)) {
232 status
= http_request_pool_detach(&obj
->pool
, request
);
235 RETURN_SUCCESS(status
);
239 /* {{{ proto bool HttpRequestPool::send()
241 * Send all attached HttpRequest objects in parallel.
243 PHP_METHOD(HttpRequestPool
, send
)
246 getObject(http_requestpool_object
, obj
);
251 status
= http_request_pool_send(&obj
->pool
);
254 RETURN_SUCCESS(status
);
258 /* {{{ proto protected bool HttpRequestPool::socketSend()
263 * while ($pool->socketSend()) {
264 * do_something_else();
265 * if (!$pool->socketSelect()) {
266 * die('Socket error');
269 * $pool->socketRead();
273 PHP_METHOD(HttpRequestPool
, socketSend
)
275 getObject(http_requestpool_object
, obj
);
279 RETURN_BOOL(0 < http_request_pool_perform(&obj
->pool
));
283 /* {{{ proto protected bool HttpRequestPool::socketSelect()
285 * See HttpRequestPool::socketSend().
287 PHP_METHOD(HttpRequestPool
, socketSelect
)
289 getObject(http_requestpool_object
, obj
);
293 RETURN_SUCCESS(http_request_pool_select(&obj
->pool
));
297 /* {{{ proto protected void HttpRequestPool::socketRead()
299 * See HttpRequestPool::socketSend().
301 PHP_METHOD(HttpRequestPool
, socketRead
)
303 getObject(http_requestpool_object
, obj
);
307 zend_llist_apply(&obj
->pool
.handles
, (llist_apply_func_t
) http_request_pool_responsehandler TSRMLS_CC
);
311 #endif /* ZEND_ENGINE_2 && HTTP_HAVE_CURL */
318 * vim600: noet sw=4 ts=4 fdm=marker
319 * vim<600: noet sw=4 ts=4