[prev in list] [next in list] [prev in thread] [next in thread]
List: pecl-cvs
Subject: [PECL-CVS] =?utf-8?q?svn:_/pecl/http/branches/DEV=5F2-serf/_php=5Fhttp.c_php=5Fhttp=5Fclient.c_php=5
From: Michael_Wallner <mike () php ! net>
Date: 2013-05-16 10:59:31
Message-ID: svn-mike-1368701971-330238-354129025 () svn ! php ! net
[Download RAW message or body]
mike Thu, 16 May 2013 10:59:31 +0000
Revision: http://svn.php.net/viewvc?view=revision&revision=330238
Log:
flush
Changed paths:
U pecl/http/branches/DEV_2-serf/php_http.c
U pecl/http/branches/DEV_2-serf/php_http_client.c
U pecl/http/branches/DEV_2-serf/php_http_client_serf.c
["svn-diffs-330238.txt" (text/x-diff)]
Modified: pecl/http/branches/DEV_2-serf/php_http.c
===================================================================
--- pecl/http/branches/DEV_2-serf/php_http.c 2013-05-16 02:46:58 UTC (rev 330237)
+++ pecl/http/branches/DEV_2-serf/php_http.c 2013-05-16 10:59:31 UTC (rev 330238)
@@ -174,6 +174,9 @@
|| SUCCESS != PHP_MINIT_CALL(http_curl)
|| SUCCESS != PHP_MINIT_CALL(http_client_curl)
#endif
+#if PHP_HTTP_HAVE_SERF
+ || SUCCESS != PHP_MINIT_CALL(http_client_serf)
+#endif
|| SUCCESS != PHP_MINIT_CALL(http_url)
|| SUCCESS != PHP_MINIT_CALL(http_env)
|| SUCCESS != PHP_MINIT_CALL(http_env_request)
@@ -198,6 +201,9 @@
|| SUCCESS != PHP_MSHUTDOWN_CALL(http_client_curl)
|| SUCCESS != PHP_MSHUTDOWN_CALL(http_curl)
#endif
+#if PHP_HTTP_HAVE_SERF
+ || SUCCESS != PHP_MSHUTDOWN_CALL(http_client_serf)
+#endif
|| SUCCESS != PHP_MSHUTDOWN_CALL(http_client)
) {
return FAILURE;
Modified: pecl/http/branches/DEV_2-serf/php_http_client.c
===================================================================
--- pecl/http/branches/DEV_2-serf/php_http_client.c 2013-05-16 02:46:58 UTC (rev \
330237)
+++ pecl/http/branches/DEV_2-serf/php_http_client.c 2013-05-16 10:59:31 UTC (rev \
330238) @@ -827,6 +827,7 @@
ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_notify, 0, 0, 0)
ZEND_ARG_OBJ_INFO(0, request, http\\Client\\Request, 1)
+ ZEND_ARG_INFO(0, progress)
ZEND_END_ARG_INFO();
static PHP_METHOD(HttpClient, notify)
{
Modified: pecl/http/branches/DEV_2-serf/php_http_client_serf.c
===================================================================
--- pecl/http/branches/DEV_2-serf/php_http_client_serf.c 2013-05-16 02:46:58 UTC (rev \
330237)
+++ pecl/http/branches/DEV_2-serf/php_http_client_serf.c 2013-05-16 10:59:31 UTC (rev \
330238) @@ -20,18 +20,52 @@
typedef struct php_http_client_serf {
serf_context_t *context;
apr_pool_t *pool;
+ php_http_client_t *client;
} php_http_client_serf_t;
+typedef struct php_http_client_serf_handler {
+ apr_pool_t *pool;
+ apr_uri_t *uri;
+ serf_connection_t *conn;
+ serf_request_t *req;
+ php_http_client_serf_t *serf;
+ php_resource_factory_t *rf;
+ php_http_client_enqueue_t queue;
+ struct {
+ php_http_message_parser_t *parser;
+ php_http_message_t *message;
+ php_http_buffer_t *buffer;
+ } request;
+
+ struct {
+ php_http_message_parser_t *parser;
+ php_http_message_t *message;
+ php_http_buffer_t *buffer;
+ } response;
+
+#ifdef ZTS
+ void ***ts;
+#endif
+} php_http_client_serf_handler_t;
+
+
static void php_http_serf_progress_callback(void *progress_baton, apr_off_t read, \
apr_off_t write) {
serf_progress_t not_implemented;
/* useless bullshit */
}
+#define not_implemented x;fprintf(stderr, "not implemented: %d\n",__LINE__);
+
static apr_status_t php_http_serf_connection_setup(apr_socket_t *skt, serf_bucket_t \
**read_bkt, serf_bucket_t **write_bkt, void *setup_baton, apr_pool_t *pool) {
- serf_connection_setup_t not_implmented;
+ php_http_client_serf_handler_t *serf = setup_baton;
+ serf_bucket_alloc_t *a = serf_bucket_allocator_create(serf->pool, NULL, NULL);
+
+ *read_bkt = serf_bucket_socket_create(skt, a);
+ /* TODO: handle SSL */
+
return APR_SUCCESS;
}
@@ -40,16 +74,62 @@
serf_connection_closed_t not_implemented;
}
-static serf_bucket_t *php_http_client_serf_response_acceptor(serf_request_t \
*request, serf_bucket_t *stream, void *acceptor_baton, apr_pool_t *pool) +static \
serf_bucket_t *php_http_serf_response_acceptor(serf_request_t *request, serf_bucket_t \
*stream, void *acceptor_baton, apr_pool_t *pool) {
- serf_response_acceptor_t not_implemented;
- return NULL;
+ serf_bucket_alloc_t *a = serf_request_get_alloc(request);
+ serf_bucket_t *b = serf_bucket_barrier_create(stream, a);
+
+ return serf_bucket_response_create(b, a);
}
+void errstr(apr_status_t s)
+{
+ char b[512];
+ fprintf(stderr, "serf: %d - %s, %s\n", s, serf_error_string(s), apr_strerror(s, b, \
sizeof(b))); +}
+static apr_status_t read_bkt(php_http_client_serf_handler_t *handler, serf_bucket_t \
*bkt) +{
+ apr_status_t rv;
+
+ do {
+ const char *data_str = NULL;
+ size_t data_len = 0;
+
+ rv = serf_bucket_read(bkt, SERF_READ_ALL_AVAIL, &data_str, &data_len);
+ php_http_buffer_append(handler->response.buffer, data_str, data_len);
+ fprintf(stderr, "READ: %zu, %.*s\n", data_len, data_len, data_str);
+ php_http_message_parser_parse(handler->response.parser, handler->response.buffer, \
0, &handler->response.message); + } while (APR_SUCCESS == rv);
+
+ return rv;
+}
+
static apr_status_t php_http_serf_response_handler(serf_request_t *request, \
serf_bucket_t *response, void *handler_baton, apr_pool_t *pool) {
- serf_response_handler_t not_implemented;
- return APR_SUCCESS;
+ php_http_client_serf_handler_t *handler = handler_baton;
+ apr_status_t rv;
+
+ if (!response) {
+ return APR_EOF;
+ }
+
+ rv = read_bkt(handler, serf_bucket_response_get_headers(response));
+ errstr(rv);
+
+ if (!APR_STATUS_IS_EOF(rv)) {
+ return rv;
+ }
+
+ rv = read_bkt(handler, response);
+ errstr(rv);
+
+ if (APR_STATUS_IS_EOF(rv)) {
+ php_http_client_t *context = handler->serf->client;
+
+ context->callback.response.func(context->callback.response.arg, context, \
&handler->queue, &handler->request.message, &handler->response.message); + }
+
+ return rv;
}
static apr_status_t php_http_serf_credentials_callback(char **username, char \
**password, serf_request_t *request, void *baton, int code, const char *authn_type, \
const char *realm, apr_pool_t *pool) @@ -60,7 +140,18 @@
static apr_status_t php_http_serf_request_setup(serf_request_t *request, void \
*setup_baton, serf_bucket_t **req_bkt, serf_response_acceptor_t *acceptor, void \
**acceptor_baton, serf_response_handler_t *handler, void **handler_baton, apr_pool_t \
*pool) {
- serf_request_setup_t not_implemented;
+ serf_bucket_t *body = NULL;
+ serf_bucket_alloc_t *alloc = serf_request_get_alloc(request);
+ php_http_client_serf_handler_t *serf_handler = setup_baton;
+
+ *req_bkt = serf_request_bucket_request_create(request,
+ serf_handler->queue.request->http.info.request.method,
+ serf_handler->queue.request->http.info.request.url, body, alloc);
+ *acceptor = php_http_serf_response_acceptor;
+ *acceptor_baton = setup_baton;
+ *handler = php_http_serf_response_handler;
+ *handler_baton = setup_baton;
+
return APR_SUCCESS;
}
@@ -81,11 +172,14 @@
static void *php_http_serf_context_ctor(void *opaque, void *init_arg TSRMLS_DC)
{
apr_pool_t *pool = new_pool(init_arg TSRMLS_CC);
- serf_context_t *serf = serf_context_create_ex(pool);
+ serf_context_t *serf = serf_context_create(pool);
- if (serf) {
- apr_pool_userdata_setn(serf, "serf", NULL, pool);
+ if (!serf) {
+ apr_pool_destroy(pool);
+ return NULL;
}
+
+ apr_pool_userdata_setn(serf, "serf", NULL, pool);
return pool;
}
@@ -98,40 +192,114 @@
php_http_serf_context_ctor,
NULL,
php_http_serf_context_dtor
-}
+};
struct serf_connection_init_data {
+ apr_uri_t uri;
+ apr_pool_t *pool;
+ serf_connection_t *conn;
php_http_client_t *client;
- apr_uri_t *uri;
+ php_http_client_serf_handler_t *handler;
};
-typedef struct php_http_client_serf_handler {
- serf_connection_t *conn;
- php_http_client_t *client;
-} php_http_client_serf_handler_t;
-
static void *php_http_serf_connection_ctor(void *opaque, void *init_arg TSRMLS_DC)
{
- struct serf_connection_init_data *data = init_arg;
+ struct serf_connection_init_data *data = *(struct serf_connection_init_data **) \
init_arg; php_http_client_serf_t *serf = data->client->ctx;
- serf_connection_t *conn = NULL;
- serf_connection_create2(&conn, serf->context, data->uri, \
php_http_serf_connection_setup, data->client, php_http_client_serf_connection_closed, \
data->client); + /*
+ * this all looks quite awkward, because we want the uri be allocated from the \
connection pool + */
+ if (APR_SUCCESS != serf_connection_create2(&data->conn, serf->context, data->uri, \
php_http_serf_connection_setup, data->handler, php_http_serf_connection_closed, \
data->client, data->pool)) { + return NULL;
+ }
+ apr_pool_userdata_setn(data->conn, "conn", (apr_status_t(*)(void*)) \
serf_connection_close, data->pool); + return data->pool;
}
+static void php_http_serf_connection_dtor(void *opaque, void *handle TSRMLS_DC)
+{
+ //apr_pool_destroy(handle);
+}
+
+static php_resource_factory_ops_t php_http_serf_connection_resource_factory_ops = {
+ php_http_serf_connection_ctor,
+ NULL,
+ php_http_serf_connection_dtor
+};
+
+static php_http_client_serf_handler_t \
*php_http_client_serf_handler_init(php_http_client_t *h, struct \
serf_connection_init_data *data) +{
+ php_http_client_serf_t *serf = h->ctx;
+ php_http_client_serf_handler_t *handler = NULL;
+ php_resource_factory_t *rf = NULL;
+ php_persistent_handle_factory_t *phf;
+ TSRMLS_FETCH_FROM_CTX(h->ts);
+
+ phf = php_persistent_handle_concede(NULL, ZEND_STRL("http\\Client\\Serf\\Request"), \
data->uri.hostinfo, strlen(data->uri.hostinfo), NULL, NULL TSRMLS_CC); + if (phf) {
+ rf = php_resource_factory_init(NULL, \
php_persistent_handle_get_resource_factory_ops(), phf, (void(*)(void*)) \
php_persistent_handle_abandon); + }
+
+ if (!rf) {
+ rf = php_resource_factory_init(NULL, \
&php_http_serf_connection_resource_factory_ops, NULL, NULL); + }
+
+ handler = ecalloc(1, sizeof(*handler));
+ handler->rf = rf;
+ handler->serf = serf;
+
+ handler->response.buffer = php_http_buffer_init(NULL);
+ handler->response.parser = php_http_message_parser_init(NULL TSRMLS_CC);
+ handler->response.message = php_http_message_init(NULL, 0, NULL TSRMLS_CC);
+
+ TSRMLS_SET_CTX(handler->ts);
+
+ data->handler = handler;
+ if (!(handler->pool = php_resource_factory_handle_ctor(rf, &data TSRMLS_CC))) {
+ /* TODO: cleanup */
+ return NULL;
+ }
+
+ apr_pool_userdata_get((void *) &handler->conn, "conn", handler->pool);
+
+ if (!handler->conn) {
+ /* TODO: cleanup */
+ return NULL;
+ }
+
+ return handler;
+
+}
+
+static void php_http_client_serf_handler_dtor(php_http_client_serf_handler_t \
*handler) +{
+ TSRMLS_FETCH_FROM_CTX(handler->ts);
+
+ php_resource_factory_handle_dtor(handler->rf, handler->pool TSRMLS_CC);
+ php_resource_factory_free(&handler->rf);
+
+ php_http_buffer_free(&handler->response.buffer);
+ php_http_message_free(&handler->response.message);
+ php_http_message_parser_free(&handler->response.parser);
+
+ efree(handler);
+}
+
static php_http_client_t *php_http_client_serf_init(php_http_client_t *h, void \
*pool) {
php_http_client_serf_t *serf;
TSRMLS_FETCH_FROM_CTX(h->ts);
- if (!pool && !(pool = php_resource_factory_handle_ctor(h->rf, NULL) TSRMLS_CC)) {
+ if (!pool && !(pool = php_resource_factory_handle_ctor(h->rf, NULL TSRMLS_CC))) {
php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_POOL, "Failed to initialize serf \
context"); return NULL;
}
serf = ecalloc(1, sizeof(*serf));
+ serf->client = h;
serf->pool = pool;
- apr_pool_userdata_get(&serf->context, "serf", serf->pool);
+ apr_pool_userdata_get((void *) &serf->context, "serf", serf->pool);
serf_context_set_progress_cb(serf->context, php_http_serf_progress_callback, h);
h->ctx = serf;
@@ -148,50 +316,112 @@
efree(serf);
h->ctx = NULL;
}
-static void php_http_client_serf_reset(php_http_client_t *h);
-static STATUS php_http_client_serf_exec(php_http_client_t *h);
-static int php_http_client_serf_once(php_http_client_t *h);
-static STATUS php_http_client_serf_wait(php_http_client_t *h, struct timeval \
*custom_timeout);
+static void php_http_client_serf_reset(php_http_client_t *h)
+{
-static php_resource_factory_t *create_rf(const char *url TSRMLS_DC)
+}
+
+static STATUS php_http_client_serf_exec(php_http_client_t *h)
{
- php_url *purl;
- php_resource_factory_t *rf = NULL;
+ php_http_client_serf_t *serf = h->ctx;
+ apr_status_t rc;
- if ((purl = php_url_parse(url))) {
- char *id_str = NULL;
- size_t id_len = spprintf(&id_str, 0, "%s:%d", STR_PTR(purl->host), purl->port ? \
purl->port : 80);
- php_persistent_handle_factory_t *pf = php_persistent_handle_concede(NULL, \
ZEND_STRL("http\\Client\\Serf\\Request"), id_str, id_len, NULL, NULL TSRMLS_CC); + do \
{ + rc = serf_context_run(serf->context, SERF_DURATION_FOREVER, serf->pool);
+ } while (rc == APR_SUCCESS);
- if (pf) {
- rf = php_resource_factory_init(NULL, \
php_persistent_handle_get_resource_factory_ops(), pf, (void (*)(void*)) \
php_persistent_handle_abandon);
- }
+ errstr(rc);
- php_url_free(purl);
- efree(id_str);
- }
+ return SUCCESS;
+}
- if (!rf) {
- rf = php_resource_factory_init(NULL, \
&php_http_serf_connection_resource_factory_ops, NULL, NULL); +static int \
php_http_client_serf_once(php_http_client_t *h) +{
+ return 0;
+}
+
+static STATUS php_http_client_serf_wait(php_http_client_t *h, struct timeval \
*custom_timeout) +{
+ return FAILURE;
+}
+
+
+static void queue_dtor(php_http_client_enqueue_t *e)
+{
+ php_http_client_serf_handler_t *handler = e->opaque;
+
+ if (handler->queue.dtor) {
+ e->opaque = handler->queue.opaque;
+ handler->queue.dtor(e);
}
+ php_http_client_serf_handler_dtor(handler);
+}
- return rf;
+static STATUS php_http_client_serf_handler_prepare(php_http_client_serf_handler_t \
*handler, struct serf_connection_init_data *data) +{
+ handler->req = serf_connection_request_create(handler->conn, \
php_http_serf_request_setup, handler); +
+ return SUCCESS;
}
static STATUS php_http_client_serf_enqueue(php_http_client_t *h, \
php_http_client_enqueue_t *enqueue) {
apr_pool_t *pool;
php_http_client_serf_t *serf = h->ctx;
+ struct serf_connection_init_data data;
+ php_http_client_serf_handler_t *handler;
+ php_resource_factory_t *rf = NULL;
TSRMLS_FETCH_FROM_CTX(h->ts);
- pool = new_pool(serf->pool);
+ data.client = h;
+ data.pool = new_pool(serf->pool TSRMLS_CC);
+ if (APR_SUCCESS != apr_uri_parse(data.pool, \
enqueue->request->http.info.request.url, &data.uri)) { \
+ apr_pool_destroy(data.pool); + php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT, \
"Failed to parse URI '%s'", enqueue->request->http.info.request.url); + return \
FAILURE; + }
+
+ handler = php_http_client_serf_handler_init(h, &data);
+ if (!handler) {
+ return FAILURE;
+ }
+
+ handler->queue = *enqueue;
+ enqueue->opaque = handler;
+ enqueue->dtor = queue_dtor;
+
+ if (SUCCESS != php_http_client_serf_handler_prepare(handler, &data)) {
+ php_http_client_serf_handler_dtor(handler);
+ return FAILURE;
+ }
+
zend_llist_add_element(&h->requests, enqueue);
+
+ return SUCCESS;
}
-static STATUS php_http_client_serf_dequeue(php_http_client_t *h, \
php_http_client_enqueue_t *enqueue);
-static STATUS php_http_client_serf_setopt(php_http_client_t *h, \
php_http_client_setopt_opt_t opt, void *arg);
-static STATUS php_http_client_serf_getopt(php_http_client_t *h, \
php_http_client_getopt_opt_t opt, void *arg, void **res);
+static int compare_queue(php_http_client_enqueue_t *e, void *ep)
+{
+ return e->request == ((php_http_client_enqueue_t *) ep)->request;
+}
+
+static STATUS php_http_client_serf_dequeue(php_http_client_t *h, \
php_http_client_enqueue_t *enqueue) +{
+ zend_llist_del_element(&h->requests, enqueue, (int(*)(void*,void*)) compare_queue);
+ return SUCCESS;
+}
+
+static STATUS php_http_client_serf_setopt(php_http_client_t *h, \
php_http_client_setopt_opt_t opt, void *arg) +{
+ return FAILURE;
+}
+
+static STATUS php_http_client_serf_getopt(php_http_client_t *h, \
php_http_client_getopt_opt_t opt, void *arg, void **res) +{
+ return FAILURE;
+}
+
static php_http_client_ops_t php_http_client_serf_ops = {
&php_http_serf_context_resource_factory_ops,
php_http_client_serf_init,
@@ -217,13 +447,16 @@
if (SUCCESS != php_http_client_driver_add(&driver)) {
return FAILURE;
}
+ if (APR_SUCCESS != apr_initialize()) {
+ return FAILURE;
+ }
if (APR_SUCCESS != apr_pool_create(&PHP_HTTP_G->serf.pool, NULL)) {
return FAILURE;
}
- if (SUCCESS != php_persistent_handle_provide(ZEND_STRL("http\\Client\\Curl"), \
&php_http_serf_context_resource_factory_ops, NULL, NULL TSRMLS_CC)) { + if (SUCCESS \
!= php_persistent_handle_provide(ZEND_STRL("http\\Client\\Serf"), \
&php_http_serf_context_resource_factory_ops, NULL, NULL TSRMLS_CC)) { return \
FAILURE; }
- if (SUCCESS != php_persistent_handle_provide(ZEND_STRL("http\\Client\\Curl\\Request"), \
&php_http_serf_connection_resource_factory_ops, NULL, NULL TSRMLS_CC)) { + if \
(SUCCESS != php_persistent_handle_provide(ZEND_STRL("http\\Client\\Serf\\Request"), \
&php_http_serf_connection_resource_factory_ops, NULL, NULL TSRMLS_CC)) { return \
FAILURE; }
@@ -235,6 +468,7 @@
{
apr_pool_destroy(PHP_HTTP_G->serf.pool);
PHP_HTTP_G->serf.pool = NULL;
+ apr_terminate();
return SUCCESS;
}
#endif
--
PECL CVS Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic