- separate sleeping functionality to _http_sleep()
authorMichael Wallner <mike@php.net>
Sun, 10 Sep 2006 13:07:01 +0000 (13:07 +0000)
committerMichael Wallner <mike@php.net>
Sun, 10 Sep 2006 13:07:01 +0000 (13:07 +0000)
- use curl suggested select timeout
- sleep if there are no fds ready for select
- add some missing request options

config9.m4
http_request_api.c
http_request_pool_api.c
http_send_api.c
package2.xml
php_http_api.h

index 1fcb91d..cb7db94 100644 (file)
@@ -242,6 +242,10 @@ dnl ----
                        [AC_DEFINE([HAVE_CURL_MULTI_SETOPT], [1], [ ])], [ ], 
                        [$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR]
                )
+               PHP_CHECK_LIBRARY(curl, curl_multi_timeout, 
+                       [AC_DEFINE([HAVE_CURL_MULTI_TIMEOUT], [1], [ ])], [ ],
+                       [$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR]
+               )
        fi
 
 dnl ----
index b253a97..9697f6d 100644 (file)
@@ -347,6 +347,17 @@ PHP_HTTP_API void _http_request_defaults(http_request *request)
                HTTP_CURL_OPT(CURLOPT_PROXYTYPE, 0L);
                HTTP_CURL_OPT(CURLOPT_PROXYUSERPWD, NULL);
                HTTP_CURL_OPT(CURLOPT_PROXYAUTH, 0L);
+               HTTP_CURL_OPT(CURLOPT_DNS_CACHE_TIMEOUT, 60L);
+               HTTP_CURL_OPT(CURLOPT_LOW_SPEED_LIMIT, 0L);
+               HTTP_CURL_OPT(CURLOPT_LOW_SPEED_TIME, 0L);
+#if HTTP_CURL_VERSION(7,15,5)
+               HTTP_CURL_OPT(CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t) 0);
+               HTTP_CURL_OPT(CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) 0);
+#endif
+               /* crashes
+               HTTP_CURL_OPT(CURLOPT_MAXCONNECTS, 5L); */
+               HTTP_CURL_OPT(CURLOPT_FRESH_CONNECT, 0L);
+               HTTP_CURL_OPT(CURLOPT_FORBID_REUSE, 0L);
                HTTP_CURL_OPT(CURLOPT_INTERFACE, NULL);
                HTTP_CURL_OPT(CURLOPT_PORT, 0L);
 #if HTTP_CURL_VERSION(7,15,2)
@@ -461,6 +472,37 @@ PHP_HTTP_API STATUS _http_request_prepare(http_request *request, HashTable *opti
                }
        }
 
