LTP GCOV extension - code coverage report
Current view: directory - ext/http - http_requestpool_object.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 140
Code covered: 84.3 % Executed lines: 118
Legend: not executed executed

       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-2007, Michael Wallner <mike@php.net>            |
      10                 :     +--------------------------------------------------------------------+
      11                 : */
      12                 : 
      13                 : /* $Id: http_requestpool_object.c,v 1.49 2007/02/07 11:50:27 mike Exp $ */
      14                 : 
      15                 : #define HTTP_WANT_CURL
      16                 : #include "php_http.h"
      17                 : 
      18                 : #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
      19                 : 
      20                 : #include "zend_interfaces.h"
      21                 : 
      22                 : #include "php_http_api.h"
      23                 : #include "php_http_exception_object.h"
      24                 : #include "php_http_request_api.h"
      25                 : #include "php_http_request_object.h"
      26                 : #include "php_http_request_pool_api.h"
      27                 : #include "php_http_requestpool_object.h"
      28                 : 
      29                 : #if defined(HAVE_SPL) && !defined(WONKY)
      30                 : /* SPL doesn't install its headers */
      31                 : extern PHPAPI zend_class_entry *spl_ce_Countable;
      32                 : #endif
      33                 : 
      34                 : #define HTTP_BEGIN_ARGS(method, req_args)       HTTP_BEGIN_ARGS_EX(HttpRequestPool, method, 0, req_args)
      35                 : #define HTTP_EMPTY_ARGS(method)                         HTTP_EMPTY_ARGS_EX(HttpRequestPool, method, 0)
      36                 : #define HTTP_REQPOOL_ME(method, visibility)     PHP_ME(HttpRequestPool, method, HTTP_ARGS(HttpRequestPool, method), visibility)
      37                 : 
      38                 : HTTP_EMPTY_ARGS(__construct);
      39                 : 
      40                 : HTTP_EMPTY_ARGS(__destruct);
      41                 : HTTP_EMPTY_ARGS(reset);
      42                 : 
      43                 : HTTP_BEGIN_ARGS(attach, 1)
      44                 :         HTTP_ARG_OBJ(HttpRequest, request, 0)
      45                 : HTTP_END_ARGS;
      46                 : 
      47                 : HTTP_BEGIN_ARGS(detach, 1)
      48                 :         HTTP_ARG_OBJ(HttpRequest, request, 0)
      49                 : HTTP_END_ARGS;
      50                 : 
      51                 : HTTP_EMPTY_ARGS(send);
      52                 : HTTP_EMPTY_ARGS(socketPerform);
      53                 : HTTP_EMPTY_ARGS(socketSelect);
      54                 : 
      55                 : HTTP_EMPTY_ARGS(valid);
      56                 : HTTP_EMPTY_ARGS(current);
      57                 : HTTP_EMPTY_ARGS(key);
      58                 : HTTP_EMPTY_ARGS(next);
      59                 : HTTP_EMPTY_ARGS(rewind);
      60                 : 
      61                 : HTTP_EMPTY_ARGS(count);
      62                 : 
      63                 : HTTP_EMPTY_ARGS(getAttachedRequests);
      64                 : HTTP_EMPTY_ARGS(getFinishedRequests);
      65                 : 
      66                 : HTTP_BEGIN_ARGS(enablePipelining, 0)
      67                 :         HTTP_ARG_VAL(enable, 0)
      68                 : HTTP_END_ARGS;
      69                 : 
      70                 : zend_class_entry *http_requestpool_object_ce;
      71                 : zend_function_entry http_requestpool_object_fe[] = {
      72                 :         HTTP_REQPOOL_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
      73                 :         HTTP_REQPOOL_ME(__destruct, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
      74                 :         HTTP_REQPOOL_ME(attach, ZEND_ACC_PUBLIC)
      75                 :         HTTP_REQPOOL_ME(detach, ZEND_ACC_PUBLIC)
      76                 :         HTTP_REQPOOL_ME(send, ZEND_ACC_PUBLIC)
      77                 :         HTTP_REQPOOL_ME(reset, ZEND_ACC_PUBLIC)
      78                 : 
      79                 :         HTTP_REQPOOL_ME(socketPerform, ZEND_ACC_PROTECTED)
      80                 :         HTTP_REQPOOL_ME(socketSelect, ZEND_ACC_PROTECTED)
      81                 : 
      82                 :         /* implements Iterator */
      83                 :         HTTP_REQPOOL_ME(valid, ZEND_ACC_PUBLIC)
      84                 :         HTTP_REQPOOL_ME(current, ZEND_ACC_PUBLIC)
      85                 :         HTTP_REQPOOL_ME(key, ZEND_ACC_PUBLIC)
      86                 :         HTTP_REQPOOL_ME(next, ZEND_ACC_PUBLIC)
      87                 :         HTTP_REQPOOL_ME(rewind, ZEND_ACC_PUBLIC)
      88                 :         
      89                 :         /* implmenents Countable */
      90                 :         HTTP_REQPOOL_ME(count, ZEND_ACC_PUBLIC)
      91                 :         
      92                 :         HTTP_REQPOOL_ME(getAttachedRequests, ZEND_ACC_PUBLIC)
      93                 :         HTTP_REQPOOL_ME(getFinishedRequests, ZEND_ACC_PUBLIC)
      94                 :         
      95                 :         HTTP_REQPOOL_ME(enablePipelining, ZEND_ACC_PUBLIC)
      96                 : 
      97                 :         EMPTY_FUNCTION_ENTRY
      98                 : };
      99                 : static zend_object_handlers http_requestpool_object_handlers;
     100                 : 
     101                 : PHP_MINIT_FUNCTION(http_requestpool_object)
     102             220 : {
     103             220 :         HTTP_REGISTER_CLASS_EX(HttpRequestPool, http_requestpool_object, NULL, 0);
     104             220 :         http_requestpool_object_handlers.clone_obj = NULL;
     105                 :         
     106                 : #if defined(HAVE_SPL) && !defined(WONKY)
     107             220 :         zend_class_implements(http_requestpool_object_ce TSRMLS_CC, 2, spl_ce_Countable, zend_ce_iterator);
     108                 : #else
     109                 :         zend_class_implements(http_requestpool_object_ce TSRMLS_CC, 1, zend_ce_iterator);
     110                 : #endif
     111                 :         
     112             220 :         return SUCCESS;
     113                 : }
     114                 : 
     115                 : zend_object_value _http_requestpool_object_new(zend_class_entry *ce TSRMLS_DC)
     116               7 : {
     117                 :         zend_object_value ov;
     118                 :         http_requestpool_object *o;
     119                 : 
     120               7 :         o = ecalloc(1, sizeof(http_requestpool_object));
     121               7 :         o->zo.ce = ce;
     122                 : 
     123               7 :         http_request_pool_init(&o->pool);
     124                 : 
     125               7 :         ALLOC_HASHTABLE(OBJ_PROP(o));
     126               7 :         zend_hash_init(OBJ_PROP(o), zend_hash_num_elements(&ce->default_properties), NULL, ZVAL_PTR_DTOR, 0);
     127               7 :         zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
     128                 : 
     129               7 :         ov.handle = putObject(http_requestpool_object, o);
     130               7 :         ov.handlers = &http_requestpool_object_handlers;
     131                 : 
     132               7 :         return ov;
     133                 : }
     134                 : 
     135                 : void _http_requestpool_object_free(zend_object *object TSRMLS_DC)
     136               7 : {
     137               7 :         http_requestpool_object *o = (http_requestpool_object *) object;
     138                 : 
     139               7 :         http_request_pool_dtor(&o->pool);
     140               7 :         freeObject(o);
     141               7 : }
     142                 : 
     143                 : #define http_requestpool_object_llist2array _http_requestpool_object_llist2array
     144                 : static void _http_requestpool_object_llist2array(zval **req, zval *array TSRMLS_DC)
     145              52 : {
     146              52 :         ZVAL_ADDREF(*req);
     147              52 :         add_next_index_zval(array, *req);
     148              52 : }
     149                 : 
     150                 : /* ### USERLAND ### */
     151                 : 
     152                 : /* {{{ proto void HttpRequestPool::__construct([HttpRequest request[, ...]])
     153                 :         Creates a new HttpRequestPool object instance. */
     154                 : PHP_METHOD(HttpRequestPool, __construct)
     155               6 : {
     156               6 :         int argc = ZEND_NUM_ARGS();
     157               6 :         zval ***argv = safe_emalloc(argc, sizeof(zval *), 0);
     158               6 :         getObject(http_requestpool_object, obj);
     159                 : 
     160               6 :         SET_EH_THROW_HTTP();
     161               6 :         if (SUCCESS == zend_get_parameters_array_ex(argc, argv)) {
     162                 :                 int i;
     163                 : 
     164              19 :                 for (i = 0; i < argc; ++i) {
     165              13 :                         if (Z_TYPE_PP(argv[i]) == IS_OBJECT && instanceof_function(Z_OBJCE_PP(argv[i]), http_request_object_ce TSRMLS_CC)) {
     166              13 :                                 http_request_pool_attach(&obj->pool, *(argv[i]));
     167                 :                         }
     168                 :                 }
     169                 :         }
     170               6 :         efree(argv);
     171               6 :         SET_EH_NORMAL();
     172               6 :         http_final(HTTP_EX_CE(request_pool));
     173               6 : }
     174                 : /* }}} */
     175                 : 
     176                 : /* {{{ proto void HttpRequestPool::__destruct()
     177                 :         Clean up HttpRequestPool object. */
     178                 : PHP_METHOD(HttpRequestPool, __destruct)
     179               7 : {
     180               7 :         getObject(http_requestpool_object, obj);
     181                 : 
     182               7 :         NO_ARGS;
     183                 : 
     184               7 :         http_request_pool_detach_all(&obj->pool);
     185               7 : }
     186                 : /* }}} */
     187                 : 
     188                 : /* {{{ proto void HttpRequestPool::reset()
     189                 :         Detach all attached HttpRequest objects. */
     190                 : PHP_METHOD(HttpRequestPool, reset)
     191               0 : {
     192               0 :         getObject(http_requestpool_object, obj);
     193                 : 
     194               0 :         NO_ARGS;
     195                 :         
     196               0 :         obj->iterator.pos = 0;
     197               0 :         http_request_pool_detach_all(&obj->pool);
     198               0 : }
     199                 : 
     200                 : /* {{{ proto bool HttpRequestPool::attach(HttpRequest request)
     201                 :         Attach an HttpRequest object to this HttpRequestPool. WARNING: set all options prior attaching! */
     202                 : PHP_METHOD(HttpRequestPool, attach)
     203              54 : {
     204                 :         zval *request;
     205              54 :         STATUS status = FAILURE;
     206              54 :         getObject(http_requestpool_object, obj);
     207                 : 
     208              54 :         SET_EH_THROW_HTTP();
     209              54 :         if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, http_request_object_ce)) {
     210              58 :                 if (obj->iterator.pos > 0 && obj->iterator.pos < zend_llist_count(&obj->pool.handles)) {
     211               4 :                         http_error(HE_THROW, HTTP_E_REQUEST_POOL, "Cannot attach to the HttpRequestPool while the iterator is active");
     212                 :                 } else {
     213              50 :                         status = http_request_pool_attach(&obj->pool, request);
     214                 :                 }
     215                 :         }
     216              54 :         SET_EH_NORMAL();
     217              54 :         RETURN_SUCCESS(status);
     218                 : }
     219                 : /* }}} */
     220                 : 
     221                 : /* {{{ proto bool HttpRequestPool::detach(HttpRequest request)
     222                 :         Detach an HttpRequest object from this HttpRequestPool. */
     223                 : PHP_METHOD(HttpRequestPool, detach)
     224              61 : {
     225                 :         zval *request;
     226              61 :         STATUS status = FAILURE;
     227              61 :         getObject(http_requestpool_object, obj);
     228                 : 
     229              61 :         SET_EH_THROW_HTTP();
     230              61 :         if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, http_request_object_ce)) {
     231              61 :                 obj->iterator.pos = -1;
     232              61 :                 status = http_request_pool_detach(&obj->pool, request);
     233                 :         }
     234              61 :         SET_EH_NORMAL();
     235              61 :         RETURN_SUCCESS(status);
     236                 : }
     237                 : /* }}} */
     238                 : 
     239                 : /* {{{ proto bool HttpRequestPool::send()
     240                 :         Send all attached HttpRequest objects in parallel. */
     241                 : PHP_METHOD(HttpRequestPool, send)
     242               4 : {
     243                 :         STATUS status;
     244               4 :         getObject(http_requestpool_object, obj);
     245                 : 
     246               4 :         NO_ARGS;
     247                 : 
     248               4 :         SET_EH_THROW_HTTP();
     249               4 :         status = http_request_pool_send(&obj->pool);
     250               4 :         SET_EH_NORMAL();
     251                 :         
     252                 :         /* rethrow as HttpRequestPoolException */
     253               4 :         http_final(HTTP_EX_CE(request_pool));
     254                 : 
     255               4 :         RETURN_SUCCESS(status);
     256                 : }
     257                 : /* }}} */
     258                 : 
     259                 : /* {{{ proto protected bool HttpRequestPool::socketPerform()
     260                 :         Returns TRUE until each request has finished its transaction. */
     261                 : PHP_METHOD(HttpRequestPool, socketPerform)
     262             250 : {
     263             250 :         getObject(http_requestpool_object, obj);
     264                 : 
     265             250 :         NO_ARGS;
     266                 : 
     267             250 :         if (0 < http_request_pool_perform(&obj->pool)) {
     268             248 :                 RETURN_TRUE;
     269                 :         } else {
     270               2 :                 RETURN_FALSE;
     271                 :         }
     272                 : }
     273                 : /* }}} */
     274                 : 
     275                 : /* {{{ proto protected bool HttpRequestPool::socketSelect() */
     276                 : PHP_METHOD(HttpRequestPool, socketSelect)
     277             248 : {
     278             248 :         getObject(http_requestpool_object, obj);
     279                 : 
     280             248 :         NO_ARGS;
     281                 : 
     282             248 :         RETURN_SUCCESS(http_request_pool_select(&obj->pool));
     283                 : }
     284                 : /* }}} */
     285                 : 
     286                 : /* {{{ proto bool HttpRequestPool::valid()
     287                 :         Implements Iterator::valid(). */
     288                 : PHP_METHOD(HttpRequestPool, valid)
     289              17 : {
     290              17 :         NO_ARGS;
     291                 : 
     292              17 :         if (return_value_used) {
     293              17 :                 getObject(http_requestpool_object, obj);
     294              17 :                 RETURN_BOOL(obj->iterator.pos >= 0 && obj->iterator.pos < zend_llist_count(&obj->pool.handles));
     295                 :         }
     296                 : }
     297                 : /* }}} */
     298                 : 
     299                 : /* {{{ proto HttpRequest HttpRequestPool::current()
     300                 :         Implements Iterator::current(). */
     301                 : PHP_METHOD(HttpRequestPool, current)
     302              14 : {
     303              14 :         NO_ARGS;
     304                 : 
     305              14 :         if (return_value_used) {
     306              14 :                 long pos = 0;
     307              14 :                 zval **current = NULL;
     308                 :                 zend_llist_position lpos;
     309              14 :                 getObject(http_requestpool_object, obj);
     310                 : 
     311              14 :                 if (obj->iterator.pos < zend_llist_count(&obj->pool.handles)) {
     312              14 :                         for (   current = zend_llist_get_first_ex(&obj->pool.handles, &lpos);
     313              44 :                                         current && obj->iterator.pos != pos++;
     314              16 :                                         current = zend_llist_get_next_ex(&obj->pool.handles, &lpos));
     315              14 :                         if (current) {
     316              14 :                                 RETURN_OBJECT(*current, 1);
     317                 :                         }
     318                 :                 }
     319               0 :                 RETURN_NULL();
     320                 :         }
     321                 : }
     322                 : /* }}} */
     323                 : 
     324                 : /* {{{ proto int HttpRequestPool::key()
     325                 :         Implements Iterator::key(). */
     326                 : PHP_METHOD(HttpRequestPool, key)
     327               0 : {
     328               0 :         NO_ARGS;
     329                 : 
     330               0 :         if (return_value_used) {
     331               0 :                 getObject(http_requestpool_object, obj);
     332               0 :                 RETURN_LONG(obj->iterator.pos);
     333                 :         }
     334                 : }
     335                 : /* }}} */
     336                 : 
     337                 : /* {{{ proto void HttpRequestPool::next()
     338                 :         Implements Iterator::next(). */
     339                 : PHP_METHOD(HttpRequestPool, next)
     340              14 : {
     341              14 :         NO_ARGS {
     342              14 :                 getObject(http_requestpool_object, obj);
     343              14 :                 ++(obj->iterator.pos);
     344                 :         }
     345              14 : }
     346                 : /* }}} */
     347                 : 
     348                 : /* {{{ proto void HttpRequestPool::rewind()
     349                 :         Implements Iterator::rewind(). */
     350                 : PHP_METHOD(HttpRequestPool, rewind)
     351               3 : {
     352               3 :         NO_ARGS {
     353               3 :                 getObject(http_requestpool_object, obj);
     354               3 :                 obj->iterator.pos = 0;
     355                 :         }
     356               3 : }
     357                 : /* }}} */
     358                 : 
     359                 : /* {{{ proto int HttpRequestPool::count()
     360                 :         Implements Countable::count(). */
     361                 : PHP_METHOD(HttpRequestPool, count)
     362               0 : {
     363               0 :         NO_ARGS {
     364               0 :                 getObject(http_requestpool_object, obj);
     365               0 :                 RETURN_LONG((long) zend_llist_count(&obj->pool.handles));
     366                 :         }
     367                 : }
     368                 : /* }}} */
     369                 : 
     370                 : /* {{{ proto array HttpRequestPool::getAttachedRequests()
     371                 :         Get attached HttpRequest objects. */
     372                 : PHP_METHOD(HttpRequestPool, getAttachedRequests)
     373               1 : {
     374               1 :         getObject(http_requestpool_object, obj);
     375                 :         
     376               1 :         NO_ARGS;
     377                 :         
     378               1 :         array_init(return_value);
     379               1 :         zend_llist_apply_with_argument(&obj->pool.handles, 
     380                 :                 (llist_apply_with_arg_func_t) http_requestpool_object_llist2array, 
     381                 :                 return_value TSRMLS_CC);
     382               1 : }
     383                 : /* }}} */
     384                 : 
     385                 : /* {{{ proto array HttpRequestPool::getFinishedRequests()
     386                 :         Get attached HttpRequest objects that already have finished their work. */
     387                 : PHP_METHOD(HttpRequestPool, getFinishedRequests)
     388             250 : {
     389             250 :         getObject(http_requestpool_object, obj);
     390                 :         
     391             250 :         NO_ARGS;
     392                 :                 
     393             250 :         array_init(return_value);
     394             250 :         zend_llist_apply_with_argument(&obj->pool.finished,
     395                 :                 (llist_apply_with_arg_func_t) http_requestpool_object_llist2array,
     396                 :                 return_value TSRMLS_CC);
     397             250 : }
     398                 : /* }}} */
     399                 : 
     400                 : /* {{{ proto bool HttpRequest::enablePiplelinig([bool enable = true])
     401                 :         Enables pipelining support for all attached requests if support in libcurl is given. */
     402                 : PHP_METHOD(HttpRequestPool, enablePipelining)
     403               0 : {
     404               0 :         zend_bool enable = 1;
     405               0 :         getObject(http_requestpool_object, obj);
     406                 :         
     407               0 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enable)) {
     408               0 :                 RETURN_FALSE;
     409                 :         }
     410                 : #if defined(HAVE_CURL_MULTI_SETOPT) && HTTP_CURL_VERSION(7,16,0)
     411                 :         if (CURLM_OK == curl_multi_setopt(obj->pool.ch, CURLMOPT_PIPELINING, (long) enable)) {
     412                 :                 RETURN_TRUE;
     413                 :         }
     414                 : #endif
     415               0 :         RETURN_FALSE;
     416                 : }
     417                 : /* }}} */
     418                 : 
     419                 : #endif /* ZEND_ENGINE_2 && HTTP_HAVE_CURL */
     420                 : 
     421                 : /*
     422                 :  * Local variables:
     423                 :  * tab-width: 4
     424                 :  * c-basic-offset: 4
     425                 :  * End:
     426                 :  * vim600: noet sw=4 ts=4 fdm=marker
     427                 :  * vim<600: noet sw=4 ts=4
     428                 :  */
     429                 : 

Generated by: LTP GCOV extension version 1.5