Merge branch 'master' of git.php.net:/pecl/http/pecl_http
authorRemi Collet <remi@php.net>
Mon, 1 Sep 2014 11:41:44 +0000 (13:41 +0200)
committerRemi Collet <remi@php.net>
Mon, 1 Sep 2014 11:41:44 +0000 (13:41 +0200)
* 'master' of git.php.net:/pecl/http/pecl_http: (329 commits)
  back to dev
  prepare 2.1.0
  fix sovereignty of clients when using events
  simplify duff device usage
  simplify duff device usage
  expose http\Message\Parser class
  fix invalid read
  release 2.1.0RC3
  prepare RC3
  news
  fix possible bus error on shutdown when using events
  be clear what we want the user to do
  add curlcode transfer info
  define off_t
  Removed port and scheme guessing of http\Url for portability
  fix PHP-5.3 compatibility
  MSVC dumbness
  back to dev
  prepare R_2_1_0_RC2
  fix write on stack
  ...

26 files changed:
config.w32
config9.m4
package.xml
php_http.c
php_http.h
php_http_api.h
php_http_client_curl.c
php_http_client_curl.h
php_http_curl.c
php_http_encoding.c
php_http_env_response.c
php_http_header_parser.c
php_http_message.c
php_http_message_parser.c
php_http_message_parser.h
php_http_misc.c
php_http_misc.h
php_http_params.c
php_http_url.c
tests/client015.phpt [new file with mode: 0644]
tests/data/message_r_multipart_put.txt
tests/info_001.phpt
tests/message002.phpt
tests/message006.phpt
tests/messageparser001.phpt [new file with mode: 0644]
tests/params015.phpt

