- separated http_check_method() from http_check_allowed_methods()
authorMichael Wallner <mike@php.net>
Wed, 27 Apr 2005 13:37:05 +0000 (13:37 +0000)
committerMichael Wallner <mike@php.net>
Wed, 27 Apr 2005 13:37:05 +0000 (13:37 +0000)
- message parser now recognizes nested messages if there's a content length header or chunked transfer encoding
- added (still crashing) HttpMessage::getMessage()
- some other fixes & adjustments

12 files changed:
http.c
http_api.c
http_cache_api.c
http_functions.c
http_message_api.c
http_message_object.c
http_methods.c
http_send_api.c
php_http_api.h
php_http_message_api.h
php_http_message_object.h
php_http_std_defs.h

diff --git a/http.c b/http.c
index 6a28a5e4fd89690e9befe4c17bdb1f3cfc211378..f5740452c8102e0a2dd27551faed475310152028 100644 (file)
--- a/http.c
+++ b/http.c
@@ -179,7 +179,7 @@ static inline void _http_globals_dtor(TSRMLS_D)
                efree(HTTP_G(ctype));
                HTTP_G(ctype) = NULL;
        }
                efree(HTTP_G(ctype));
                HTTP_G(ctype) = NULL;
        }
-       
+
 #ifdef HTTP_HAVE_CURL
 #      if LIBCURL_VERSION_NUM < 0x070c00
        memset(&HTTP_G(curlerr), 0, sizeof(HTTP_G(curlerr)));
 #ifdef HTTP_HAVE_CURL
 #      if LIBCURL_VERSION_NUM < 0x070c00
        memset(&HTTP_G(curlerr), 0, sizeof(HTTP_G(curlerr)));
@@ -193,21 +193,13 @@ static inline void _http_globals_dtor(TSRMLS_D)
 #define http_check_allowed_methods(m, l) _http_check_allowed_methods((m), (l) TSRMLS_CC)
 static inline void _http_check_allowed_methods(char *methods, int length TSRMLS_DC)
 {
 #define http_check_allowed_methods(m, l) _http_check_allowed_methods((m), (l) TSRMLS_CC)
 static inline void _http_check_allowed_methods(char *methods, int length TSRMLS_DC)
 {
-       char *found, *header;
-
-       if (!length || !SG(request_info).request_method) {
-               return;
+       if (length && SG(request_info).request_method) {
+               if (SUCCESS != http_check_method(SG(request_info).request_method, methods)) {
+                       char *header = emalloc(length + sizeof("Allow: "));
+                       sprintf(header, "Allow: %s", methods);
+                       http_exit(405, header);
+               }
        }
        }
-
-       if (    (found = strstr(methods, SG(request_info).request_method)) &&
-                       (found == SG(request_info).request_method || !isalpha(found[-1])) &&
-                       (!isalpha(found[strlen(SG(request_info).request_method) + 1]))) {
-               return;
-       }
-
-       header = emalloc(length + sizeof("Allow: "));
-       sprintf(header, "Allow: %s", methods);
-       http_exit(405, header);
 }
 /* }}} */
 
 }
 /* }}} */
 
index 5a0dd3728a8a4f655bbb609d89b0aca73b071935..e76846c43dac7f40c7b35a0c88c40137e4fcdc0c 100644 (file)
@@ -101,6 +101,20 @@ STATUS _http_exit_ex(int status, char *header, zend_bool free_header TSRMLS_DC)
 }
 /* }}} */
 
 }
 /* }}} */
 
