* Fixed bug in HttpRequestPool where a negative timeout was passed to select()
authorMichael Wallner <mike@php.net>
Mon, 25 Sep 2006 08:27:32 +0000 (08:27 +0000)
committerMichael Wallner <mike@php.net>
Mon, 25 Sep 2006 08:27:32 +0000 (08:27 +0000)
* Improve performace of http_request_info() (auto-generated)

config.w32
config9.m4
http.dsp
http_request_api.c
http_request_info.c [new file with mode: 0644]
http_request_pool_api.c
lib/BigGet.php
lib/XmlRpcClient.php
package2.xml
php_http_request_int.h
scripts/gen_curlinfo.php [new file with mode: 0644]

index c524037..1ec34d1 100644 (file)
@@ -56,7 +56,7 @@ if (PHP_HTTP != "no") {
                "http_filter_api.c http_request_body_api.c http_querystring_object.c "+
                "http_deflatestream_object.c http_inflatestream_object.c "+
                "http_cookie_api.c http_querystring_api.c http_request_datashare_api.c "+
-               "http_requestdatashare_object.c",
+               "http_requestdatashare_object.c http_request_info.c",
                null,
                "/I\"" + configure_module_dirname + "/phpstr\"");
        ADD_SOURCES(configure_module_dirname + "/phpstr", "phpstr.c", "http");
index 14db91a..8ad36a3 100644 (file)
@@ -318,7 +318,7 @@ dnl ----
        PHP_HTTP_SOURCES="missing.c http.c http_functions.c phpstr/phpstr.c \
                http_util_object.c http_message_object.c http_request_object.c http_request_pool_api.c \
                http_response_object.c http_exception_object.c http_requestpool_object.c \
-               http_api.c http_cache_api.c http_request_api.c http_date_api.c \
+               http_api.c http_cache_api.c http_request_api.c http_request_info.c http_date_api.c \
                http_headers_api.c http_message_api.c http_send_api.c http_url_api.c \
                http_info_api.c http_request_method_api.c http_encoding_api.c \
                http_filter_api.c http_request_body_api.c http_querystring_object.c \
index a10817b..ff7cb63 100644 (file)
--- a/http.dsp
+++ b/http.dsp
@@ -110,6 +110,10 @@ SOURCE=.\http_request_api.c
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\http_request_info.c\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\http_request_body_api.c\r
 # End Source File\r
 # Begin Source File\r
index 9697f6d..e278644 100644 (file)
@@ -856,45 +856,6 @@ PHP_HTTP_API void _http_request_exec(http_request *request)
 }
 /* }}} */
 