index 497fb650175edaa9a36b0bc0271414e3eb092fe3..b84101f79af9a389546b4731db267a7791a37e5e 100644 (file)
@@ -61,8 +61,6 @@ if (PHP_HTTP != "no") {
        AC_DEFINE("HTTP_SHARED_DEPS", 1, "Depend on shared extensions");\r
        \r
        AC_DEFINE("HAVE_GETHOSTNAME", 1);\r
-       AC_DEFINE("HAVE_GETSERVBYPORT", 1);\r
-       AC_DEFINE("HAVE_GETSERVBYNAME", 1);\r
        \r
        if (PHP_DEBUG != "no") {\r
                ADD_FLAG("CFLAGS_HTTP", "/W3");\r
index ba1b93511b551885c801bcead58a0503532346d1..9ca835630506f1a608fcfb7b75bb994e917dff50 100644 (file)
@@ -68,7 +68,6 @@ if test "$PHP_HTTP" != "no"; then
        AC_DEFUN([HTTP_HAVE_PHP_EXT], [
                extname=$1
                haveext=$[PHP_]translit($1,a-z_-,A-Z__)
-               
                AC_MSG_CHECKING([for ext/$extname support])
                if test -x "$PHP_EXECUTABLE"; then
                        grepext=`$PHP_EXECUTABLE -m | $EGREP ^$extname\$`
@@ -96,13 +95,11 @@ if test "$PHP_HTTP" != "no"; then
 dnl ----
 dnl STDC
 dnl ----
+       AC_TYPE_OFF_T
+       dnl getdomainname() is declared in netdb.h on some platforms: AIX, OSF
        AC_CHECK_HEADERS([netdb.h unistd.h])
        PHP_CHECK_FUNC(gethostname, nsl)
        PHP_CHECK_FUNC(getdomainname, nsl)
-       PHP_CHECK_FUNC(getservbyport, nsl)
-       PHP_CHECK_FUNC(getservbyport_r, nsl)
-       PHP_CHECK_FUNC(getservbyname, nsl)
-       PHP_CHECK_FUNC(getservbyname_r, nsl)
 
 dnl ----
 dnl ZLIB
@@ -379,7 +376,7 @@ dnl ----
                        PHP_ADD_INCLUDE([$HTTP_EXT_RAPHF_INCDIR])
                fi
        ], [
-               AC_MSG_ERROR([Please install pecl/raphf])
+               AC_MSG_ERROR([Please install pecl/raphf and activate extension=raphf.$SHLIB_DL_SUFFIX_NAME in your php.ini])
        ])
 
 dnl ----
@@ -407,7 +404,7 @@ dnl ----
                        PHP_ADD_INCLUDE([$HTTP_EXT_PROPRO_INCDIR])
                fi
        ], [
-               AC_MSG_ERROR([Please install pecl/propro])
+               AC_MSG_ERROR([Please install pecl/propro and activate extension=propro.$SHLIB_DL_SUFFIX_NAME in your php.ini])
        ])
 
 PHP_ARG_WITH([http-shared-deps], [whether to depend on extensions which have been built shared],
index 33d50e662bb09b11f7a760f3ee1dff4ab33e6acf..8c74393422927b714c93b97e06db0a6b3da7b8df 100644 (file)
@@ -37,10 +37,10 @@ v2: http://dev.iworks.at/ext-http/lcov/ext/http/
   <email>mike@php.net</email>
   <active>yes</active>
  </lead>
- <date>2014-08-01</date>
+ <date>2014-08-19</date>
  <version>
-  <release>2.1.0RC1</release>
-  <api>2.1.0</api>
+  <release>2.2.0dev</release>
+  <api>2.2.0</api>
  </version>
  <stability>
   <release>beta</release>
@@ -48,16 +48,8 @@ v2: http://dev.iworks.at/ext-http/lcov/ext/http/
  </stability>
  <license>BSD, revised</license>
  <notes><![CDATA[
-* Fixed bug #67733 (Compile error with libevent 2.x)
-+ Added RFC5987 support in http\Params
-+ Improved synthetic HTTP message parsing performace for ~20%
-+ Added request options if libcurl has builtin c-ares support:
-  dns_interface, dns_local_ip4, dns_local_ip6 (all libcurl >= 7.33.0)
-+ Added request options:
-  expect_100_timeout (libcurl >= 7.36.0)
-  tcp_nodelay
-+ Added transfer info:
-  tls_session (libcurl >= 7.34.0), only available during transfer
+- var_dump(http\Message) no longer automatically creates an empty body
++ Added http\Message\Parser class
 ]]></notes>
  <contents>
   <dir name="/">
@@ -256,6 +248,7 @@ v2: http://dev.iworks.at/ext-http/lcov/ext/http/
      <file role="test" name="messagebody008.phpt"/>
      <file role="test" name="messagebody009.phpt"/>
      <file role="test" name="messagebody010.phpt"/>
+     <file role="test" name="messageparser001.phpt"/>
      <file role="test" name="negotiate001.phpt"/>
      <file role="test" name="params001.phpt"/>
      <file role="test" name="params002.phpt"/>
index 2101f0b70c278f1fdd9ad61125193739433c0f97..f7a0b8698f03012f2d8460532fcdb37504ea5649 100644 (file)
@@ -142,6 +142,7 @@ PHP_MINIT_FUNCTION(http)
        || SUCCESS != PHP_MINIT_CALL(http_filter)
        || SUCCESS != PHP_MINIT_CALL(http_header)
        || SUCCESS != PHP_MINIT_CALL(http_message)
+       || SUCCESS != PHP_MINIT_CALL(http_message_parser)
        || SUCCESS != PHP_MINIT_CALL(http_message_body)
        || SUCCESS != PHP_MINIT_CALL(http_querystring)
        || SUCCESS != PHP_MINIT_CALL(http_client)
@@ -187,9 +188,6 @@ PHP_RINIT_FUNCTION(http)
 {
        if (0
        || SUCCESS != PHP_RINIT_CALL(http_env)
-#if PHP_HTTP_HAVE_CURL && PHP_HTTP_HAVE_EVENT
-       || SUCCESS != PHP_RINIT_CALL(http_client_curl)
-#endif
        ) {
                return FAILURE;
        }
@@ -200,9 +198,6 @@ PHP_RINIT_FUNCTION(http)
 PHP_RSHUTDOWN_FUNCTION(http)
 {
        if (0
-#if PHP_HTTP_HAVE_CURL && PHP_HTTP_HAVE_EVENT
-       || SUCCESS != PHP_RSHUTDOWN_CALL(http_client_curl)
-#endif
        || SUCCESS != PHP_RSHUTDOWN_CALL(http_env)
        ) {
                return FAILURE;
index 72670089e143978455d034e0d8f5ce931bbe060a..98332cb68fb7fdfcb5824ca784d72e5e5e50311a 100644 (file)
@@ -13,7 +13,7 @@
 #ifndef PHP_EXT_HTTP_H
 #define PHP_EXT_HTTP_H
 
-#define PHP_PECL_HTTP_VERSION "2.1.0RC1"
+#define PHP_PECL_HTTP_VERSION "2.2.0dev"
 
 extern zend_module_entry http_module_entry;
 #define phpext_http_ptr &http_module_entry
index 9e0dc6ca69bc39fa7eb80263fbf78a24f56a378a..0e65ccb6315f3c9483de784e1abd8cd23909449b 100644 (file)
@@ -58,17 +58,14 @@ typedef int STATUS;
 
 #ifdef PHP_WIN32
 #      define CURL_STATICLIB
-#      define PHP_HTTP_HAVE_NETDB
 #      include <winsock2.h>
-#elif defined(HAVE_NETDB_H)
-#      define PHP_HTTP_HAVE_NETDB
-#      include <netdb.h>
+#else
+#      ifdef HAVE_NETDB_H
+#              include <netdb.h>
+#      endif
 #      ifdef HAVE_UNISTD_H
 #              include <unistd.h>
 #      endif
-#      ifdef HAVE_ERRNO_H
-#              include <errno.h>
-#      endif
 #endif
 
 #include <ctype.h>
@@ -111,9 +108,6 @@ typedef int STATUS;
 
 ZEND_BEGIN_MODULE_GLOBALS(php_http)
        struct php_http_env_globals env;
-#if PHP_HTTP_HAVE_CURL && PHP_HTTP_HAVE_EVENT
-       struct php_http_curl_globals curl;
-#endif
 ZEND_END_MODULE_GLOBALS(php_http)
 
 ZEND_EXTERN_MODULE_GLOBALS(php_http);
index 15d26192cedfdc27dbeff17d8ec7ab23a3e5c7d2..db73a3141bae70b393661f732f8cf2eebf2c1571 100644 (file)
@@ -49,6 +49,7 @@ typedef struct php_http_client_curl {
        int unfinished;  /* int because of curl_multi_perform() */
 
 #if PHP_HTTP_HAVE_EVENT
+       struct event_base *evbase;
        struct event *timeout;
        unsigned useevents:1;
 #endif
@@ -98,6 +99,7 @@ typedef struct php_http_client_curl_handler {
 typedef struct php_http_curle_storage {
        char *url;
        char *cookiestore;
+       CURLcode errorcode;
        char errorbuffer[0x100];
 } php_http_curle_storage_t;
 
@@ -487,7 +489,6 @@ static STATUS php_http_curle_get_info(CURL *ch, HashTable *info)
 
 #if PHP_HTTP_CURL_VERSION(7,34,0)
        {
-               int i;
                zval *ti_array;
                struct curl_tlssessioninfo *ti;
 
@@ -599,7 +600,12 @@ static STATUS php_http_curle_get_info(CURL *ch, HashTable *info)
                }
        }
 #endif
-       add_assoc_string_ex(&array, "error", sizeof("error"), php_http_curle_get_storage(ch)->errorbuffer, 1);
+       {
+               php_http_curle_storage_t *st = php_http_curle_get_storage(ch);
+
+               add_assoc_long_ex(&array, "curlcode", sizeof("curlcode"), st->errorcode);
+               add_assoc_string_ex(&array, "error", sizeof("error"), st->errorbuffer, 1);
+       }
 
        return SUCCESS;
 }
@@ -622,7 +628,7 @@ static void php_http_curlm_responsehandler(php_http_client_t *context)
                if (msg && CURLMSG_DONE == msg->msg) {
                        if (CURLE_OK != msg->data.result) {
                                php_http_curle_storage_t *st = php_http_curle_get_storage(msg->easy_handle);
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s; %s (%s)", curl_easy_strerror(msg->data.result), STR_PTR(st->errorbuffer), STR_PTR(st->url));
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s; %s (%s)", curl_easy_strerror(st->errorcode = msg->data.result), STR_PTR(st->errorbuffer), STR_PTR(st->url));
                        }
 
                        if ((enqueue = php_http_client_enqueued(context, msg->easy_handle, compare_queue))) {
@@ -753,7 +759,7 @@ static int php_http_curlm_socket_callback(CURL *easy, curl_socket_t sock, int ac
                                return -1;
                }
 
-               event_assign(&ev->evnt, PHP_HTTP_G->curl.event_base, sock, events, php_http_curlm_event_callback, context);
+               event_assign(&ev->evnt, curl->evbase, sock, events, php_http_curlm_event_callback, context);
                event_add(&ev->evnt, NULL);
        }
 
@@ -774,10 +780,9 @@ static void php_http_curlm_timer_callback(CURLM *multi, long timeout_ms, void *t
                        php_http_curlm_timeout_callback(CURL_SOCKET_TIMEOUT, /*EV_READ|EV_WRITE*/0, context);
                } else if (timeout_ms > 0 || !event_initialized(curl->timeout) || !event_pending(curl->timeout, EV_TIMEOUT, NULL)) {
                        struct timeval timeout;
-                       TSRMLS_FETCH_FROM_CTX(context->ts);
 
                        if (!event_initialized(curl->timeout)) {
-                               event_assign(curl->timeout, PHP_HTTP_G->curl.event_base, CURL_SOCKET_TIMEOUT, 0, php_http_curlm_timeout_callback, context);
+                               event_assign(curl->timeout, curl->evbase, CURL_SOCKET_TIMEOUT, 0, php_http_curlm_timeout_callback, context);
                        } else if (event_pending(curl->timeout, EV_TIMEOUT, NULL)) {
                                event_del(curl->timeout);
                        }
@@ -1309,7 +1314,7 @@ static void php_http_curle_options_init(php_http_options_t *registry TSRMLS_DC)
                }
                if ((opt = php_http_option_register(registry, ZEND_STRL("certtype"), CURLOPT_SSLCERTTYPE, IS_STRING))) {
                        opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
-                       ZVAL_STRING(&opt->defval, "PEM", 1);
+                       ZVAL_STRING(&opt->defval, "PEM", 0);
                }
                if ((opt = php_http_option_register(registry, ZEND_STRL("key"), CURLOPT_SSLKEY, IS_STRING))) {
                        opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
@@ -1317,7 +1322,7 @@ static void php_http_curle_options_init(php_http_options_t *registry TSRMLS_DC)
                }
                if ((opt = php_http_option_register(registry, ZEND_STRL("keytype"), CURLOPT_SSLKEYTYPE, IS_STRING))) {
                        opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
-                       ZVAL_STRING(&opt->defval, "PEM", 1);
+                       ZVAL_STRING(&opt->defval, "PEM", 0);
                }
                if ((opt = php_http_option_register(registry, ZEND_STRL("keypasswd"), CURLOPT_SSLKEYPASSWD, IS_STRING))) {
                        opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN;
@@ -1731,9 +1736,16 @@ static void php_http_client_curl_dtor(php_http_client_t *h)
 
 #if PHP_HTTP_HAVE_EVENT
        if (curl->timeout) {
+               if (event_initialized(curl->timeout) && event_pending(curl->timeout, EV_TIMEOUT, NULL)) {
+                       event_del(curl->timeout);
+               }
                efree(curl->timeout);
                curl->timeout = NULL;
        }
+       if (curl->evbase) {
+               event_base_free(curl->evbase);
+               curl->evbase = NULL;
+       }
 #endif
        curl->unfinished = 0;
 
@@ -1943,7 +1955,7 @@ static STATUS php_http_client_curl_exec(php_http_client_t *h)
        if (curl->useevents) {
                php_http_curlm_timeout_callback(CURL_SOCKET_TIMEOUT, /*EV_READ|EV_WRITE*/0, h);
                do {
-                       int ev_rc = event_base_dispatch(PHP_HTTP_G->curl.event_base);
+                       int ev_rc = event_base_dispatch(curl->evbase);
 
 #if DBG_EVENTS
                        fprintf(stderr, "%c", "X.0"[ev_rc+1]);
@@ -1987,6 +1999,9 @@ static STATUS php_http_client_curl_setopt(php_http_client_t *h, php_http_client_
                case PHP_HTTP_CLIENT_OPT_USE_EVENTS:
 #if PHP_HTTP_HAVE_EVENT
                        if ((curl->useevents = *((zend_bool *) arg))) {
+                               if (!curl->evbase) {
+                                       curl->evbase = event_base_new();
+                               }
                                if (!curl->timeout) {
                                        curl->timeout = ecalloc(1, sizeof(struct event));
                                }
@@ -2153,24 +2168,6 @@ PHP_MSHUTDOWN_FUNCTION(http_client_curl)
        return SUCCESS;
 }
 
-#if PHP_HTTP_HAVE_EVENT
-PHP_RINIT_FUNCTION(http_client_curl)
-{
-       if (!PHP_HTTP_G->curl.event_base && !(PHP_HTTP_G->curl.event_base = event_base_new())) {
-               return FAILURE;
-       }
-       return SUCCESS;
-}
-PHP_RSHUTDOWN_FUNCTION(http_client_curl)
-{
-       if (PHP_HTTP_G->curl.event_base) {
-               event_base_free(PHP_HTTP_G->curl.event_base);
-               PHP_HTTP_G->curl.event_base = NULL;
-       }
-       return SUCCESS;
-}
-#endif /* PHP_HTTP_HAVE_EVENT */
-
 #endif /* PHP_HTTP_HAVE_CURL */
 
 /*
index 03b9b6f03e9601513b148bc961fa8137adedabfc..c82a09cb94609c6a719acd6ca7437d2293b981fc 100644 (file)
 
 #if PHP_HTTP_HAVE_CURL
 
-#if PHP_HTTP_HAVE_EVENT
-struct php_http_curl_globals {
-       void *event_base;
-};
-
-PHP_RINIT_FUNCTION(http_client_curl);
-PHP_RSHUTDOWN_FUNCTION(http_client_curl);
-#endif /* PHP_HTTP_HAVE_EVENT */
-
 PHP_MINIT_FUNCTION(http_client_curl);
 PHP_MSHUTDOWN_FUNCTION(http_client_curl);
 #endif /* PHP_HTTP_HAVE_CURL */
index 30feba0fcd5639b11e44c2e13b485a0632bfbec3..a9950948d1c5ebb66ae8c3e4b9b7568e7ec99b7a 100644 (file)
 #              elif defined(PHP_HTTP_HAVE_GNUTLS)
 #                      define PHP_HTTP_NEED_GNUTLS_TSL
 #                      include <gcrypt.h>
-#              else
-#                      warning \
-                               "libcurl was compiled with SSL support, but configure could not determine which" \
-                               "library was used; thus no SSL crypto locking callbacks will be set, which may " \
-                               "cause random crashes on SSL requests"
 #              endif /* PHP_HTTP_HAVE_OPENSSL || PHP_HTTP_HAVE_GNUTLS */
 #      endif /* PHP_WIN32 */
 #endif /* ZTS && PHP_HTTP_HAVE_SSL */
index 403d781832c96ed1651b1edbff30a95aa895fa04..7f0462c78c1c5537e7ee2438fb74d2999836f368 100644 (file)
@@ -53,7 +53,6 @@ const char *php_http_encoding_dechunk(const char *encoded, size_t encoded_len, c
                                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Data does not seem to be chunked encoded");
                                memcpy(*decoded, encoded, encoded_len);
                                *decoded_len = encoded_len;
-                               decoded[*decoded_len] = '\0';
                                return encoded + encoded_len;
                        } else {
                                efree(*decoded);
index 4d6ef037471fb9bb02faf0a32f2773e052a631e1..c155dde3263bde5cba07c77ec108a4f7abd80077 100644 (file)
@@ -1096,7 +1096,11 @@ static PHP_METHOD(HttpEnvResponse, __invoke)
 
                php_http_message_object_init_body_object(obj);
                php_http_message_body_append(obj->message->body, ob_str, ob_len);
+#if PHP_VERSION_ID >= 50400
                RETURN_TRUE;
+#else
+               RETURN_EMPTY_STRING();
+#endif
        }
 }
 
index f560a8561a5917f241500b1c53a647f28e60a66e..ec41a240e66a8a4cf3881d86af759be0879df998 100644 (file)
@@ -62,7 +62,7 @@ php_http_header_parser_state_t php_http_header_parser_state_is(php_http_header_p
        php_http_header_parser_state_t state;
 
        if (parser->stack.top) {
-               return (php_http_header_parser_state_t) zend_ptr_stack_top(&parser->stack);
+               return (php_http_header_parser_state_t) parser->stack.elements[parser->stack.top - 1];
        }
 
        return PHP_HTTP_HEADER_PARSER_STATE_START;
index cc04edcf3850285742935ce626e74b76fdb816ef..70dcae82c933e68c9927b1dd5ed404a61b086e07 100644 (file)
@@ -98,6 +98,19 @@ php_http_message_t *php_http_message_init_env(php_http_message_t *message, php_h
                                        zval_dtor(&tval);
                                }
                        }
+#else
+                       if (OG(ob_nesting_level)) {
+                               if (php_get_output_start_filename(TSRMLS_C)) {
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch response body, output has already been sent at %s:%d", php_get_output_start_filename(TSRMLS_C), php_get_output_start_lineno(TSRMLS_C));
+                                       goto error;
+                               } else if (SUCCESS != php_ob_get_buffer(&tval TSRMLS_CC)) {
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch response body");
+                                       goto error;
+                               } else {
+                                       php_http_message_body_append(message->body, Z_STRVAL(tval), Z_STRLEN(tval));
+                                       zval_dtor(&tval);
+                               }
+                       }
 #endif
                        break;
                        
@@ -924,13 +937,11 @@ static HashTable *php_http_message_object_get_props(zval *object TSRMLS_DC)
 {
        zval *headers;
        php_http_message_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
-       php_http_message_t *msg = obj->message;
        HashTable *props = zend_get_std_object_handlers()->get_properties(object TSRMLS_CC);
        zval array, *parent, *body;
        char *version;
 
        PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
-       
        INIT_PZVAL_ARRAY(&array, props);
        
 #define ASSOC_PROP(ptype, n, val) \
@@ -951,20 +962,20 @@ static HashTable *php_http_message_object_get_props(zval *object TSRMLS_DC)
                } \
        } while(0)
 
-       ASSOC_PROP(long, "type", msg->type);
-       ASSOC_STRINGL_EX("httpVersion", version, spprintf(&version, 0, "%u.%u", msg->http.version.major, msg->http.version.minor), 0);
+       ASSOC_PROP(long, "type", obj->message->type);
+       ASSOC_STRINGL_EX("httpVersion", version, spprintf(&version, 0, "%u.%u", obj->message->http.version.major, obj->message->http.version.minor), 0);
 
-       switch (msg->type) {
+       switch (obj->message->type) {
                case PHP_HTTP_REQUEST:
                        ASSOC_PROP(long, "responseCode", 0);
                        ASSOC_STRINGL("responseStatus", "", 0);
-                       ASSOC_STRING("requestMethod", STR_PTR(msg->http.info.request.method));
-                       ASSOC_STRING("requestUrl", STR_PTR(msg->http.info.request.url));
+                       ASSOC_STRING("requestMethod", STR_PTR(obj->message->http.info.request.method));
+                       ASSOC_STRING("requestUrl", STR_PTR(obj->message->http.info.request.url));
                        break;
 
                case PHP_HTTP_RESPONSE:
-                       ASSOC_PROP(long, "responseCode", msg->http.info.response.code);
-                       ASSOC_STRING("responseStatus", STR_PTR(msg->http.info.response.status));
+                       ASSOC_PROP(long, "responseCode", obj->message->http.info.response.code);
+                       ASSOC_STRING("responseStatus", STR_PTR(obj->message->http.info.response.status));
                        ASSOC_STRINGL("requestMethod", "", 0);
                        ASSOC_STRINGL("requestUrl", "", 0);
                        break;
@@ -980,18 +991,19 @@ static HashTable *php_http_message_object_get_props(zval *object TSRMLS_DC)
 
        MAKE_STD_ZVAL(headers);
        array_init(headers);
-       zend_hash_copy(Z_ARRVAL_P(headers), &msg->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+       zend_hash_copy(Z_ARRVAL_P(headers), &obj->message->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
        ASSOC_PROP(zval, "headers", headers);
 
        MAKE_STD_ZVAL(body);
-       if (!obj->body) {
-               php_http_new(NULL, php_http_message_body_class_entry, (php_http_new_t) php_http_message_body_object_new_ex, NULL, (void *) php_http_message_body_init(&obj->message->body, NULL TSRMLS_CC), (void *) &obj->body TSRMLS_CC);
+       if (obj->body) {
+               ZVAL_OBJVAL(body, obj->body->zv, 1);
+       } else {
+               ZVAL_NULL(body);
        }
-       ZVAL_OBJVAL(body, obj->body->zv, 1);
        ASSOC_PROP(zval, "body", body);
 
        MAKE_STD_ZVAL(parent);
-       if (msg->parent) {
+       if (obj->message->parent) {
                ZVAL_OBJVAL(parent, obj->parent->zv, 1);
        } else {
                ZVAL_NULL(parent);
index 6328fa49e503a04944c618cb3ca56a38dcaccd57..0d11bf6aed153a2843ec87d6c5af85ae57021e07 100644 (file)
@@ -80,7 +80,7 @@ php_http_message_parser_state_t php_http_message_parser_state_push(php_http_mess
 php_http_message_parser_state_t php_http_message_parser_state_is(php_http_message_parser_t *parser)
 {
        if (parser->stack.top) {
-               return (php_http_message_parser_state_t) zend_ptr_stack_top(&parser->stack);
+               return (php_http_message_parser_state_t) parser->stack.elements[parser->stack.top - 1];
        }
        return PHP_HTTP_MESSAGE_PARSER_STATE_START;
 }
@@ -97,6 +97,7 @@ void php_http_message_parser_dtor(php_http_message_parser_t *parser)
 {
        php_http_header_parser_dtor(&parser->header);
        zend_ptr_stack_destroy(&parser->stack);
+       php_http_message_free(&parser->message);
        if (parser->dechunk) {
                php_http_encoding_stream_free(&parser->dechunk);
        }
@@ -508,6 +509,153 @@ php_http_message_parser_state_t php_http_message_parser_parse(php_http_message_p
        return php_http_message_parser_state_is(parser);
 }
 
+zend_class_entry *php_http_message_parser_class_entry;
+static zend_object_handlers php_http_message_parser_object_handlers;
+
+zend_object_value php_http_message_parser_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+       return php_http_message_parser_object_new_ex(ce, NULL, NULL TSRMLS_CC);
+}
+
+zend_object_value php_http_message_parser_object_new_ex(zend_class_entry *ce, php_http_message_parser_t *parser, php_http_message_parser_object_t **ptr TSRMLS_DC)
+{
+       php_http_message_parser_object_t *o;
+
+       o = ecalloc(1, sizeof(php_http_message_parser_object_t));
+       zend_object_std_init((zend_object *) o, ce TSRMLS_CC);
+       object_properties_init((zend_object *) o, ce);
+
+       if (ptr) {
+               *ptr = o;
+       }
+
+       if (parser) {
+               o->parser = parser;
+       } else {
+               o->parser = php_http_message_parser_init(NULL TSRMLS_CC);
+       }
+       o->buffer = php_http_buffer_new();
+
+       o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_http_message_parser_object_free, NULL TSRMLS_CC);
+       o->zv.handlers = &php_http_message_parser_object_handlers;
+
+       return o->zv;
+}
+
+void php_http_message_parser_object_free(void *object TSRMLS_DC)
+{
+       php_http_message_parser_object_t *o = (php_http_message_parser_object_t *) object;
+
+       if (o->parser) {
+               php_http_message_parser_free(&o->parser);
+       }
+       if (o->buffer) {
+               php_http_buffer_free(&o->buffer);
+       }
+       zend_object_std_dtor((zend_object *) o TSRMLS_CC);
+       efree(o);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageParser_getState, 0, 0, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpMessageParser, getState)
+{
+       php_http_message_parser_object_t *parser_obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+       zend_parse_parameters_none();
+       /* always return the real state */
+       RETVAL_LONG(php_http_message_parser_state_is(parser_obj->parser));
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageParser_parse, 0, 0, 3)
+       ZEND_ARG_INFO(0, data)
+       ZEND_ARG_INFO(0, flags)
+       ZEND_ARG_INFO(1, message)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpMessageParser, parse)
+{
+       php_http_message_parser_object_t *parser_obj;
+       zval *zmsg;
+       char *data_str;
+       int data_len;
+       long flags;
+
+       php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slz", &data_str, &data_len, &flags, &zmsg), invalid_arg, return);
+
+       parser_obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+       php_http_buffer_append(parser_obj->buffer, data_str, data_len);
+       RETVAL_LONG(php_http_message_parser_parse(parser_obj->parser, parser_obj->buffer, flags, &parser_obj->parser->message));
+
+       zval_dtor(zmsg);
+       if (parser_obj->parser->message) {
+                       ZVAL_OBJVAL(zmsg, php_http_message_object_new_ex(php_http_message_class_entry, php_http_message_copy(parser_obj->parser->message, NULL), NULL TSRMLS_CC), 0);
+               }
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessageParser_stream, 0, 0, 3)
+       ZEND_ARG_INFO(0, stream)
+       ZEND_ARG_INFO(0, flags)
+       ZEND_ARG_INFO(1, message)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpMessageParser, stream)
+{
+       php_http_message_parser_object_t *parser_obj;
+       zend_error_handling zeh;
+       zval *zmsg, *zstream;
+       php_stream *s;
+       long flags;
+
+       php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &zstream, &flags, &zmsg), invalid_arg, return);
+
+       zend_replace_error_handling(EH_THROW, php_http_exception_unexpected_val_class_entry, &zeh TSRMLS_CC);
+       php_stream_from_zval(s, &zstream);
+       zend_restore_error_handling(&zeh TSRMLS_CC);
+
+       parser_obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+       RETVAL_LONG(php_http_message_parser_parse_stream(parser_obj->parser, s, flags, &parser_obj->parser->message));
+
+       zval_dtor(zmsg);
+       if (parser_obj->parser->message) {
+               ZVAL_OBJVAL(zmsg, php_http_message_object_new_ex(php_http_message_class_entry, php_http_message_copy(parser_obj->parser->message, NULL), NULL TSRMLS_CC), 0);
+       }
+}
+
+static zend_function_entry php_http_message_parser_methods[] = {
+               PHP_ME(HttpMessageParser, getState, ai_HttpMessageParser_getState, ZEND_ACC_PUBLIC)
+               PHP_ME(HttpMessageParser, parse, ai_HttpMessageParser_parse, ZEND_ACC_PUBLIC)
+               PHP_ME(HttpMessageParser, stream, ai_HttpMessageParser_stream, ZEND_ACC_PUBLIC)
+               {NULL, NULL, NULL}
+};
+
+PHP_MINIT_FUNCTION(http_message_parser)
+{
+       zend_class_entry ce;
+
+       INIT_NS_CLASS_ENTRY(ce, "http\\Message", "Parser", php_http_message_parser_methods);
+       php_http_message_parser_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
+       memcpy(&php_http_message_parser_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+       php_http_message_parser_class_entry->create_object = php_http_message_parser_object_new;
+       php_http_message_parser_object_handlers.clone_obj = NULL;
+
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("CLEANUP"), PHP_HTTP_MESSAGE_PARSER_CLEANUP TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("DUMB_BODIES"), PHP_HTTP_MESSAGE_PARSER_DUMB_BODIES TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("EMPTY_REDIRECTS"), PHP_HTTP_MESSAGE_PARSER_EMPTY_REDIRECTS TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("GREEDY"), PHP_HTTP_MESSAGE_PARSER_GREEDY TSRMLS_CC);
+
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_FAILURE"), PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_START"), PHP_HTTP_MESSAGE_PARSER_STATE_START TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_HEADER"), PHP_HTTP_MESSAGE_PARSER_STATE_HEADER TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_HEADER_DONE"), PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY_DUMB"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY_LENGTH"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY_CHUNKED"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY_DONE"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_DONE"), PHP_HTTP_MESSAGE_PARSER_STATE_DONE TSRMLS_CC);
+
+       return SUCCESS;
+}
+
 /*
  * Local variables:
  * tab-width: 4
index ebc2142157bd3feb13021e53cfafe5abc6960352..5b04351678e430151e9102de2f40ec86e94bcd10 100644 (file)
@@ -56,6 +56,21 @@ PHP_HTTP_API void php_http_message_parser_free(php_http_message_parser_t **parse
 PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_parse(php_http_message_parser_t *parser, php_http_buffer_t *buffer, unsigned flags, php_http_message_t **message);
 PHP_HTTP_API php_http_message_parser_state_t php_http_message_parser_parse_stream(php_http_message_parser_t *parser, php_stream *s, unsigned flags, php_http_message_t **message);
 
+typedef struct php_http_message_parser_object {
+       zend_object zo;
+       zend_object_value zv;
+       php_http_buffer_t *buffer;
+       php_http_message_parser_t *parser;
+} php_http_message_parser_object_t;
+
+PHP_HTTP_API zend_class_entry *php_http_message_parser_class_entry;
+
+PHP_MINIT_FUNCTION(http_message_parser);
+
+zend_object_value php_http_message_parser_object_new(zend_class_entry *ce TSRMLS_DC);
+zend_object_value php_http_message_parser_object_new_ex(zend_class_entry *ce, php_http_message_parser_t *parser, php_http_message_parser_object_t **ptr TSRMLS_DC);
+void php_http_message_parser_object_free(void *object TSRMLS_DC);
+
 #endif
 
 /*
index 7afa006053299cb1215069e98c49a9a47c765e1d..8fcb82e2449f5f4a2dbb982b5a50a3e1ef60061f 100644 (file)
@@ -96,7 +96,7 @@ char *php_http_pretty_key(register char *key, size_t key_len, zend_bool uctitle,
                if ((wasalpha = PHP_HTTP_IS_CTYPE(alpha, key[0]))) {
                        key[0] = (char) (uctitle ? PHP_HTTP_TO_CTYPE(upper, key[0]) : PHP_HTTP_TO_CTYPE(lower, key[0]));
                }
-               PHP_HTTP_DUFF(1, key_len,
+               PHP_HTTP_DUFF(key_len,
                        if (PHP_HTTP_IS_CTYPE(alpha, key[i])) {
                                key[i] = (char) (((!wasalpha) && uctitle) ? PHP_HTTP_TO_CTYPE(upper, key[i]) : PHP_HTTP_TO_CTYPE(lower, key[i]));
                                wasalpha = 1;
index d47477c91ccaf87dc6256ae84bbef31d6c5fe14a..3bd77d8b931046006373445f7344476a7bd2a1b9 100644 (file)
@@ -65,48 +65,44 @@ size_t php_http_boundary(char *buf, size_t len TSRMLS_DC);
 int php_http_select_str(const char *cmp, int argc, ...);
 
 /* See "A Reusable Duff Device" By Ralf Holly, August 01, 2005 */
-#define PHP_HTTP_DUFF_BREAK(i) do { \
-       times_##i = 1; \
-} while (0)
-
-#define PHP_HTTP_DUFF(i, c, a) do { \
-               size_t count_##i = (c); \
-               size_t times_##i = (count_##i + 7) >> 3; \
-               switch (count_##i & 7){ \
-               case 0: do { a; \
-               case 7: a; \
-               case 6: a; \
-               case 5: a; \
-               case 4: a; \
-               case 3: a; \
-               case 2: a; \
-               case 1: a; \
-               } while (--times_##i > 0); \
+#define PHP_HTTP_DUFF_BREAK() times_=1
+#define PHP_HTTP_DUFF(c, a) do { \
+       size_t count_ = (c); \
+       size_t times_ = (count_ + 7) >> 3; \
+       switch (count_ & 7){ \
+               case 0: do { \
+                       a; \
+               case 7: \
+                       a; \
+               case 6: \
+                       a; \
+               case 5: \
+                       a; \
+               case 4: \
+                       a; \
+               case 3: \
+                       a; \
+               case 2: \
+                       a; \
+               case 1: \
+                       a; \
+                                       } while (--times_ > 0); \
        } \
 } while (0)
 
-
 static inline const char *php_http_locate_str(register const char *h, size_t h_len, const char *n, size_t n_len)
 {
-       register const char *p1, *p2;
-
-       if (n_len && h_len && h_len >= n_len) {
-               PHP_HTTP_DUFF(1, h_len - n_len + 1,
-                       if (*h == *n) {
-                               p1 = h;
-                               p2 = n;
-                               PHP_HTTP_DUFF(2, n_len,
-                                       if (*p1++ != *p2++) {
-                                               PHP_HTTP_DUFF_BREAK(2);
-                                       } else if (p2 == n + n_len - 1) {
-                                               return h;
-                                       }
-                               );
-                       }
-                       ++h;
-               );
+       if (!n_len || !h_len || h_len < n_len) {
+               return NULL;
        }
 
+       PHP_HTTP_DUFF(h_len - n_len + 1,
+               if (*h == *n && !strncmp(h + 1, n + 1, n_len - 1)) {
+                       return h;
+               }
+               ++h;
+       );
+
        return NULL;
 }
 
@@ -125,7 +121,7 @@ static inline const char *php_http_locate_bin_eol(const char *bin, size_t len, i
        register const char *eol = bin;
 
        if (len > 0) {
-               PHP_HTTP_DUFF(1, len,
+               PHP_HTTP_DUFF(len,
                        if (*eol == '\r' || *eol == '\n') {
                                if (eol_len) {
                                        *eol_len = ((eol[0] == '\r' && eol[1] == '\n') ? 2 : 1);
index 65504ac660155e6d40da74c98d8e7b0d4b15b7cc..523424423d3b21ce15704d4804cae4dd73fc1daa 100644 (file)
@@ -224,6 +224,10 @@ static inline void sanitize_key(unsigned flags, char *str, size_t len, zval *zv,
        if (flags & PHP_HTTP_PARAMS_ESCAPED) {
                sanitize_escaped(zv TSRMLS_CC);
        }
+       
+       if (!Z_STRLEN_P(zv)) {
+               return;
+       }
 
        eos = &Z_STRVAL_P(zv)[Z_STRLEN_P(zv)-1];
        if (*eos == '*') {
@@ -253,7 +257,7 @@ static inline void sanitize_rfc5987(zval *zv, char **language, zend_bool *latin1
        switch (Z_STRVAL_P(zv)[0]) {
        case 'I':
        case 'i':
-               if (!strncasecmp(Z_STRVAL_P(zv), ZEND_STRL("iso-8859-1"))) {
+               if (!strncasecmp(Z_STRVAL_P(zv), "iso-8859-1", lenof("iso-8859-1"))) {
                        *latin1 = 1;
                        ptr = Z_STRVAL_P(zv) + lenof("iso-8859-1");
                        break;
@@ -261,7 +265,7 @@ static inline void sanitize_rfc5987(zval *zv, char **language, zend_bool *latin1
                /* no break */
        case 'U':
        case 'u':
-               if (!strncasecmp(Z_STRVAL_P(zv), ZEND_STRL("utf-8"))) {
+               if (!strncasecmp(Z_STRVAL_P(zv), "utf-8", lenof("utf-8"))) {
                        *latin1 = 0;
                        ptr = Z_STRVAL_P(zv) + lenof("utf-8");
                        break;
index c4eb90b5d34d395ccb2acd9dacf42f235b4af0f2..7c8077b6a31995208a8a16da0ed6789d68bd2878 100644 (file)
@@ -42,94 +42,6 @@ static inline char *localhostname(void)
        return estrndup("localhost", lenof("localhost"));
 }
 
-static inline unsigned port(const char *scheme)
-{
-       unsigned port = 80;
-
-#if defined(ZTS) && defined(HAVE_GETSERVBYPORT_R)
-       int rc;
-       size_t len = 0xff;
-       char *buf = NULL;
-       struct servent *se_res = NULL, se_buf = {0};
-
-       do {
-               buf = erealloc(buf, len);
-               rc = getservbyname_r(scheme, "tcp", &se_buf, buf, len, &se_res);
-               len *= 2;
-       } while (rc == ERANGE && len <= 0xfff);
-
-       if (!rc) {
-               port = ntohs(se_res->s_port);
-       }
-
-       efree(buf);
-#elif !defined(ZTS) && defined(HAVE_GETSERVBYPORT)
-       struct servent *se;
-
-       if ((se = getservbyname(scheme, "tcp")) && se->s_port) {
-               port = ntohs(se->s_port);
-       }
-#endif
-
-       return port;
-}
-static inline char *scheme(unsigned port)
-{
-       char *scheme;
-#if defined(ZTS) && defined(HAVE_GETSERVBYPORT_R)
-       int rc;
-       size_t len = 0xff;
-       char *buf = NULL;
-       struct servent *se_res = NULL, se_buf = {0};
-#elif !defined(ZTS) && defined(HAVE_GETSERVBYPORT)
-       struct servent *se;
-#endif
-
-       switch (port) {
-       case 443:
-               scheme = estrndup("https", lenof("https"));
-               break;
-
-#if defined(ZTS) && !defined(HAVE_GETSERVBYPORT_R)
-       default:
-#elif !defined(ZTS) && !defined(HAVE_GETSERVBYPORT)
-       default:
-#endif
-       case 80:
-       case 0:
-               scheme = estrndup("http", lenof("http"));
-               break;
-
-#if defined(ZTS) && defined(HAVE_GETSERVBYPORT_R)
-       default:
-               do {
-                       buf = erealloc(buf, len);
-                       rc = getservbyport_r(htons(port), "tcp", &se_buf, buf, len, &se_res);
-                       len *= 2;
-               } while (rc == ERANGE && len <= 0xfff);
-
-               if (!rc && se_res) {
-                       scheme = estrdup(se_res->s_name);
-               } else {
-                       scheme = estrndup("http", lenof("http"));
-               }
-
-               efree(buf);
-               break;
-
-#elif !defined(ZTS) && defined(HAVE_GETSERVBYPORT)
-       default:
-               if ((se = getservbyport(htons(port), "tcp")) && se->s_name) {
-                       scheme = estrdup(se->s_name);
-               } else {
-                       scheme = estrndup("http", lenof("http"));
-               }
-               break;
-#endif
-       }
-       return scheme;
-}
-
 static php_url *php_http_url_from_env(php_url *url TSRMLS_DC)
 {
        zval *https, *zhost, *zport;
@@ -150,7 +62,7 @@ static php_url *php_http_url_from_env(php_url *url TSRMLS_DC)
        if (https && !strcasecmp(Z_STRVAL_P(https), "ON")) {
                url->scheme = estrndup("https", lenof("https"));
        } else {
-               url->scheme = scheme(url->port);
+               url->scheme = estrndup("http", lenof("http"));
        }
 
        /* host */
@@ -339,7 +251,6 @@ void php_http_url(int flags, const php_url *old_url, const php_url *new_url, php
        if (url->port) {
                if (    ((url->port == 80) && !strcmp(url->scheme, "http"))
                        ||      ((url->port ==443) && !strcmp(url->scheme, "https"))
-                       ||      ( url->port == port(url->scheme))
                ) {
                        url->port = 0;
                }
diff --git a/tests/client015.phpt b/tests/client015.phpt
new file mode 100644 (file)
index 0000000..35981a5
--- /dev/null
@@ -0,0 +1,41 @@
+--TEST--
+http client event base
+--SKIPIF--
+<?php 
+include "skipif.inc";
+try {
+       $client = new http\Client;
+       if (!$client->enableEvents())
+               throw new Exception("need events support"); 
+} catch (Exception $e) {
+       die("skip ".$e->getMessage()); 
+}
+?>
+--FILE--
+<?php
+echo "Test\n";
+
+$client1 = new http\Client;
+$client2 = new http\Client;
+
+$client1->enableEvents();
+$client2->enableEvents();
+
+$client1->enqueue(new http\Client\Request("GET", "http://www.google.ca/"));
+$client2->enqueue(new http\Client\Request("GET", "http://www.google.co.uk/"));
+
+$client1->send();
+
+if (($r = $client1->getResponse())) {
+       var_dump($r->getTransferInfo("response_code"));
+}
+if (($r = $client2->getResponse())) {
+       var_dump($r->getTransferInfo("response_code"));
+}
+
+?>
+DONE
+--EXPECT--
+Test
+int(200)
+DONE
index 52776d4b1c5245ff55462377ff676692322c0e30..b3284cfbb1bb8ecdf9ad8c8c724612075778d6d7 100644 (file)
@@ -2,7 +2,7 @@ PUT /docs/ HTTP/1.1
 User-Agent: curl/7.24.0 (x86_64-unknown-linux-gnu) libcurl/7.24.0 OpenSSL/1.0.0g zlib/1.2.6 libssh2/1.3.0
 Host: drop
 Accept: */*
-Content-Length: 2284
+Content-Length: 2273
 Expect: 100-continue
 Content-Type: multipart/form-data; boundary=----------------------------6e182425881c
 
index 11b83f6168ec83812cb82bb1ff04e482c7db1784..370d70ee5e157eda4aeb375f58c4b0c950d8c2e8 100644 (file)
@@ -40,8 +40,7 @@ object(http\Message)#%d (9) {
   ["type":protected]=>
   int(1)
   ["body":protected]=>
-  object(http\Message\Body)#%d (0) {
-  }
+  NULL
   ["requestMethod":protected]=>
   string(3) "GET"
   ["requestUrl":protected]=>
index 403fb262e7bf8add86d6f6105208b13359f5e7c1..0809676e8dc797273d595efb787ba841c142afba 100644 (file)
@@ -37,8 +37,7 @@ object(%s)#%d (12) {
   ["type":protected]=>
   int(1)
   ["body":protected]=>
-  object(http\Message\Body)#%d (0) {
-  }
+  NULL
   ["requestMethod":protected]=>
   string(4) "POST"
   ["requestUrl":protected]=>
index 52e534ddb8c84131ffd6de7ac9e0f94289190fde..4d1a69388e35b5a8e9deae4ecab16b22cec5e8c8 100644 (file)
@@ -29,8 +29,7 @@ object(c)#%d (9) {
   ["type":protected]=>
   int(0)
   ["body":protected]=>
-  object(http\Message\Body)#%d (0) {
-  }
+  NULL
   ["requestMethod":protected]=>
   string(0) ""
   ["requestUrl":protected]=>
diff --git a/tests/messageparser001.phpt b/tests/messageparser001.phpt
new file mode 100644 (file)
index 0000000..f4ec2d9
--- /dev/null
@@ -0,0 +1,53 @@
+--TEST--
+message parser
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+
+echo "Test\n";
+
+use http\Message\Parser;
+
+foreach (glob(__DIR__."/data/message_*.txt") as $file) {
+       $parser = new Parser;
+       $fd = fopen($file, "r") or die("Could not open $file");
+       while (!feof($fd)) {
+               switch ($parser->parse(fgets($fd), 0, $message)) {
+               case Parser::STATE_DONE:
+                       $string = (string) $message;
+                       break 2;
+               case Parser::STATE_FAILURE:
+                       throw new Exception(($e = error_get_last()) ? $e["message"] : "Could not parse $file");
+               }
+       }
+
+       $parser = new Parser;
+       rewind($fd);
+       unset($message);
+
+       switch ($parser->stream($fd, 0, $message)) {
+       case Parser::STATE_DONE:
+       case Parser::STATE_START:
+               break;
+       default:
+               printf("Expected parser state 0 or 8, got %d", $parser->getState());
+       }
+       if ($string !== (string) $message) {
+               $a = explode("\n", $string);
+               $b = explode("\n", (string) $message);
+               while ((null !== ($aa = array_shift($a))) || (null !== ($bb = array_shift($b)))) {
+                       if ($aa !== $bb) {
+                               isset($aa) and printf("-- %s\n", $aa);
+                               isset($bb) and printf("++ %s\n", $bb);
+                       }
+               }
+       }
+}
+?>
+DONE
+--EXPECT--
+Test
+DONE
index ad3948cb0581cda7dd60ec86a4c4a36768f30eb0..7501167971d0a0dcc5b573d1f325ee6390d772ec 100644 (file)
@@ -7,7 +7,7 @@ include "skipif.inc";
 --FILE--
 <?php
 echo "Test\n";
-$p = new http\Params(["attachment"=>["filename"=>"foo.bar"]]);
+$p = new http\Params(array("attachment"=>array("filename"=>"foo.bar")));
 var_dump($p->params);
 var_dump((string)$p);
 ?>