+       /* dns */
+       if ((zoption = http_request_option(request, options, "dns_cache_timeout", IS_LONG))) {
+               HTTP_CURL_OPT(CURLOPT_DNS_CACHE_TIMEOUT, Z_LVAL_P(zoption));
+       }
+       
+       /* limits */
+       if ((zoption = http_request_option(request, options, "low_speed_limit", IS_LONG))) {
+               HTTP_CURL_OPT(CURLOPT_LOW_SPEED_LIMIT, Z_LVAL_P(zoption));
+       }
+       if ((zoption = http_request_option(request, options, "low_speed_time", IS_LONG))) {
+               HTTP_CURL_OPT(CURLOPT_LOW_SPEED_TIME, Z_LVAL_P(zoption));
+       }
+#if HTTP_CURL_VERSION(7,15,5)
+       if ((zoption = http_request_option(request, options, "max_send_speed", IS_LONG))) {
+               HTTP_CURL_OPT(CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t) Z_LVAL_P(zoption));
+       }
+       if ((zoption = http_request_option(request, options, "max_recv_speed", IS_LONG))) {
+               HTTP_CURL_OPT(CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) Z_LVAL_P(zoption));
+       }
+#endif
+       /* crashes
+       if ((zoption = http_request_option(request, options, "maxconnects", IS_LONG))) {
+               HTTP_CURL_OPT(CURLOPT_MAXCONNECTS, Z_LVAL_P(zoption));
+       } */
+       if ((zoption = http_request_option(request, options, "fresh_connect", IS_BOOL)) && Z_BVAL_P(zoption)) {
+               HTTP_CURL_OPT(CURLOPT_FRESH_CONNECT, 1L);
+       }
+       if ((zoption = http_request_option(request, options, "forbid_reuse", IS_BOOL)) && Z_BVAL_P(zoption)) {
+               HTTP_CURL_OPT(CURLOPT_FORBID_REUSE, 1L);
+       }
+       
        /* outgoing interface */
        if ((zoption = http_request_option(request, options, "interface", IS_STRING))) {
                HTTP_CURL_OPT(CURLOPT_INTERFACE, Z_STRVAL_P(zoption));
@@ -978,6 +1020,9 @@ static int http_curl_raw_callback(CURL *ch, curl_infotype type, char *data, size
                        if (data[length-1] != 0xa) {
                                fprintf(stderr, "\n");
                        }
+#endif
+#if 0
+                       fprintf(stderr, "%.*s%s", length, data, data[length-1]=='\n'?"":"\n");
 #endif
                        break;
        }
index 5b04472..dab929e 100644 (file)
@@ -261,13 +261,24 @@ PHP_HTTP_API STATUS _http_request_pool_select(http_request_pool *pool)
        int MAX;
        fd_set R, W, E;
        struct timeval timeout = {1, 0};
+#ifdef HAVE_CURL_MULTI_TIMEOUT
+       long max_tout = 1000;
+       
+       if (CURLM_OK == curl_multi_timeout(pool->ch, &max_tout)) {
+               timeout.tv_sec = max_tout / 1000;
+               timeout.tv_usec = (max_tout % 1000) * 1000;
+       }
+#endif
 
        FD_ZERO(&R);
        FD_ZERO(&W);
        FD_ZERO(&E);
 
        if (CURLM_OK == curl_multi_fdset(pool->ch, &R, &W, &E, &MAX)) {
-               if (MAX == -1 || SELECT_ERROR != select(MAX + 1, &R, &W, &E, &timeout)) {
+               if (MAX == -1) {
+                       http_sleep((double) timeout.tv_sec + (double) (timeout.tv_usec / HTTP_MCROSEC));
+                       return SUCCESS;
+               } else if (SELECT_ERROR != select(MAX + 1, &R, &W, &E, &timeout)) {
                        return SUCCESS;
                }
        }
index ebecb33..0c1fe57 100644 (file)
@@ -39,28 +39,8 @@ static inline void _http_flush(void *nothing, const char *data, size_t data_len
        fprintf(stderr, "Flushing after writing %u bytes\n", (uint) data_len);
 #endif
        
-#define HTTP_MSEC(s) (s * 1000)
-#define HTTP_USEC(s) (HTTP_MSEC(s) * 1000)
-#define HTTP_NSEC(s) (HTTP_USEC(s) * 1000)
-#define HTTP_NANOSEC (1000 * 1000 * 1000)
-#define HTTP_DIFFSEC (0.001)
-
        if (HTTP_G->send.throttle_delay >= HTTP_DIFFSEC) {
-#if defined(PHP_WIN32)
-               Sleep((DWORD) HTTP_MSEC(HTTP_G->send.throttle_delay));
-#elif defined(HAVE_USLEEP)
-               usleep(HTTP_USEC(HTTP_G->send.throttle_delay));
-#elif defined(HAVE_NANOSLEEP)
-               struct timespec req, rem;
-
-               req.tv_sec = (time_t) HTTP_G->send.throttle_delay;
-               req.tv_nsec = HTTP_NSEC(HTTP_G->send.throttle_delay) % HTTP_NANOSEC;
-
-               while (nanosleep(&req, &rem) && (errno == EINTR) && (HTTP_NSEC(rem.tv_sec) + rem.tv_nsec) > HTTP_NSEC(HTTP_DIFFSEC))) {
-                       req.tv_sec = rem.tv_sec;
-                       req.tv_nsec = rem.tv_nsec;
-               }
-#endif
+               http_sleep(HTTP_G->send.throttle_delay);
        }
 }
 /* }}} */
index 15cfea5..43d6afa 100644 (file)
@@ -40,6 +40,8 @@ support. Parallel requests are available for PHP 5 and greater.
  <license>BSD, revised</license>
  <notes><![CDATA[
 + Added HttpRequestPool::enablePipielining([bool enable = TRUE]) (libcurl >= 7.16.0)
++ Added "dns_cache_timeout", "low_speed_limit", "low_speed_time", "max_send_speed",
+  "max_recv_speed", "forbid_reuse" and "fresh_connect" request options
 ]]></notes>
  <contents>
   <dir name="/">
index 9e5c389..052fb1e 100644 (file)
@@ -156,6 +156,41 @@ PHP_HTTP_API void _http_parse_params_default_callback(void *ht, const char *key,
 PHP_HTTP_API STATUS _http_parse_params_ex(const char *params, int flags, http_parse_params_callback cb, void *cb_arg TSRMLS_DC);
 
 
+#define http_sleep(s) _http_sleep(s)
+static inline void _http_sleep(double s)
+{
+#define HTTP_DIFFSEC (0.001)
+#define HTTP_MLLISEC (1000)
+#define HTTP_MCROSEC (1000 * 1000)
+#define HTTP_NANOSEC (1000 * 1000 * 1000)
+#define HTTP_MSEC(s) (s * HTTP_MLLISEC)
+#define HTTP_USEC(s) (s * HTTP_MCROSEC)
+#define HTTP_NSEC(s) (s * HTTP_NANOSEC)
+
+#if defined(PHP_WIN32)
+       Sleep((DWORD) HTTP_MSEC(s));
+#elif defined(HAVE_USLEEP)
+       usleep(HTTP_USEC(s));
+#elif defined(HAVE_NANOSLEEP)
+       struct timespec req, rem;
+
+       req.tv_sec = (time_t) s;
+       req.tv_nsec = HTTP_NSEC(s) % HTTP_NANOSEC;
+
+       while (nanosleep(&req, &rem) && (errno == EINTR) && (HTTP_NSEC(rem.tv_sec) + rem.tv_nsec) > HTTP_NSEC(HTTP_DIFFSEC))) {
+               req.tv_sec = rem.tv_sec;
+               req.tv_nsec = rem.tv_nsec;
+       }
+#else
+       struct timeval timeout;
+       timeout.tv.sec = (time_t) s;
+       timeout.tv_usec = HTTP_USEC(s) % HTTP_MCROSEC;
+       
+       select(0, NULL, NULL, NULL, &timeout);
+#endif
+}
+
 #define http_locate_body _http_locate_body
 static inline const char *_http_locate_body(const char *message)
 {