-/* {{{ void http_request_info(http_request *, HashTable *) */
-PHP_HTTP_API void _http_request_info(http_request *request, HashTable *info)
-{
-       zval array;
-       INIT_ZARR(array, info);
-
-       HTTP_CURL_INFO(CURLINFO_EFFECTIVE_URL);
-       HTTP_CURL_INFO(CURLINFO_RESPONSE_CODE);
-       HTTP_CURL_INFO_EX(CURLINFO_HTTP_CONNECTCODE, "connect_code");
-       HTTP_CURL_INFO(CURLINFO_FILETIME);
-       HTTP_CURL_INFO(CURLINFO_TOTAL_TIME);
-       HTTP_CURL_INFO(CURLINFO_NAMELOOKUP_TIME);
-       HTTP_CURL_INFO(CURLINFO_CONNECT_TIME);
-       HTTP_CURL_INFO(CURLINFO_PRETRANSFER_TIME);
-       HTTP_CURL_INFO(CURLINFO_STARTTRANSFER_TIME);
-       HTTP_CURL_INFO(CURLINFO_REDIRECT_TIME);
-       HTTP_CURL_INFO(CURLINFO_REDIRECT_COUNT);
-       HTTP_CURL_INFO(CURLINFO_SIZE_UPLOAD);
-       HTTP_CURL_INFO(CURLINFO_SIZE_DOWNLOAD);
-       HTTP_CURL_INFO(CURLINFO_SPEED_DOWNLOAD);
-       HTTP_CURL_INFO(CURLINFO_SPEED_UPLOAD);
-       HTTP_CURL_INFO(CURLINFO_HEADER_SIZE);
-       HTTP_CURL_INFO(CURLINFO_REQUEST_SIZE);
-       HTTP_CURL_INFO(CURLINFO_SSL_VERIFYRESULT);
-       HTTP_CURL_INFO(CURLINFO_SSL_ENGINES);
-       HTTP_CURL_INFO(CURLINFO_CONTENT_LENGTH_DOWNLOAD);
-       HTTP_CURL_INFO(CURLINFO_CONTENT_LENGTH_UPLOAD);
-       HTTP_CURL_INFO(CURLINFO_CONTENT_TYPE);
-       HTTP_CURL_INFO(CURLINFO_HTTPAUTH_AVAIL);
-       HTTP_CURL_INFO(CURLINFO_PROXYAUTH_AVAIL);
-       HTTP_CURL_INFO(CURLINFO_NUM_CONNECTS);
-#if HTTP_CURL_VERSION(7,14,1)
-       HTTP_CURL_INFO_EX(CURLINFO_COOKIELIST, "cookies");
-#endif
-       HTTP_CURL_INFO(CURLINFO_OS_ERRNO);
-       add_assoc_string(&array, "error", request->_error, 1);
-}
-/* }}} */
-
 /* {{{ static size_t http_curl_read_callback(void *, size_t, size_t, void *) */
 static size_t http_curl_read_callback(void *data, size_t len, size_t n, void *ctx)
 {
diff --git a/http_request_info.c b/http_request_info.c
new file mode 100644 (file)
index 0000000..bb7e601
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+    +--------------------------------------------------------------------+
+    | PECL :: http                                                       |
+    +--------------------------------------------------------------------+
+    | Redistribution and use in source and binary forms, with or without |
+    | modification, are permitted provided that the conditions mentioned |
+    | in the accompanying LICENSE file are met.                          |
+    +--------------------------------------------------------------------+
+    | Copyright (c) 2004-2006, Michael Wallner <mike@php.net>            |
+    +--------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#define HTTP_WANT_CURL
+#include "php_http.h"
+
+#include "php_http_request_api.h"
+
+/* {{{ void http_request_info(http_request *, HashTable *) */
+PHP_HTTP_API void _http_request_info(http_request *request, HashTable *info)
+{
+       char *c;
+       long l;
+       double d;
+       struct curl_slist *s, *p;
+       zval *subarray, array;
+       INIT_ZARR(array, info);
+       
+       /* BEGIN */
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_EFFECTIVE_URL, &c)) {
+               add_assoc_string_ex(&array, "effective_url", sizeof("effective_url"), c ? c : "", 1);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_RESPONSE_CODE, &l)) {
+               add_assoc_long_ex(&array, "response_code", sizeof("response_code"), l);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_TOTAL_TIME, &d)) {
+               add_assoc_double_ex(&array, "total_time", sizeof("total_time"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_NAMELOOKUP_TIME, &d)) {
+               add_assoc_double_ex(&array, "namelookup_time", sizeof("namelookup_time"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_CONNECT_TIME, &d)) {
+               add_assoc_double_ex(&array, "connect_time", sizeof("connect_time"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_PRETRANSFER_TIME, &d)) {
+               add_assoc_double_ex(&array, "pretransfer_time", sizeof("pretransfer_time"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SIZE_UPLOAD, &d)) {
+               add_assoc_double_ex(&array, "size_upload", sizeof("size_upload"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SIZE_DOWNLOAD, &d)) {
+               add_assoc_double_ex(&array, "size_download", sizeof("size_download"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SPEED_DOWNLOAD, &d)) {
+               add_assoc_double_ex(&array, "speed_download", sizeof("speed_download"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SPEED_UPLOAD, &d)) {
+               add_assoc_double_ex(&array, "speed_upload", sizeof("speed_upload"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_HEADER_SIZE, &l)) {
+               add_assoc_long_ex(&array, "header_size", sizeof("header_size"), l);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_REQUEST_SIZE, &l)) {
+               add_assoc_long_ex(&array, "request_size", sizeof("request_size"), l);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SSL_VERIFYRESULT, &l)) {
+               add_assoc_long_ex(&array, "ssl_verifyresult", sizeof("ssl_verifyresult"), l);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_FILETIME, &l)) {
+               add_assoc_long_ex(&array, "filetime", sizeof("filetime"), l);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d)) {
+               add_assoc_double_ex(&array, "content_length_download", sizeof("content_length_download"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_CONTENT_LENGTH_UPLOAD, &d)) {
+               add_assoc_double_ex(&array, "content_length_upload", sizeof("content_length_upload"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_STARTTRANSFER_TIME, &d)) {
+               add_assoc_double_ex(&array, "starttransfer_time", sizeof("starttransfer_time"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_CONTENT_TYPE, &c)) {
+               add_assoc_string_ex(&array, "content_type", sizeof("content_type"), c ? c : "", 1);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_REDIRECT_TIME, &d)) {
+               add_assoc_double_ex(&array, "redirect_time", sizeof("redirect_time"), d);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_REDIRECT_COUNT, &l)) {
+               add_assoc_long_ex(&array, "redirect_count", sizeof("redirect_count"), l);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_HTTP_CONNECTCODE, &l)) {
+               add_assoc_long_ex(&array, "connect_code", sizeof("connect_code"), l);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_HTTPAUTH_AVAIL, &l)) {
+               add_assoc_long_ex(&array, "httpauth_avail", sizeof("httpauth_avail"), l);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_PROXYAUTH_AVAIL, &l)) {
+               add_assoc_long_ex(&array, "proxyauth_avail", sizeof("proxyauth_avail"), l);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_OS_ERRNO, &l)) {
+               add_assoc_long_ex(&array, "os_errno", sizeof("os_errno"), l);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_NUM_CONNECTS, &l)) {
+               add_assoc_long_ex(&array, "num_connects", sizeof("num_connects"), l);
+       }
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_SSL_ENGINES, &s)) {
+               MAKE_STD_ZVAL(subarray);
+               array_init(subarray);
+               for (p = s; p; p = p->next) {
+                       add_next_index_string(subarray, p->data, 1);
+               }
+               add_assoc_zval_ex(&array, "ssl_engines", sizeof("ssl_engines"), subarray);
+               curl_slist_free_all(s);
+       }
+#if HTTP_CURL_VERSION(7,14,1)
+       if (CURLE_OK == curl_easy_getinfo(request->ch, CURLINFO_COOKIELIST, &s)) {
+               MAKE_STD_ZVAL(subarray);
+               array_init(subarray);
+               for (p = s; p; p = p->next) {
+                       add_next_index_string(subarray, p->data, 1);
+               }
+               add_assoc_zval_ex(&array, "cookielist", sizeof("cookielist"), subarray);
+               curl_slist_free_all(s);
+       }
+#endif
+/* END */
+       add_assoc_string_ex(&array, "error", sizeof("error"), request->_error, 1);
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
index dab929e..1541614 100644 (file)
@@ -264,7 +264,7 @@ PHP_HTTP_API STATUS _http_request_pool_select(http_request_pool *pool)
 #ifdef HAVE_CURL_MULTI_TIMEOUT
        long max_tout = 1000;
        
