* split request and response message parsers, so the "100 Continue" response does...
authorMichael Wallner <mike@php.net>
Wed, 30 May 2012 11:10:08 +0000 (11:10 +0000)
committerMichael Wallner <mike@php.net>
Wed, 30 May 2012 11:10:08 +0000 (11:10 +0000)
* make sure that message headers are updated by inspecting the body prior sending the request
* add http\Message\Body::getResource()

php_http_client.c
php_http_client.h
php_http_curl_client.c
php_http_env_request.c
php_http_message.c
php_http_message.h
php_http_message_body.c
php_http_message_body.h

index 47c7ef4..f131136 100644 (file)
@@ -29,9 +29,13 @@ PHP_HTTP_API php_http_client_t *php_http_client_init(php_http_client_t *h, php_h
        } else if (ops->rsrc) {
                h->rf = php_http_resource_factory_init(NULL, h->ops->rsrc, h, NULL);
        }
-       h->buffer = php_http_buffer_init(NULL);
-       h->parser = php_http_message_parser_init(NULL TSRMLS_CC);
-       h->message = php_http_message_init(NULL, 0 TSRMLS_CC);
+       h->request.buffer = php_http_buffer_init(NULL);
+       h->request.parser = php_http_message_parser_init(NULL TSRMLS_CC);
+       h->request.message = php_http_message_init(NULL, 0 TSRMLS_CC);
+
+       h->response.buffer = php_http_buffer_init(NULL);
+       h->response.parser = php_http_message_parser_init(NULL TSRMLS_CC);
+       h->response.message = php_http_message_init(NULL, 0 TSRMLS_CC);
 
        TSRMLS_SET_CTX(h->ts);
 
@@ -56,9 +60,13 @@ PHP_HTTP_API void php_http_client_dtor(php_http_client_t *h)
 
        php_http_resource_factory_free(&h->rf);
 
-       php_http_message_parser_free(&h->parser);
-       php_http_message_free(&h->message);
-       php_http_buffer_free(&h->buffer);
+       php_http_message_parser_free(&h->request.parser);
+       php_http_message_free(&h->request.message);
+       php_http_buffer_free(&h->request.buffer);
+
+       php_http_message_parser_free(&h->response.parser);
+       php_http_message_free(&h->response.message);
+       php_http_buffer_free(&h->response.buffer);
 }
 
 PHP_HTTP_API void php_http_client_free(php_http_client_t **h)
@@ -88,9 +96,14 @@ PHP_HTTP_API php_http_client_t *php_http_client_copy(php_http_client_t *from, ph
                } else if (to->ops->rsrc){
                        to->rf = php_http_resource_factory_init(NULL, to->ops->rsrc, to, NULL);
                }
-               to->buffer = php_http_buffer_init(NULL);
-               to->parser = php_http_message_parser_init(NULL TSRMLS_CC);
-               to->message = php_http_message_init(NULL, 0 TSRMLS_CC);
+
+               to->request.buffer = php_http_buffer_init(NULL);
+               to->request.parser = php_http_message_parser_init(NULL TSRMLS_CC);
+               to->request.message = php_http_message_init(NULL, 0 TSRMLS_CC);
+
+               to->response.buffer = php_http_buffer_init(NULL);
+               to->response.parser = php_http_message_parser_init(NULL TSRMLS_CC);
+               to->response.message = php_http_message_init(NULL, 0 TSRMLS_CC);
 
                TSRMLS_SET_CTX(to->ts);
 
