release 2.4.0
[m6w6/ext-http] / php_http_message.c
index 1219d5dcf59373e9476b1561c35adc9ffde7834d..3b19a8c8f2dc1ba94fe6812542ac04df4b4f4429 100644 (file)
@@ -253,12 +253,12 @@ void php_http_message_set_type(php_http_message_t *message, php_http_message_typ
                /* free request info */
                switch (message->type) {
                        case PHP_HTTP_REQUEST:
-                               STR_FREE(message->http.info.request.method);
-                               STR_FREE(message->http.info.request.url);
+                               PTR_FREE(message->http.info.request.method);
+                               PTR_FREE(message->http.info.request.url);
                                break;
                        
                        case PHP_HTTP_RESPONSE:
-                               STR_FREE(message->http.info.response.status);
+                               PTR_FREE(message->http.info.response.status);
                                break;
                        
                        default:
@@ -276,13 +276,13 @@ void php_http_message_set_info(php_http_message_t *message, php_http_info_t *inf
        message->http.version = info->http.version;
        switch (message->type) {
                case PHP_HTTP_REQUEST:
-                       STR_SET(PHP_HTTP_INFO(message).request.url, PHP_HTTP_INFO(info).request.url ? php_http_url_copy(PHP_HTTP_INFO(info).request.url, 0) : NULL);
-                       STR_SET(PHP_HTTP_INFO(message).request.method, PHP_HTTP_INFO(info).request.method ? estrdup(PHP_HTTP_INFO(info).request.method) : NULL);
+                       PTR_SET(PHP_HTTP_INFO(message).request.url, PHP_HTTP_INFO(info).request.url ? php_http_url_copy(PHP_HTTP_INFO(info).request.url, 0) : NULL);
+                       PTR_SET(PHP_HTTP_INFO(message).request.method, PHP_HTTP_INFO(info).request.method ? estrdup(PHP_HTTP_INFO(info).request.method) : NULL);
                        break;
                
                case PHP_HTTP_RESPONSE:
                        PHP_HTTP_INFO(message).response.code = PHP_HTTP_INFO(info).response.code;
-                       STR_SET(PHP_HTTP_INFO(message).response.status, PHP_HTTP_INFO(info).response.status ? estrdup(PHP_HTTP_INFO(info).response.status) : NULL);
+                       PTR_SET(PHP_HTTP_INFO(message).response.status, PHP_HTTP_INFO(info).response.status ? estrdup(PHP_HTTP_INFO(info).response.status) : NULL);
                        break;
                
                default:
@@ -297,6 +297,9 @@ void php_http_message_update_headers(php_http_message_t *msg)
 
        if (php_http_message_body_stream(msg->body)->readfilters.head) {
                /* if a read stream filter is attached to the body the caller must also care for the headers */
+       } else if ((h = php_http_message_header(msg, ZEND_STRL("Content-Range"), 0))) {
+               /* don't mess around with a Content-Range message */
+               zval_ptr_dtor(&h);
        } else if ((size = php_http_message_body_size(msg->body))) {
                MAKE_STD_ZVAL(h);
                ZVAL_LONG(h, size);
@@ -324,6 +327,7 @@ void php_http_message_update_headers(php_http_message_t *msg)
 
                zval_ptr_dtor(&h);
                if (Z_LVAL_P(h_cpy)) {
+                       /* body->size == 0, so get rid of old Content-Length */
                        zend_hash_del(&msg->hdrs, "Content-Length", sizeof("Content-Length"));
                }
                zval_ptr_dtor(&h_cpy);
@@ -338,12 +342,12 @@ static void message_headers(php_http_message_t *msg, php_http_buffer_t *str)
        switch (msg->type) {
                case PHP_HTTP_REQUEST:
                        php_http_buffer_appendf(str, PHP_HTTP_INFO_REQUEST_FMT_ARGS(&msg->http, tmp, PHP_HTTP_CRLF));
-                       STR_FREE(tmp);
+                       PTR_FREE(tmp);
                        break;
 
                case PHP_HTTP_RESPONSE:
                        php_http_buffer_appendf(str, PHP_HTTP_INFO_RESPONSE_FMT_ARGS(&msg->http, tmp, PHP_HTTP_CRLF));
-                       STR_FREE(tmp);
+                       PTR_FREE(tmp);
                        break;
 
                default:
@@ -499,12 +503,12 @@ void php_http_message_dtor(php_http_message_t *message)
                
                switch (message->type) {
                        case PHP_HTTP_REQUEST:
-                               STR_SET(message->http.info.request.method, NULL);
-                               STR_SET(message->http.info.request.url, NULL);
+                               PTR_SET(message->http.info.request.method, NULL);
+                               PTR_SET(message->http.info.request.url, NULL);
                                break;
                        
                        case PHP_HTTP_RESPONSE:
-                               STR_SET(message->http.info.response.status, NULL);
+                               PTR_SET(message->http.info.response.status, NULL);
                                break;
                        
                        default:
@@ -539,11 +543,11 @@ typedef struct php_http_message_object_prophandler {
        php_http_message_object_prophandler_func_t write;
 } php_http_message_object_prophandler_t;
 
-static STATUS php_http_message_object_add_prophandler(const char *prop_str, size_t prop_len, php_http_message_object_prophandler_func_t read, php_http_message_object_prophandler_func_t write) {
+static ZEND_RESULT_CODE php_http_message_object_add_prophandler(const char *prop_str, size_t prop_len, php_http_message_object_prophandler_func_t read, php_http_message_object_prophandler_func_t write) {
        php_http_message_object_prophandler_t h = { read, write };
        return zend_hash_add(&php_http_message_object_prophandlers, prop_str, prop_len + 1, (void *) &h, sizeof(h), NULL);
 }
-static STATUS php_http_message_object_get_prophandler(const char *prop_str, size_t prop_len, php_http_message_object_prophandler_t **handler) {
+static ZEND_RESULT_CODE php_http_message_object_get_prophandler(const char *prop_str, size_t prop_len, php_http_message_object_prophandler_t **handler) {
        return zend_hash_find(&php_http_message_object_prophandlers, prop_str, prop_len + 1, (void *) handler);
 }
 static void php_http_message_object_prophandler_get_type(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) {
@@ -564,7 +568,7 @@ static void php_http_message_object_prophandler_get_request_method(php_http_mess
 static void php_http_message_object_prophandler_set_request_method(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
        if (PHP_HTTP_MESSAGE_TYPE(REQUEST, obj->message)) {
                zval *cpy = php_http_ztyp(IS_STRING, value);
-               STR_SET(obj->message->http.info.request.method, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
+               PTR_SET(obj->message->http.info.request.method, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
                zval_ptr_dtor(&cpy);
        }
 }
@@ -580,7 +584,7 @@ static void php_http_message_object_prophandler_get_request_url(php_http_message
 }
 static void php_http_message_object_prophandler_set_request_url(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
        if (PHP_HTTP_MESSAGE_TYPE(REQUEST, obj->message)) {
-               STR_SET(obj->message->http.info.request.url, php_http_url_from_zval(value, ~0 TSRMLS_CC));
+               PTR_SET(obj->message->http.info.request.url, php_http_url_from_zval(value, ~0 TSRMLS_CC));
        }
 }
 static void php_http_message_object_prophandler_get_response_status(php_http_message_object_t *obj, zval *return_value TSRMLS_DC) {
@@ -593,7 +597,7 @@ static void php_http_message_object_prophandler_get_response_status(php_http_mes
 static void php_http_message_object_prophandler_set_response_status(php_http_message_object_t *obj, zval *value TSRMLS_DC) {
        if (PHP_HTTP_MESSAGE_TYPE(RESPONSE, obj->message)) {
                zval *cpy = php_http_ztyp(IS_STRING, value);
-               STR_SET(obj->message->http.info.response.status, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
+               PTR_SET(obj->message->http.info.response.status, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
                zval_ptr_dtor(&cpy);
        }
 }
@@ -608,7 +612,7 @@ static void php_http_message_object_prophandler_set_response_code(php_http_messa
        if (PHP_HTTP_MESSAGE_TYPE(RESPONSE, obj->message)) {
                zval *cpy = php_http_ztyp(IS_LONG, value);
                obj->message->http.info.response.code = Z_LVAL_P(cpy);
-               STR_SET(obj->message->http.info.response.status, estrdup(php_http_env_get_response_status_for_code(obj->message->http.info.response.code)));
+               PTR_SET(obj->message->http.info.response.status, estrdup(php_http_env_get_response_status_for_code(obj->message->http.info.response.code)));
                zval_ptr_dtor(&cpy);
        }
 }
@@ -749,7 +753,7 @@ void php_http_message_object_prepend(zval *this_ptr, zval *prepend, zend_bool to
        }
 }
 
-STATUS php_http_message_object_set_body(php_http_message_object_t *msg_obj, zval *zbody TSRMLS_DC)
+ZEND_RESULT_CODE php_http_message_object_set_body(php_http_message_object_t *msg_obj, zval *zbody TSRMLS_DC)
 {
        zval *tmp = NULL;
        php_stream *s;
@@ -815,7 +819,7 @@ STATUS php_http_message_object_set_body(php_http_message_object_t *msg_obj, zval
        return SUCCESS;
 }
 
-STATUS php_http_message_object_init_body_object(php_http_message_object_t *obj)
+ZEND_RESULT_CODE php_http_message_object_init_body_object(php_http_message_object_t *obj)
 {
        TSRMLS_FETCH_FROM_CTX(obj->message->ts);
 
@@ -1161,17 +1165,19 @@ static PHP_METHOD(HttpMessage, getHeader)
                        if (!header_ce) {
                                RETURN_ZVAL(header, 1, 1);
                        } else if (instanceof_function(header_ce, php_http_header_class_entry TSRMLS_CC)) {
+                               php_http_object_method_t cb;
                                zval *header_name, **argv[2];
 
                                MAKE_STD_ZVAL(header_name);
                                ZVAL_STRINGL(header_name, header_str, header_len, 1);
-                               Z_ADDREF_P(header);
 
                                argv[0] = &header_name;
                                argv[1] = &header;
 
                                object_init_ex(return_value, header_ce);
-                               php_http_method_call(return_value, ZEND_STRL("__construct"), 2, argv, NULL TSRMLS_CC);
+                               php_http_object_method_init(&cb, return_value, ZEND_STRL("__construct") TSRMLS_CC);
+                               php_http_object_method_call(&cb, return_value, NULL, 2, argv TSRMLS_CC);
+                               php_http_object_method_dtor(&cb);
 
                                zval_ptr_dtor(&header_name);
                                zval_ptr_dtor(&header);
@@ -1338,11 +1344,11 @@ static PHP_METHOD(HttpMessage, getInfo)
                switch (obj->message->type) {
                        case PHP_HTTP_REQUEST:
                                Z_STRLEN_P(return_value) = spprintf(&Z_STRVAL_P(return_value), 0, PHP_HTTP_INFO_REQUEST_FMT_ARGS(&obj->message->http, tmp, ""));
-                               STR_FREE(tmp);
+                               PTR_FREE(tmp);
                                break;
                        case PHP_HTTP_RESPONSE:
                                Z_STRLEN_P(return_value) = spprintf(&Z_STRVAL_P(return_value), 0, PHP_HTTP_INFO_RESPONSE_FMT_ARGS(&obj->message->http, tmp, ""));
-                               STR_FREE(tmp);
+                               PTR_FREE(tmp);
                                break;
                        default:
                                RETURN_NULL();
@@ -1462,7 +1468,7 @@ static PHP_METHOD(HttpMessage, setResponseCode)
        }
 
        obj->message->http.info.response.code = code;
-       STR_SET(obj->message->http.info.response.status, estrdup(php_http_env_get_response_status_for_code(code)));
+       PTR_SET(obj->message->http.info.response.status, estrdup(php_http_env_get_response_status_for_code(code)));
 
        RETVAL_ZVAL(getThis(), 1, 0);
 }
@@ -1507,7 +1513,7 @@ static PHP_METHOD(HttpMessage, setResponseStatus)
                php_http_throw(bad_method_call, "http\\Message is not of type response", NULL);
        }
 
-       STR_SET(obj->message->http.info.response.status, estrndup(status, status_len));
+       PTR_SET(obj->message->http.info.response.status, estrndup(status, status_len));
        RETVAL_ZVAL(getThis(), 1, 0);
 }
 
@@ -1558,7 +1564,7 @@ static PHP_METHOD(HttpMessage, setRequestMethod)
                return;
        }
 
-       STR_SET(obj->message->http.info.request.method, estrndup(method, method_len));
+       PTR_SET(obj->message->http.info.request.method, estrndup(method, method_len));
        RETVAL_ZVAL(getThis(), 1, 0);
 }
 
@@ -1617,7 +1623,7 @@ static PHP_METHOD(HttpMessage, setRequestUrl)
                php_http_url_free(&url);
                php_http_throw(invalid_arg, "Cannot set http\\Message's request url to an empty string", NULL);
        } else {
-               STR_SET(obj->message->http.info.request.url, url);
+               PTR_SET(obj->message->http.info.request.url, url);
        }
 
        RETVAL_ZVAL(getThis(), 1, 0);
@@ -1671,6 +1677,16 @@ static PHP_METHOD(HttpMessage, toString)
        RETURN_EMPTY_STRING();
 }
 
+#ifdef ZTS
+static size_t write_to_stream(void *s, const char *str, size_t len)
+{
+       TSRMLS_FETCH();
+       return php_stream_write(s, str, len);
+}
+#else
+#      define write_to_stream (php_http_pass_callback_t)_php_stream_write
+#endif
+
 ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_toStream, 0, 0, 1)
        ZEND_ARG_INFO(0, stream)
 ZEND_END_ARG_INFO();
@@ -1685,7 +1701,7 @@ static PHP_METHOD(HttpMessage, toStream)
                PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
 
                php_stream_from_zval(s, &zstream);
-               php_http_message_to_callback(obj->message, (php_http_pass_callback_t) _php_stream_write, s);
+               php_http_message_to_callback(obj->message, write_to_stream, s);
        }
 }
 
@@ -1854,7 +1870,7 @@ static PHP_METHOD(HttpMessage, splitMultipartBody)
 
        php_http_expect(msg = php_http_message_body_split(obj->message->body, boundary), bad_message, return);
 
-       STR_FREE(boundary);
+       PTR_FREE(boundary);
 
        RETURN_OBJVAL(php_http_message_object_new_ex(php_http_message_class_entry, msg, NULL TSRMLS_CC), 0);
 }