-       if (CURLM_OK == curl_multi_timeout(pool->ch, &max_tout)) {
+       if ((CURLM_OK == curl_multi_timeout(pool->ch, &max_tout)) && (max_tout != -1)) {
                timeout.tv_sec = max_tout / 1000;
                timeout.tv_usec = (max_tout % 1000) * 1000;
        }
index 0189261..73049a6 100644 (file)
@@ -156,13 +156,7 @@ class BigGet extends HttpRequestPool
      */
     protected function socketPerform()
     {
-        try {
-            $rs = parent::socketPerform();
-        } catch (HttpRequestPoolException $x) {
-            foreach ($x->exceptionStack as $e) {
-                echo $e->getMessage(), "\n";
-            }
-        }
+        $rs = parent::socketPerform();
         
         foreach ($this->getFinishedRequests() as $r) {
             $this->detach($r);
index 83a154e..c7abb2a 100644 (file)
@@ -22,7 +22,7 @@
  * @copyright   Michael Wallner, <mike@iworks.at>
  * @license     BSD, revised
  * @package     pecl/http
- * @version     $Revision$
+ * @version        $Revision$
  */
 class XmlRpcClient
 {
@@ -56,8 +56,7 @@ class XmlRpcClient
         */
        public function __construct($url, $namespace = '', array $options = null)
        {
-               $this->__request = new HttpRequest($url, HTTP_METH_POST);
-               $this->__request->setOptions($options);
+               $this->__request = new HttpRequest($url, HttpRequest::METH_POST, $options);
                $this->__namespace = $namespace;
        }
        
@@ -75,8 +74,9 @@ class XmlRpcClient
                        $method = $this->__namespace .'.'. $method;
                }
                $this->__request->setContentType("text/xml; charset=". $this->__encoding);
-               $request = xmlrpc_encode_request($method, $params, array("encoding" => $this->__encoding));
-               $this->__request->setRawPostData($request);
+               $this->__request->setRawPostData(
+                       xmlrpc_encode_request($method, $params, 
+                               array("encoding" => $this->__encoding)));
                $this->__request->send();
                $response = $this->__request->getResponseMessage();
                if ($response->getResponseCode() != 200) {
index a8bd365..a856366 100644 (file)
@@ -39,7 +39,8 @@ support. Parallel requests are available for PHP 5 and greater.
  </stability>
  <license>BSD, revised</license>
  <notes><![CDATA[
-+ Fixed build with gcc-2.95 (bug #8737)
+* Fixed build with gcc-2.95 (bug #8737)
+* Fixed bug in HttpRequestPool where a negative timeout was passed to select()
 ]]></notes>
  <contents>
   <dir name="/">
@@ -108,6 +109,7 @@ support. Parallel requests are available for PHP 5 and greater.
    <file role="src" name="http_message_api.c"/>
    <file role="src" name="http_querystring_api.c"/>
    <file role="src" name="http_request_api.c"/>
+   <file role="src" name="http_request_info.c"/>
    <file role="src" name="http_request_body_api.c"/>
    <file role="src" name="http_request_datashare_api.c"/>
    <file role="src" name="http_request_method_api.c"/>
index 5eecf9f..ae29186 100644 (file)
 #      define curl_easy_strerror(dummy) "unknown error"
 #endif
 
-#define HTTP_CURL_INFO(I) \
-       { \
-               char *N = #I; \
-               HTTP_CURL_INFO_EX(I, N+lenof("CURLINFO_")); \
-       }
-#define HTTP_CURL_INFO_EX(I, X) \
-       switch (I & ~CURLINFO_MASK) \
-       { \
-               case CURLINFO_STRING: \
-               { \
-                       char *c; \
-                       if (CURLE_OK == curl_easy_getinfo(request->ch, I, &c)) { \
-                               char *key = estrndup(X, strlen(X)); \
-                               add_assoc_string(&array, pretty_key(key, strlen(X), 0, 0), c ? c : "", 1); \
-                               efree(key); \
-                       } \
-               } \
-               break; \
-\
-               case CURLINFO_DOUBLE: \
-               { \
-                       double d; \
-                       if (CURLE_OK == curl_easy_getinfo(request->ch, I, &d)) { \
-                               char *key = estrndup(X, strlen(X)); \
-                               add_assoc_double(&array, pretty_key(key, strlen(X), 0, 0), d); \
-                               efree(key); \
-                       } \
-               } \
-               break; \
-\
-               case CURLINFO_LONG: \
-               { \
-                       long l; \
-                       if (CURLE_OK == curl_easy_getinfo(request->ch, I, &l)) { \
-                               char *key = estrndup(X, strlen(X)); \
-                               add_assoc_long(&array, pretty_key(key, strlen(X), 0, 0), l); \
-                               efree(key); \
-                       } \
-               } \
-               break; \
-\
-               case CURLINFO_SLIST: \
-               { \
-                       struct curl_slist *l, *p; \
-                       if (CURLE_OK == curl_easy_getinfo(request->ch, I, &l)) { \
-                               zval *subarray; \
-                               char *key = estrndup(X, strlen(X)); \
-                               MAKE_STD_ZVAL(subarray); \
-                               array_init(subarray); \
-                               for (p = l; p; p = p->next) { \
-                                       add_next_index_string(subarray, p->data, 1); \
-                               } \
-                               add_assoc_zval(&array, pretty_key(key, strlen(X), 0, 0), subarray); \
-                               curl_slist_free_all(l); \
-                               efree(key); \
-                       } \
-               } \
-       }
-
 #define HTTP_CURL_OPT(OPTION, p) HTTP_CURL_OPT_EX(request->ch, OPTION, (p))
 #define HTTP_CURL_OPT_EX(ch, OPTION, p) curl_easy_setopt((ch), OPTION, (p))
 
diff --git a/scripts/gen_curlinfo.php b/scripts/gen_curlinfo.php
new file mode 100644 (file)
index 0000000..129833a
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+// $Id$
+
+error_reporting(0);
+
+function failure() {
+       fprintf(STDERR, "FAILURE: %s\n", error_get_last());
+       exit(-1);
+}
+
+function file_re($file, $pattern, $all = true) {
+       static $path;
+       
+       $path or $path = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1].'/include/curl/' : "/usr/local/include/curl/";
+       
+       if ($content = file_get_contents($path . $file)) {
+               if ($all) {
+                       if (preg_match_all($pattern, $content, $matches, PREG_SET_ORDER)) {
+                               return $matches;
+                       }
+               } else {
+                       if (preg_match($pattern, $content, $matches)) {
+                               return $matches;
+                       }
+               }
+               trigger_error("no match in $file for $pattern");
+       }
+       failure();
+}
+
+function version($major, $minor, $pl) {
+       static $version;
+       
+       $version or $version = file_re('curlver.h', '/^#\s*define\s+LIBCURL_VERSION\s+"(\d+)\.(\d+)\.(\d+)(?:-\w+)?"\s*$/m', false);
+       
+       return $major <= $version[1] && $minor <= $version[2] && $pl <= $version[3];
+}
+
+$ifdefs = array(
+       'COOKIELIST' => '7,14,1'
+);
+$exclude = array(
+       'PRIVATE', 'LASTSOCKET', 'FTP_ENTRY_PATH'
+);
+$translate = array(
+       'HTTP_CONNECTCODE' => "connect_code"
+);
+
+$templates = array(
+'STRING' => 
+'      if (CURLE_OK == curl_easy_getinfo(request->ch, %s, &c)) {
+               add_assoc_string_ex(&array, "%s", sizeof("%2$s"), c ? c : "", 1);
+       }
+',
+'DOUBLE' => 
+'      if (CURLE_OK == curl_easy_getinfo(request->ch, %s, &d)) {
+               add_assoc_double_ex(&array, "%s", sizeof("%2$s"), d);
+       }
+',
+'LONG' => 
+'      if (CURLE_OK == curl_easy_getinfo(request->ch, %s, &l)) {
+               add_assoc_long_ex(&array, "%s", sizeof("%2$s"), l);
+       }
+',
+'SLIST' => 
+'      if (CURLE_OK == curl_easy_getinfo(request->ch, %s, &s)) {
+               MAKE_STD_ZVAL(subarray);
+               array_init(subarray);
+               for (p = s; p; p = p->next) {
+                       add_next_index_string(subarray, p->data, 1);
+               }
+               add_assoc_zval_ex(&array, "%s", sizeof("%2$s"), subarray);
+               curl_slist_free_all(s);
+       }
+'
+);
+
+$types = file_re('curl.h', '/^#\s*define\s+CURLINFO_(STRING|LONG|DOUBLE|SLIST|MASK|TYPEMASK)\s+(0x[0-9a-fA-F]+)\s*$/m');
+$infos = file_re('curl.h', '/^\s*(CURLINFO_(\w+))\s*=\s*CURLINFO_(STRING|LONG|DOUBLE|SLIST)\s*\+\s*\d+\s*,?\s*$/m');
+
+ob_start();
+foreach ($infos as $info) {
+       list(, $full, $short, $type) = $info;
+       if (in_array($short, $exclude)) continue;
+       if (isset($ifdefs[$short])) printf("#if HTTP_CURL_VERSION(%s)\n", $ifdefs[$short]);
+       if (isset($translate[$short])) $short = $translate[$short];
+       printf($templates[$type], $full, strtolower($short));
+       if (isset($ifdefs[$short])) printf("#endif\n");
+}
+
+file_put_contents("http_request_info.c", 
+       preg_replace('/(\/\* BEGIN \*\/\n).*(\/\* END \*\/)/s', '$1'. ob_get_contents() .'$2',
+               file_get_contents("http_request_info.c")));
+
+?>