@@ -358,7 +371,7 @@ STATUS php_http_client_object_handle_request(zval *zclient, zval **zreq TSRMLS_D
        php_http_client_reset(obj->client);
 
        /* reset transfer info */
-       zend_update_property_null(php_http_client_class_entry, zclient, ZEND_STRL("info") TSRMLS_CC);
+       zend_update_property_null(php_http_client_class_entry, zclient, ZEND_STRL("transferInfo") TSRMLS_CC);
 
        /* set client options */
        zoptions = zend_read_property(php_http_client_class_entry, zclient, ZEND_STRL("options"), 0 TSRMLS_CC);
@@ -405,8 +418,8 @@ STATUS php_http_client_object_handle_response(zval *zclient TSRMLS_DC)
        zend_update_property(php_http_client_class_entry, zclient, ZEND_STRL("transferInfo"), info TSRMLS_CC);
        zval_ptr_dtor(&info);
 
-       if ((msg = obj->client->message)) {
-               /* update history */
+       if ((msg = obj->client->response.message)) {
+               /* FIXME: update history */
                if (i_zend_is_true(zend_read_property(php_http_client_class_entry, zclient, ZEND_STRL("recordHistory"), 0 TSRMLS_CC))) {
                        zval *new_hist, *old_hist = zend_read_property(php_http_client_class_entry, zclient, ZEND_STRL("history"), 0 TSRMLS_CC);
                        zend_object_value ov = php_http_client_object_message(zclient, php_http_message_copy(msg, NULL) TSRMLS_CC);
@@ -431,8 +444,7 @@ STATUS php_http_client_object_handle_response(zval *zclient TSRMLS_DC)
                        zend_update_property(php_http_client_class_entry, zclient, ZEND_STRL("responseMessage"), message TSRMLS_CC);
                        zval_ptr_dtor(&message);
 
-                       obj->client->message = php_http_message_init(NULL, 0 TSRMLS_CC);
-                       msg = msg->parent;
+                       obj->client->response.message = php_http_message_init(NULL, 0 TSRMLS_CC);
                } else {
                        zend_update_property_null(php_http_client_class_entry, zclient, ZEND_STRL("responseMessage") TSRMLS_CC);
                }
@@ -440,19 +452,17 @@ STATUS php_http_client_object_handle_response(zval *zclient TSRMLS_DC)
                zend_update_property_null(php_http_client_class_entry, zclient, ZEND_STRL("responseMessage") TSRMLS_CC);
        }
 
-       /* there might be a 100-Continue response in between */
-       while (msg && !PHP_HTTP_MESSAGE_TYPE(REQUEST, msg)) {
-               msg = msg->parent;
-       }
-
-       if (PHP_HTTP_MESSAGE_TYPE(REQUEST, msg)) {
-               zval *message;
+       if ((msg = obj->client->request.message)) {
+               if (PHP_HTTP_MESSAGE_TYPE(REQUEST, msg)) {
+                       zval *message;
 
-               /* update the actual request message */
-               MAKE_STD_ZVAL(message);
-               ZVAL_OBJVAL(message, php_http_message_object_new_ex(php_http_message_get_class_entry(), php_http_message_copy_ex(msg, NULL, 0), NULL TSRMLS_CC), 0);
-               zend_update_property(php_http_client_class_entry, zclient, ZEND_STRL("requestMessage"), message TSRMLS_CC);
-               zval_ptr_dtor(&message);
+                       /* update the actual request message */
+                       MAKE_STD_ZVAL(message);
+                       ZVAL_OBJVAL(message, php_http_message_object_new_ex(php_http_message_get_class_entry(), php_http_message_copy_ex(msg, NULL, 0), NULL TSRMLS_CC), 0);
+                       zend_update_property(php_http_client_class_entry, zclient, ZEND_STRL("requestMessage"), message TSRMLS_CC);
+                       zval_ptr_dtor(&message);
+                       obj->client->request.message = php_http_message_init(NULL, 0 TSRMLS_CC);
+               }
        }
 
        if (SUCCESS == php_http_client_getopt(obj->client, PHP_HTTP_CLIENT_OPT_PROGRESS_INFO, &progress)) {
index 93a910c..8e3d8b4 100644 (file)
@@ -144,9 +144,16 @@ typedef struct php_http_client {
        void *ctx;
        php_http_resource_factory_t *rf;
        php_http_client_ops_t *ops;
-       php_http_message_parser_t *parser;
-       php_http_message_t *message;
-       php_http_buffer_t *buffer;
+       struct {
+               php_http_message_parser_t *parser;
+               php_http_message_t *message;
+               php_http_buffer_t *buffer;
+       } request;
+       struct {
+               php_http_message_parser_t *parser;
+               php_http_message_t *message;
+               php_http_buffer_t *buffer;
+       } response;
 #ifdef ZTS
        void ***ts;
 #endif
index 7f4d005..97b04a2 100644 (file)
@@ -175,15 +175,22 @@ static int php_http_curl_client_raw_callback(CURL *ch, curl_infotype type, char
        switch (type) {
                case CURLINFO_HEADER_IN:
                case CURLINFO_DATA_IN:
-               case CURLINFO_HEADER_OUT:
-               case CURLINFO_DATA_OUT:
-                       php_http_buffer_append(h->buffer, data, length);
+                       php_http_buffer_append(h->response.buffer, data, length);
 
                        if (curl->options.redirects) {
                                flags |= PHP_HTTP_MESSAGE_PARSER_EMPTY_REDIRECTS;
                        }
 
-                       if (PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE == php_http_message_parser_parse(h->parser, h->buffer, flags, &h->message)) {
+                       if (PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE == php_http_message_parser_parse(h->response.parser, h->response.buffer, flags, &h->response.message)) {
+                               return -1;
+                       }
+                       break;
+
+               case CURLINFO_HEADER_OUT:
+               case CURLINFO_DATA_OUT:
+                       php_http_buffer_append(h->request.buffer, data, length);
+
+                       if (PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE == php_http_message_parser_parse(h->request.parser, h->request.buffer, flags, &h->request.message)) {
                                return -1;
                        }
                        break;
@@ -1075,6 +1082,7 @@ PHP_HTTP_API STATUS php_http_curl_client_prepare(php_http_client_t *h, php_http_
        }
 
        /* request headers */
+       php_http_message_update_headers(msg);
        if (zend_hash_num_elements(&msg->hdrs)) {
                php_http_array_hashkey_t header_key = php_http_array_hashkey_init(0);
                zval **header_val;
index 3e88bd0..cbb7fb4 100644 (file)
@@ -130,6 +130,7 @@ PHP_METHOD(HttpEnvRequest, __construct)
                        zval *zsg;
 
                        obj->message = php_http_message_init_env(obj->message, PHP_HTTP_REQUEST TSRMLS_CC);
+                       obj->body.handle = 0;
 
                        if ((zsg = php_http_env_get_superglobal(ZEND_STRL("_GET") TSRMLS_CC))) {
                                zval *zquery;
index e85c7d3..34d9ed8 100644 (file)
@@ -277,27 +277,12 @@ PHP_HTTP_API void php_http_message_set_info(php_http_message_t *message, php_htt
        }
 }
 
-static inline void message_headers(php_http_message_t *msg, php_http_buffer_t *str)
+PHP_HTTP_API void php_http_message_update_headers(php_http_message_t *msg)
 {
-       php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
-       HashPosition pos1;
-       zval **header, *h;
+       zval *h;
        size_t size;
        TSRMLS_FETCH_FROM_CTX(msg->ts);
 
-       switch (msg->type) {
-               case PHP_HTTP_REQUEST:
-                       php_http_buffer_appendf(str, PHP_HTTP_INFO_REQUEST_FMT_ARGS(&msg->http, PHP_HTTP_CRLF));
-                       break;
-
-               case PHP_HTTP_RESPONSE:
-                       php_http_buffer_appendf(str, PHP_HTTP_INFO_RESPONSE_FMT_ARGS(&msg->http, PHP_HTTP_CRLF));
-                       break;
-
-               default:
-                       break;
-       }
-
        if ((size = php_http_message_body_size(&msg->body))) {
                MAKE_STD_ZVAL(h);
                ZVAL_LONG(h, size);
@@ -321,6 +306,28 @@ static inline void message_headers(php_http_message_t *msg, php_http_buffer_t *s
                        }
                }
        }
+}
+static inline void message_headers(php_http_message_t *msg, php_http_buffer_t *str)
+{
+       php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
+       HashPosition pos1;
+       zval **header;
+       TSRMLS_FETCH_FROM_CTX(msg->ts);
+
+       switch (msg->type) {
+               case PHP_HTTP_REQUEST:
+                       php_http_buffer_appendf(str, PHP_HTTP_INFO_REQUEST_FMT_ARGS(&msg->http, PHP_HTTP_CRLF));
+                       break;
+
+               case PHP_HTTP_RESPONSE:
+                       php_http_buffer_appendf(str, PHP_HTTP_INFO_RESPONSE_FMT_ARGS(&msg->http, PHP_HTTP_CRLF));
+                       break;
+
+               default:
+                       break;
+       }
+
+       php_http_message_update_headers(msg);
 
        FOREACH_HASH_KEYVAL(pos1, &msg->hdrs, key, header) {
                if (key.type == HASH_KEY_IS_STRING) {
index 8ebcecf..fb991f5 100644 (file)
@@ -50,6 +50,8 @@ PHP_HTTP_API void php_http_message_free(php_http_message_t **message);
 PHP_HTTP_API void php_http_message_set_type(php_http_message_t *m, php_http_message_type_t t);
 PHP_HTTP_API void php_http_message_set_info(php_http_message_t *message, php_http_info_t *info);
 
+PHP_HTTP_API void php_http_message_update_headers(php_http_message_t *msg);
+
 PHP_HTTP_API zval *php_http_message_header(php_http_message_t *msg, char *key_str, size_t key_len, int join);
 PHP_HTTP_API zend_bool php_http_message_is_multipart(php_http_message_t *msg, char **boundary);
 
index c4c3f9d..aeadb18 100644 (file)
@@ -543,6 +543,8 @@ PHP_HTTP_BEGIN_ARGS(toCallback, 1)
        PHP_HTTP_ARG_VAL(callback, 0)
 PHP_HTTP_END_ARGS;
 
+PHP_HTTP_EMPTY_ARGS(getResource);
+
 PHP_HTTP_BEGIN_ARGS(append, 1)
        PHP_HTTP_ARG_VAL(string, 0)
 PHP_HTTP_END_ARGS;
@@ -575,6 +577,7 @@ static zend_function_entry php_http_message_body_method_entry[] = {
        PHP_MALIAS(HttpMessageBody, toString, __toString, args_for_HttpMessageBody___toString, ZEND_ACC_PUBLIC)
        PHP_HTTP_MESSAGE_BODY_ME(toStream, ZEND_ACC_PUBLIC)
        PHP_HTTP_MESSAGE_BODY_ME(toCallback, ZEND_ACC_PUBLIC)
+       PHP_HTTP_MESSAGE_BODY_ME(getResource, ZEND_ACC_PUBLIC)
        PHP_HTTP_MESSAGE_BODY_ME(append, ZEND_ACC_PUBLIC)
        PHP_HTTP_MESSAGE_BODY_ME(addForm, ZEND_ACC_PUBLIC)
        PHP_HTTP_MESSAGE_BODY_ME(addPart, ZEND_ACC_PUBLIC)
@@ -722,6 +725,15 @@ PHP_METHOD(HttpMessageBody, toCallback)
        RETURN_FALSE;
 }
 
+PHP_METHOD(HttpMessageBody, getResource)
+{
+       if (SUCCESS == zend_parse_parameters_none()) {
+               php_http_message_body_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+               RETVAL_RESOURCE(obj->body->stream_id);
+       }
+}
+
 PHP_METHOD(HttpMessageBody, append)
 {
        char *str;
index 4e3fae9..7fc6e56 100644 (file)
@@ -67,6 +67,7 @@ void php_http_message_body_object_free(void *object TSRMLS_DC);
 
 PHP_METHOD(HttpMessageBody, __construct);
 PHP_METHOD(HttpMessageBody, __toString);
+PHP_METHOD(HttpMessageBody, getResource);
 PHP_METHOD(HttpMessageBody, toStream);
 PHP_METHOD(HttpMessageBody, toCallback);
 PHP_METHOD(HttpMessageBody, append);