+/* {{{ STATUS http_check_method(char *) */
+STATUS _http_check_method_ex(const char *method, const char *methods)
+{
+       const char *found;
+
+       if (    (found = strstr(methods, method)) &&
+                       (found == method || !isalpha(found[-1])) &&
+                       (!isalpha(found[strlen(method) + 1]))) {
+               return SUCCESS;
+       }
+       return FAILURE;
+}
+/* }}} */
+
 /* {{{ zval *http_get_server_var_ex(char *, size_t) */
 PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_size, zend_bool check TSRMLS_DC)
 {
 /* {{{ zval *http_get_server_var_ex(char *, size_t) */
 PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_size, zend_bool check TSRMLS_DC)
 {
@@ -117,8 +131,8 @@ PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_size, zen
 /* }}} */
 
 
 /* }}} */
 
 
-/* {{{ STATUS http_chunked_decode(char *, size_t, char **, size_t *) */
-PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len,
+/* {{{ char *http_chunked_decode(char *, size_t, char **, size_t *) */
+PHP_HTTP_API char *_http_chunked_decode(const char *encoded, size_t encoded_len,
        char **decoded, size_t *decoded_len TSRMLS_DC)
 {
        const char *e_ptr;
        char **decoded, size_t *decoded_len TSRMLS_DC)
 {
        const char *e_ptr;
@@ -139,7 +153,7 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len
                        if (i == 9) {
                                http_error_ex(E_WARNING, HTTP_E_PARSE, "Chunk size is too long: 0x%s...", hex_len);
                                efree(*decoded);
                        if (i == 9) {
                                http_error_ex(E_WARNING, HTTP_E_PARSE, "Chunk size is too long: 0x%s...", hex_len);
                                efree(*decoded);
-                               return FAILURE;
+                               return NULL;
                        }
                        hex_len[i++] = *e_ptr++;
                }
                        }
                        hex_len[i++] = *e_ptr++;
                }
@@ -151,9 +165,11 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len
 
                /* new line */
                if (strncmp(e_ptr, HTTP_CRLF, 2)) {
 
                /* new line */
                if (strncmp(e_ptr, HTTP_CRLF, 2)) {
-                       http_error_ex(E_WARNING, HTTP_E_PARSE, "Invalid character (expected 0x0D 0x0A; got: %x %x)", *e_ptr, *(e_ptr + 1));
+                       http_error_ex(E_WARNING, HTTP_E_PARSE, 
+                               "Invalid character (expected 0x0D 0x0A; got: 0x%x(%c) 0x%x(%c))", 
+                               *e_ptr, *e_ptr, *(e_ptr + 1), *(e_ptr + 1));
                        efree(*decoded);
                        efree(*decoded);
-                       return FAILURE;
+                       return NULL;
                }
 
                /* hex to long */
                }
 
                /* hex to long */
@@ -163,7 +179,7 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len
                        if (error == hex_len) {
                                http_error_ex(E_WARNING, HTTP_E_PARSE, "Invalid chunk size string: '%s'", hex_len);
                                efree(*decoded);
                        if (error == hex_len) {
                                http_error_ex(E_WARNING, HTTP_E_PARSE, "Invalid chunk size string: '%s'", hex_len);
                                efree(*decoded);
-                               return FAILURE;
+                               return NULL;
                        }
                }
 
                        }
                }
 
@@ -173,7 +189,7 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len
                *decoded_len += chunk_len;
        }
 
                *decoded_len += chunk_len;
        }
 
-       return SUCCESS;
+       return e_ptr;
 }
 /* }}} */
 
 }
 /* }}} */
 
index 8d2b47f5e23cd29e9bfc76efaad131a2f56ccc45..c75b6dcf5078e7b0d36ecdeb91f542e75fc8af40 100644 (file)
@@ -207,7 +207,7 @@ PHP_HTTP_API STATUS _http_cache_etag(const char *etag, size_t etag_len,
                if (!http_match_etag("HTTP_IF_NONE_MATCH", etag)) {
                        return SUCCESS;
                }
                if (!http_match_etag("HTTP_IF_NONE_MATCH", etag)) {
                        return SUCCESS;
                }
-               return http_cache_exit_ex(etag, 1, 0);
+               return http_cache_exit_ex((char *)etag, 1, 0);
        }
 
        /* if no etag is given and we didn't already start ob_etaghandler -- start it */
        }
 
        /* if no etag is given and we didn't already start ob_etaghandler -- start it */
index ffc84c3687ab283cbe827620f4ea9261bf1e0a63..5854e30b86d1c0d4d824def146f716a4290e7762 100644 (file)
@@ -327,7 +327,7 @@ PHP_FUNCTION(http_match_etag)
 
 /* {{{ proto bool http_cache_last_modified([int timestamp_or_expires]])
  *
 
 /* {{{ proto bool http_cache_last_modified([int timestamp_or_expires]])
  *
- * If timestamp_or_exires is greater than 0, it is handled as timestamp
+ * If timestamp_or_expires is greater than 0, it is handled as timestamp
  * and will be sent as date of last modification.  If it is 0 or omitted,
  * the current time will be sent as Last-Modified date.  If it's negative,
  * it is handled as expiration time in seconds, which means that if the
  * and will be sent as date of last modification.  If it is 0 or omitted,
  * the current time will be sent as Last-Modified date.  If it's negative,
  * it is handled as expiration time in seconds, which means that if the
@@ -491,7 +491,6 @@ PHP_FUNCTION(http_send_data)
        }
 
        convert_to_string_ex(&zdata);
        }
 
        convert_to_string_ex(&zdata);
-       http_send_header("Accept-Ranges: bytes");
        RETURN_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)));
 }
 /* }}} */
        RETURN_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)));
 }
 /* }}} */
