fix bug #66388 (Crash on POST with Content-Length:0 and untouched body)
[m6w6/ext-http] / php_http_client_curl.c
index 3200fa2cad21bc901f2e65d1f7924807f2dc476a..3b96cf4dfab60410234046f926b8dcb3efac3711 100644 (file)
 #if PHP_HTTP_HAVE_CURL
 
 #if PHP_HTTP_HAVE_EVENT
-#      include <event.h>
 #      if !PHP_HTTP_HAVE_EVENT2 && /* just be really sure */ !(LIBEVENT_VERSION_NUMBER >= 0x02000000)
+#              include <event.h>
 #              define event_base_new event_init
 #              define event_assign(e, b, s, a, cb, d) do {\
                        event_set(e, s, a, cb, d); \
                        event_base_set(b, e); \
                } while(0)
+#      else
+#              if PHP_HTTP_HAVE_EVENT2
+#                      include <event2/event.h>
+#                      include <event2/event_struct.h>
+#              else
+#                      error "libevent presence is unknown"
+#              endif
 #      endif
 #      ifndef DBG_EVENTS
 #              define DBG_EVENTS 0
@@ -169,9 +176,13 @@ static size_t php_http_curle_read_callback(void *data, size_t len, size_t n, voi
 {
        php_http_message_body_t *body = ctx;
 
-       if (body) {
-               TSRMLS_FETCH_FROM_CTX(body->ts);
-               return php_stream_read(php_http_message_body_stream(body), data, len * n);
+       if (body && body->stream_id) {
+               php_stream *s = php_http_message_body_stream(body);
+
+               if (s) {
+                       TSRMLS_FETCH_FROM_CTX(body->ts);
+                       return php_stream_read(s, data, len * n);
+               } else abort();
        }
        return 0;
 }
@@ -1497,6 +1508,11 @@ static STATUS php_http_client_curl_handler_prepare(php_http_client_curl_handler_
                curl_easy_setopt(curl->handle, CURLOPT_READDATA, msg->body);
                curl_easy_setopt(curl->handle, CURLOPT_INFILESIZE, body_size);
                curl_easy_setopt(curl->handle, CURLOPT_POSTFIELDSIZE, body_size);
+       } else {
+               curl_easy_setopt(curl->handle, CURLOPT_IOCTLDATA, NULL);
+               curl_easy_setopt(curl->handle, CURLOPT_READDATA, NULL);
+               curl_easy_setopt(curl->handle, CURLOPT_INFILESIZE, 0L);
+               curl_easy_setopt(curl->handle, CURLOPT_POSTFIELDSIZE, 0L);
        }
 
        php_http_options_apply(&php_http_curle_options, enqueue->options, curl);
@@ -1762,11 +1778,12 @@ static int php_http_client_curl_once(php_http_client_t *h)
 
 static STATUS php_http_client_curl_exec(php_http_client_t *h)
 {
-       TSRMLS_FETCH_FROM_CTX(h->ts);
-
 #if PHP_HTTP_HAVE_EVENT
        php_http_client_curl_t *curl = h->ctx;
+#endif
+       TSRMLS_FETCH_FROM_CTX(h->ts);
 
+#if PHP_HTTP_HAVE_EVENT
        if (curl->useevents) {
                php_http_curlm_timeout_callback(CURL_SOCKET_TIMEOUT, /*EV_READ|EV_WRITE*/0, h);
                do {
@@ -1972,7 +1989,11 @@ PHP_MINIT_FUNCTION(http_client_curl)
 
 PHP_MSHUTDOWN_FUNCTION(http_client_curl)
 {
+       php_persistent_handle_cleanup(ZEND_STRL("http\\Client\\Curl"), NULL, 0 TSRMLS_CC);
+       php_persistent_handle_cleanup(ZEND_STRL("http\\Client\\Curl\\Request"), NULL, 0 TSRMLS_CC);
+
        php_http_options_dtor(&php_http_curle_options);
+
        return SUCCESS;
 }