@@ -513,7 +512,6 @@ PHP_FUNCTION(http_send_file)
                RETURN_FALSE;
        }
 
                RETURN_FALSE;
        }
 
-       http_send_header("Accept-Ranges: bytes");
        RETURN_SUCCESS(http_send_file(file));
 }
 /* }}} */
        RETURN_SUCCESS(http_send_file(file));
 }
 /* }}} */
@@ -533,7 +531,6 @@ PHP_FUNCTION(http_send_stream)
        }
 
        php_stream_from_zval(file, &zstream);
        }
 
        php_stream_from_zval(file, &zstream);
-       http_send_header("Accept-Ranges: bytes");
        RETURN_SUCCESS(http_send_stream(file));
 }
 /* }}} */
        RETURN_SUCCESS(http_send_stream(file));
 }
 /* }}} */
index 04564afc7ee39c2b21856ff2e79e1cc8bfaef0a8..76e1d22dbe6a3ba17e3d4ab2467ba9b9eb51f247 100644 (file)
 #include "php_http.h"
 #include "php_http_std_defs.h"
 #include "php_http_message_api.h"
 #include "php_http.h"
 #include "php_http_std_defs.h"
 #include "php_http_message_api.h"
+#include "php_http_api.h"
 #include "php_http_headers_api.h"
 
 #include "phpstr/phpstr.h"
 
 #include "php_http_headers_api.h"
 
 #include "phpstr/phpstr.h"
 
+#define http_message_parse_nested(msg, begin, length) _http_message_parse_nested((msg), (begin), (length) TSRMLS_CC)
+static inline http_message *_http_message_parse_nested(http_message *msg, const char *begin, size_t length TSRMLS_DC)
+{
+       http_message *new;
+
+       while (isspace(*begin)) {
+               ++begin;
+               if (!length--) {
+                       return NULL;
+               }
+       }
+
+       if (new = http_message_parse(begin, length)) {
+               new->nested = msg;
+               return new;
+       }
+       return NULL;
+}
+
 PHP_HTTP_API http_message *_http_message_init_ex(http_message *message, http_message_type type)
 {
        if (!message) {
 PHP_HTTP_API http_message *_http_message_init_ex(http_message *message, http_message_type type)
 {
        if (!message) {
@@ -41,7 +61,7 @@ PHP_HTTP_API http_message *_http_message_init_ex(http_message *message, http_mes
        return message;
 }
 
        return message;
 }
 
-PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, char *message, size_t message_length, zend_bool dup TSRMLS_DC)
+PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char *message, size_t message_length TSRMLS_DC)
 {
        char *body = NULL;
        size_t header_length = 0;
 {
        char *body = NULL;
        size_t header_length = 0;
@@ -56,8 +76,6 @@ PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, char *messa
        }
 
        msg = http_message_init(msg);
        }
 
        msg = http_message_init(msg);
-       msg->len = message_length;
-       msg->raw = dup ? estrndup(message, message_length) : message;
 
        if (body = strstr(message, HTTP_CRLF HTTP_CRLF)) {
                body += lenof(HTTP_CRLF HTTP_CRLF);
 
        if (body = strstr(message, HTTP_CRLF HTTP_CRLF)) {
                body += lenof(HTTP_CRLF HTTP_CRLF);
@@ -66,7 +84,7 @@ PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, char *messa
                header_length = message_length;
        }
 
                header_length = message_length;
        }
 
-       if (SUCCESS != http_parse_headers_cb(message, header_length, &msg->hdrs, 1, http_message_parse_headers_callback, (void **) &msg)) {
+       if (SUCCESS != http_parse_headers_cb((char *)message, header_length, &msg->hdrs, 1, http_message_parse_headers_callback, (void **) &msg)) {
                if (free_msg) {
                        http_message_free(msg);
                }
                if (free_msg) {
                        http_message_free(msg);
                }
@@ -74,7 +92,32 @@ PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, char *messa
        }
 
        if (body) {
        }
 
        if (body) {
-               phpstr_from_string_ex(PHPSTR(msg), body, message_length - header_length);
+               zval **c;
+               http_message *nested;
+
+               if (SUCCESS == zend_hash_find(&msg->hdrs, "Content-Length", sizeof("Content-Length"), (void **) &c)) {
+                       long len = atol(Z_STRVAL_PP(c));
+                       phpstr_from_string_ex(PHPSTR(msg), body, len);
+                       if (nested = http_message_parse_nested(msg, body + len,  message + message_length - body - len)) {
+                               return nested;
+                       }
+               } else if (
+                               SUCCESS == zend_hash_find(&msg->hdrs, "Transfer-Encoding", sizeof("Transfer-Encoding"), (void **) &c) &&
+                               !strcasecmp("chunked", Z_STRVAL_PP(c))) {
+
+                       char *decoded, *end;
+                       size_t decoded_len;
+
+                       if (end = http_chunked_decode(body, message_length - header_length, &decoded, &decoded_len)) { 
+                               phpstr_from_string_ex(PHPSTR(msg), decoded, decoded_len);
+                               efree(decoded);
+                               if (nested = http_message_parse_nested(msg, end, message + message_length - end)) {
+                                       return nested;
+                               }
+                       }
+               } else {
+                       phpstr_from_string_ex(PHPSTR(msg), body, message_length - header_length);
+               }
        }
 
        return msg;
        }
 
        return msg;
@@ -119,49 +162,52 @@ PHP_HTTP_API void _http_message_tostring(http_message *msg, char **string, size_
        ulong idx;
        zval **header;
 
        ulong idx;
        zval **header;
 
-       phpstr_init_ex(&str, msg->len, 1);
-       /* set sane alloc size */
-       str.size = 4096;
-
-       switch (msg->type)
-       {
-               case HTTP_MSG_REQUEST:
-                       phpstr_appendf(&str, "%s %s HTTP/%1.1f" HTTP_CRLF,
-                               msg->info.request.method,
-                               msg->info.request.URI,
-                               msg->info.request.http_version);
-               break;
-
-               case HTTP_MSG_RESPONSE:
-                       phpstr_appendf(&str, "HTTP/%1.1f %d" HTTP_CRLF,
-                               msg->info.response.http_version,
-                               msg->info.response.code);
-               break;
-       }
+       phpstr_init_ex(&str, 4096, 0);
 
 
-       FOREACH_HASH_KEYVAL(&msg->hdrs, key, idx, header) {
-               if (key) {
-                       zval **single_header;
-
-                       switch (Z_TYPE_PP(header))
-                       {
-                               case IS_STRING:
-                                       phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key, Z_STRVAL_PP(header));
-                               break;
-
-                               case IS_ARRAY:
-                                       FOREACH_VAL(*header, single_header) {
-                                               phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key, Z_STRVAL_PP(single_header));
-                                       }
-                               break;
-                       }
+       do {
+
+               switch (msg->type)
+               {
+                       case HTTP_MSG_REQUEST:
+                               phpstr_appendf(&str, "%s %s HTTP/%1.1f" HTTP_CRLF,
+                                       msg->info.request.method,
+                                       msg->info.request.URI,
+                                       msg->info.request.http_version);
+                       break;
 
 
-                       key = NULL;
+                       case HTTP_MSG_RESPONSE:
+                               phpstr_appendf(&str, "HTTP/%1.1f %d" HTTP_CRLF,
+                                       msg->info.response.http_version,
+                                       msg->info.response.code);
+                       break;
                }
                }
-       }
 
 
-       phpstr_appends(&str, HTTP_CRLF);
-       phpstr_append(&str, PHPSTR_VAL(msg), PHPSTR_LEN(msg));
+               FOREACH_HASH_KEYVAL(&msg->hdrs, key, idx, header) {
+                       if (key) {
+                               zval **single_header;
+
+                               switch (Z_TYPE_PP(header))
+                               {
+                                       case IS_STRING:
+                                               phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key, Z_STRVAL_PP(header));
+                                       break;
+
+                                       case IS_ARRAY:
+                                               FOREACH_VAL(*header, single_header) {
+                                                       phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key, Z_STRVAL_PP(single_header));
+                                               }
+                                       break;
+                               }
+
+                               key = NULL;
+                       }
+               }
+
+               phpstr_appends(&str, HTTP_CRLF);
+               phpstr_append(&str, PHPSTR_VAL(msg), PHPSTR_LEN(msg));
+               phpstr_appends(&str, HTTP_CRLF);
+
+       } while (msg = msg->nested);
 
        data = phpstr_data(&str, string, length);
        if (!string) {
 
        data = phpstr_data(&str, string, length);
        if (!string) {
@@ -176,10 +222,6 @@ PHP_HTTP_API void _http_message_dtor(http_message *message)
        if (message) {
                zend_hash_destroy(&message->hdrs);
                phpstr_dtor(PHPSTR(message));
        if (message) {
                zend_hash_destroy(&message->hdrs);
                phpstr_dtor(PHPSTR(message));
-               if (message->raw) {
-                       efree(message->raw);
-                       message->raw = NULL;
-               }
                if (message->type == HTTP_MSG_REQUEST) {
                        if (message->info.request.method) {
                                efree(message->info.request.method);
                if (message->type == HTTP_MSG_REQUEST) {
                        if (message->info.request.method) {
                                efree(message->info.request.method);
@@ -198,6 +240,7 @@ PHP_HTTP_API void _http_message_free(http_message *message)
        if (message) {
                if (message->nested) {
                        http_message_free(message->nested);
        if (message) {
                if (message->nested) {
                        http_message_free(message->nested);
+                       message->nested = NULL;
                }
                http_message_dtor(message);
                efree(message);
                }
                http_message_dtor(message);
                efree(message);
index fee935ededa29330dc0378e8f6b5112c3d97d52a..ffb319809ba6a1752b54b385d82a390e06be709b 100644 (file)
@@ -55,6 +55,7 @@ zend_function_entry http_message_object_fe[] = {
        PHP_ME(HttpMessage, setRequestUri, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(HttpMessage, getHttpVersion, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(HttpMessage, setHttpVersion, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(HttpMessage, setRequestUri, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(HttpMessage, getHttpVersion, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(HttpMessage, setHttpVersion, NULL, ZEND_ACC_PUBLIC)
+       PHP_ME(HttpMessage, getNestedMessage, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(HttpMessage, toString, NULL, ZEND_ACC_PUBLIC)
 
        ZEND_MALIAS(HttpMessage, __toString, toString, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(HttpMessage, toString, NULL, ZEND_ACC_PUBLIC)
 
        ZEND_MALIAS(HttpMessage, __toString, toString, NULL, ZEND_ACC_PUBLIC)
@@ -106,7 +107,6 @@ static inline void _http_message_object_declare_default_properties(TSRMLS_D)
 
        DCL_PROP(PROTECTED, long, type, HTTP_MSG_NONE);
 
 
        DCL_PROP(PROTECTED, long, type, HTTP_MSG_NONE);
 
-       DCL_PROP(PROTECTED, string, raw, "");
        DCL_PROP(PROTECTED, string, body, "");
 
        DCL_PROP(PROTECTED, string, requestMethod, "");
        DCL_PROP(PROTECTED, string, body, "");
 
        DCL_PROP(PROTECTED, string, requestMethod, "");
@@ -144,7 +144,7 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type
                return EG(uninitialized_zval_ptr);
        }
 
                return EG(uninitialized_zval_ptr);
        }
 
-    zval_dtor(return_value);
+    zval_ptr_dtor(&return_value);
 
 #if 0
        fprintf(stderr, "Reading property: %s(%d==%d) (%lu)\n", Z_STRVAL_P(member), Z_STRLEN_P(member), strlen(Z_STRVAL_P(member)),
 
 #if 0
        fprintf(stderr, "Reading property: %s(%d==%d) (%lu)\n", Z_STRVAL_P(member), Z_STRLEN_P(member), strlen(Z_STRVAL_P(member)),
@@ -175,18 +175,6 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type
                        }
                break;
 
                        }
                break;
 
-               case HTTP_MSG_PROPHASH_RAW:
-                       if (msg->raw) {
-                               if (msg->len) {
-                                       RETVAL_STRINGL(msg->raw, msg->len, 1);
-                               } else {
-                                       RETVAL_STRINGL("", 0, 1);
-                               }
-                       } else {
-                               RETVAL_NULL();
-                       }
-               break;
-
                case HTTP_MSG_PROPHASH_BODY:
                        phpstr_fix(PHPSTR(msg));
                        RETVAL_PHPSTR(PHPSTR(msg), 0, 1);
                case HTTP_MSG_PROPHASH_BODY:
                        phpstr_fix(PHPSTR(msg));
                        RETVAL_PHPSTR(PHPSTR(msg), 0, 1);
@@ -198,7 +186,12 @@ static zval *_http_message_object_read_prop(zval *object, zval *member, int type
                break;
 
                case HTTP_MSG_PROPHASH_NESTED_MESSAGE:
                break;
 
                case HTTP_MSG_PROPHASH_NESTED_MESSAGE:
-                       RETVAL_NULL();
+                       if (msg->nested) {
+                               Z_TYPE_P(return_value) = IS_OBJECT;
+                               return_value->value.obj = http_message_object_from_msg(msg->nested);
+                       } else {
+                               RETVAL_NULL();
+                       }
                break;
 
                case HTTP_MSG_PROPHASH_REQUEST_METHOD:
                break;
 
                case HTTP_MSG_PROPHASH_REQUEST_METHOD:
@@ -282,11 +275,6 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va
                        }
                break;
 
                        }
                break;
 
-               case HTTP_MSG_PROPHASH_RAW:
-                       http_message_dtor(msg);
-                       http_message_parse_ex(msg, Z_STRVAL_P(value), Z_STRLEN_P(value), 1);
-               break;
-
                case HTTP_MSG_PROPHASH_BODY:
                        phpstr_dtor(PHPSTR(msg));
                        phpstr_from_string_ex(PHPSTR(msg), Z_STRVAL_P(value), Z_STRLEN_P(value));
                case HTTP_MSG_PROPHASH_BODY:
                        phpstr_dtor(PHPSTR(msg));
                        phpstr_from_string_ex(PHPSTR(msg), Z_STRVAL_P(value), Z_STRLEN_P(value));
@@ -357,7 +345,6 @@ static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC)
        zend_hash_clean(OBJ_PROP(obj));
 
        ASSOC_PROP(obj, long, "type", msg->type);
        zend_hash_clean(OBJ_PROP(obj));
 
        ASSOC_PROP(obj, long, "type", msg->type);
-       ASSOC_STRINGL(obj, "raw", msg->raw, msg->len)
        ASSOC_STRINGL(obj, "body", PHPSTR_VAL(msg), PHPSTR_LEN(msg));
 
        MAKE_STD_ZVAL(headers);
        ASSOC_STRINGL(obj, "body", PHPSTR_VAL(msg), PHPSTR_LEN(msg));
 
        MAKE_STD_ZVAL(headers);
index 49c57a4f6f438f275ad668f3afbf3956a22e9f31..dfbc712dd80d17e9a95c7618e3f7ce1d04b88ee4 100644 (file)
@@ -875,7 +875,7 @@ PHP_METHOD(HttpMessage, setHttpVersion)
        zval *zv, *version;
        getObject(http_message_object, obj);
 
        zval *zv, *version;
        getObject(http_message_object, obj);
 
-       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zv)) {
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &zv)) {
                return;
        }
 
                return;
        }
 
@@ -890,6 +890,29 @@ PHP_METHOD(HttpMessage, setHttpVersion)
 }
 /* }}} */
 
 }
 /* }}} */
 
+/* {{{ proto HttpMessage HttpMessage::getNestedMessage()
+ *
+ * Get nested HTTP Message.
+ */
+PHP_METHOD(HttpMessage, getNestedMessage)
+{
+       zval *nested;
+       getObject(http_message_object, obj);
+       
+       NO_ARGS;
+       
+       nested = GET_PROP(obj, nestedMessage);
+       if (Z_TYPE_P(nested) == IS_OBJECT) {
+               Z_TYPE_P(return_value) = IS_OBJECT;
+               return_value->is_ref = 1;
+               return_value->value.obj = nested->value.obj;
+               zval_add_ref(&return_value);
+       } else {
+               RETVAL_NULL();
+       }
+}
+/* }}} */
+
 /* {{{ proto string HttpMessage::toString()
  *
  * Get the string representation of the Message.
 /* {{{ proto string HttpMessage::toString()
  *
  * Get the string representation of the Message.
index 0fa18daa01c546c12b34c120c5b318eda0e1586a..41ba3058e556d1089853ecf3e2d670ce10696531 100644 (file)
@@ -330,6 +330,9 @@ PHP_HTTP_API STATUS _http_send(const void *data_ptr, size_t data_size, http_send
                HTTP_G(etag_started) = 0;
        }
 
                HTTP_G(etag_started) = 0;
        }
 
+       /* enable partial dl and resume */
+       http_send_header("Accept-Ranges: bytes");
+
        zend_hash_init(&ranges, 0, NULL, ZVAL_PTR_DTOR, 0);
        range_status = http_get_request_ranges(&ranges, data_size);
 
        zend_hash_init(&ranges, 0, NULL, ZVAL_PTR_DTOR, 0);
        range_status = http_get_request_ranges(&ranges, data_size);
 
@@ -362,14 +365,14 @@ PHP_HTTP_API STATUS _http_send(const void *data_ptr, size_t data_size, http_send
                        return FAILURE;
                }
                if (http_match_etag("HTTP_IF_NONE_MATCH", etag)) {
                        return FAILURE;
                }
                if (http_match_etag("HTTP_IF_NONE_MATCH", etag)) {
-                       return http_cache_exit(etag, 1, 1);
+                       return http_cache_exit_ex(etag, 1, 1);
                }
                efree(etag);
        }
 
        /* send 304 Not Modified if last modified matches */
        if (http_match_last_modified("HTTP_IF_MODIFIED_SINCE", HTTP_G(lmod))) {
                }
                efree(etag);
        }
 
        /* send 304 Not Modified if last modified matches */
        if (http_match_last_modified("HTTP_IF_MODIFIED_SINCE", HTTP_G(lmod))) {
-               return http_cache_exit(http_date(HTTP_G(lmod)), 0, 1);
+               return http_cache_exit_ex(http_date(HTTP_G(lmod)), 0, 1);
        }
 
        /* send full entity */
        }
 
        /* send full entity */
index 3e596bac321a687632c3c584b924f0de82324ab2..27e0babf629f2a03fc24b216b3304504d58b0637 100644 (file)
@@ -31,6 +31,10 @@ extern void _http_error_ex(long type, long code, const char *format, ...);
 #define http_exit_ex(s, h, f) _http_exit_ex((s), (h), (f) TSRMLS_CC)
 extern STATUS _http_exit_ex(int status, char *header, zend_bool free_header TSRMLS_DC);
 
 #define http_exit_ex(s, h, f) _http_exit_ex((s), (h), (f) TSRMLS_CC)
 extern STATUS _http_exit_ex(int status, char *header, zend_bool free_header TSRMLS_DC);
 
+#define http_check_method(m) http_check_method_ex((m), HTTP_KNOWN_METHODS)
+#define http_check_method_ex(m, a) _http_check_method_ex((m), (a))
+extern STATUS _http_check_method(const char *method, const char *methods);
+
 #define HTTP_GSC(var, name, ret)  HTTP_GSP(var, name, return ret)
 #define HTTP_GSP(var, name, ret) \
                if (!(var = _http_get_server_var_ex(name, strlen(name)+1, 1 TSRMLS_CC))) { \
 #define HTTP_GSC(var, name, ret)  HTTP_GSP(var, name, return ret)
 #define HTTP_GSP(var, name, ret) \
                if (!(var = _http_get_server_var_ex(name, strlen(name)+1, 1 TSRMLS_CC))) { \
@@ -42,7 +46,7 @@ extern STATUS _http_exit_ex(int status, char *header, zend_bool free_header TSRM
 PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_size, zend_bool check TSRMLS_DC);
 
 #define http_chunked_decode(e, el, d, dl) _http_chunked_decode((e), (el), (d), (dl) TSRMLS_CC)
 PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_size, zend_bool check TSRMLS_DC);
 
 #define http_chunked_decode(e, el, d, dl) _http_chunked_decode((e), (el), (d), (dl) TSRMLS_CC)
-PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC);
+PHP_HTTP_API char *_http_chunked_decode(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC);
 
 #define http_split_response(r, h, b) _http_split_response((r), (h), (b) TSRMLS_CC)
 PHP_HTTP_API STATUS _http_split_response(zval *response, zval *headers, zval *body TSRMLS_DC);
 
 #define http_split_response(r, h, b) _http_split_response((r), (h), (b) TSRMLS_CC)
 PHP_HTTP_API STATUS _http_split_response(zval *response, zval *headers, zval *body TSRMLS_DC);
index 78355a63c47f4bea0b7b14c617b68cf56ab9afaf..d60dc9861769dfb2f2d85bf1e4484650cf137c43 100644 (file)
@@ -59,9 +59,6 @@ struct _http_message {
 
        } info;
 
 
        } info;
 
-       size_t          len;
-       char            *raw;
-
        http_message *nested;
 };
 
        http_message *nested;
 };
 
@@ -73,9 +70,9 @@ struct _http_message {
 #define http_message_init_ex(m, t) _http_message_init_ex((m), (t))
 PHP_HTTP_API http_message *_http_message_init_ex(http_message *m, http_message_type t);
 
 #define http_message_init_ex(m, t) _http_message_init_ex((m), (t))
 PHP_HTTP_API http_message *_http_message_init_ex(http_message *m, http_message_type t);
 
-#define http_message_parse(m, l) http_message_parse_ex(NULL, (m), (l), 1)
-#define http_message_parse_ex(h, m, l, d) _http_message_parse_ex((h), (m), (l), (d) TSRMLS_CC)
-PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, char *message, size_t length, zend_bool duplicate TSRMLS_DC);
+#define http_message_parse(m, l) http_message_parse_ex(NULL, (m), (l))
+#define http_message_parse_ex(h, m, l) _http_message_parse_ex((h), (m), (l) TSRMLS_CC)
+PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char *message, size_t length TSRMLS_DC);
 
 #define http_message_parse_headers_callback _http_message_parse_headers_callback
 PHP_HTTP_API void _http_message_parse_headers_callback(void *message, char *http_line, size_t line_length, HashTable **headers TSRMLS_DC);
 
 #define http_message_parse_headers_callback _http_message_parse_headers_callback
 PHP_HTTP_API void _http_message_parse_headers_callback(void *message, char *http_line, size_t line_length, HashTable **headers TSRMLS_DC);
index ba5a073daef5f39f3aa27bf32f9dc54ff2452d78..46a1dd536283f0b7ed6ffb6647af40a4977abc5b 100644 (file)
@@ -67,9 +67,20 @@ PHP_METHOD(HttpMessage, getRequestUri);
 PHP_METHOD(HttpMessage, setRequestUri);
 PHP_METHOD(HttpMessage, getHttpVersion);
 PHP_METHOD(HttpMessage, setHttpVersion);
 PHP_METHOD(HttpMessage, setRequestUri);
 PHP_METHOD(HttpMessage, getHttpVersion);
 PHP_METHOD(HttpMessage, setHttpVersion);
+PHP_METHOD(HttpMessage, getNestedMessage);
 PHP_METHOD(HttpMessage, toString);
 
 PHP_METHOD(HttpMessage, fromString);
 
 #endif
 #endif
 PHP_METHOD(HttpMessage, toString);
 
 PHP_METHOD(HttpMessage, fromString);
 
 #endif
 #endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
index 59edb29935f319185dc336a1c091b1e5fca75eaa..953d4ac22e6db6a7d04ed65eb9bf47176b6d2975 100644 (file)
@@ -64,12 +64,12 @@ typedef int STATUS;
                /* HTTP 1.1 */ \
                "GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, CONNECT, " \
                /* WebDAV - RFC 2518 */ \
                /* HTTP 1.1 */ \
                "GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, CONNECT, " \
                /* WebDAV - RFC 2518 */ \
-               /* "PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, " */ \
+               "PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, " \
                /* WebDAV Versioning - RFC 3253 */ \
                /* WebDAV Versioning - RFC 3253 */ \
-               /* "VERSION-CONTROL, REPORT, CHECKOUT, CHECKIN, UNCHECKOUT, " */ \
-               /* "MKWORKSPACE, UPDATE, LABEL, MERGE, BASELINE-CONTROL, MKACTIVITY, " */ \
+               "VERSION-CONTROL, REPORT, CHECKOUT, CHECKIN, UNCHECKOUT, " \
+               "MKWORKSPACE, UPDATE, LABEL, MERGE, BASELINE-CONTROL, MKACTIVITY, " \
                /* WebDAV Access Control - RFC 3744 */ \
                /* WebDAV Access Control - RFC 3744 */ \
-               /* "ACL, " */ \
+               "ACL, " \
                /* END */
 
 
                /* END */