From: Michael Wallner Date: Mon, 10 Oct 2005 14:29:28 +0000 (+0000) Subject: - move the chunked decoder to the encoding_api X-Git-Tag: RELEASE_0_15_0~15 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=commitdiff_plain;h=f6a58b4f97105ba3c3177116c18672f1b8ba4179;hp=9d4113f62a7a8fe2fe3879b94a3712d11cec8726 - move the chunked decoder to the encoding_api --- diff --git a/config.m4 b/config.m4 index 7412b63..aac5a54 100644 --- a/config.m4 +++ b/config.m4 @@ -34,7 +34,7 @@ dnl ZLIB dnl ---- AC_MSG_CHECKING([for zlib.h]) ZLIB_DIR= - for i int "$PHP_HTTP_ZLIB_COMPRESSION" /user/local /usr /opt; do + for i int "$PHP_HTTP_ZLIB_COMPRESSION" "$PHP_ZLIB_DIR" "$PHP_ZLIB" /user/local /usr /opt; do if test -r "$i/include/zlib.h"; then ZLIB_DIR=$i break; @@ -44,6 +44,7 @@ dnl ---- AC_MSG_RESULT([not found]) AC_MSG_WARNING([zlib support not enabled; zlib.h not found]) else + AC_MSG_RESULT([found in $ZLIB_DIR]) PHP_ADD_INCLUDE($ZLIB_DIR/include) PHP_ADD_LIBRARY_WITH_PATH(libz, $ZLIB_DIR/$PHP_LIBDIR, HTTP_SHARED_LIBADD) AC_DEFINE([HTTP_HAVE_ZLIB], [1], [Have zlib support]) diff --git a/http_api.c b/http_api.c index 9943cd8..39736ef 100644 --- a/http_api.c +++ b/http_api.c @@ -294,71 +294,6 @@ PHP_HTTP_API STATUS _http_get_request_body_ex(char **body, size_t *length, zend_ } /* }}} */ -/* {{{ char *http_chunked_decode(char *, size_t, char **, size_t *) */ -PHP_HTTP_API const char *_http_chunked_decode(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC) -{ - const char *e_ptr; - char *d_ptr; - long rest; - - *decoded_len = 0; - *decoded = ecalloc(1, encoded_len); - d_ptr = *decoded; - e_ptr = encoded; - - while ((rest = encoded + encoded_len - e_ptr) > 0) { - long chunk_len = 0; - int EOL_len = 0, eol_mismatch = 0; - char *n_ptr; - - chunk_len = strtol(e_ptr, &n_ptr, 16); - - /* check if: - * - we could not read in chunk size - * - we got a negative chunk size - * - chunk size is greater then remaining size - * - chunk size is not followed by (CR)LF|NUL - */ - if ( (n_ptr == e_ptr) || (chunk_len < 0) || (chunk_len > rest) || - (*n_ptr && (eol_mismatch = (n_ptr != http_locate_eol(e_ptr, &EOL_len))))) { - /* don't fail on apperently not encoded data */ - if (e_ptr == encoded) { - memcpy(*decoded, encoded, encoded_len); - *decoded_len = encoded_len; - return encoded + encoded_len; - } else { - efree(*decoded); - if (eol_mismatch) { - if (EOL_len == 2) { - http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Invalid character (expected 0x0D 0x0A; got: 0x%X 0x%X)", *n_ptr, *(n_ptr + 1)); - } else { - http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Invalid character (expected 0x0A; got: 0x%X)", *n_ptr); - } - } else { - char *error = estrndup(n_ptr, strcspn(n_ptr, "\r\n ")); - http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Invalid chunk size: '%s' at pos %d", error, n_ptr - encoded); - efree(error); - } - return NULL; - } - } else { - e_ptr = n_ptr; - } - - /* reached the end */ - if (!chunk_len) { - break; - } - - memcpy(d_ptr, e_ptr += EOL_len, chunk_len); - d_ptr += chunk_len; - e_ptr += chunk_len + EOL_len; - *decoded_len += chunk_len; - } - - return e_ptr; -} -/* }}} */ /* {{{ char *http_guess_content_type(char *magic_file, long magic_mode, void *data, size_t size, http_send_mode mode) */ PHP_HTTP_API char *_http_guess_content_type(const char *magicfile, long magicmode, void *data_ptr, size_t data_len, http_send_mode data_mode TSRMLS_DC) diff --git a/http_encoding_api.c b/http_encoding_api.c index 67c27a1..47f01dd 100644 --- a/http_encoding_api.c +++ b/http_encoding_api.c @@ -24,14 +24,80 @@ #include "php_http.h" #include "php_http_api.h" +ZEND_EXTERN_MODULE_GLOBALS(http); + +/* {{{ char *http_encoding_dechunk(char *, size_t, char **, size_t *) */ +PHP_HTTP_API const char *_http_encoding_dechunk(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC) +{ + const char *e_ptr; + char *d_ptr; + long rest; + + *decoded_len = 0; + *decoded = ecalloc(1, encoded_len); + d_ptr = *decoded; + e_ptr = encoded; + + while ((rest = encoded + encoded_len - e_ptr) > 0) { + long chunk_len = 0; + int EOL_len = 0, eol_mismatch = 0; + char *n_ptr; + + chunk_len = strtol(e_ptr, &n_ptr, 16); + + /* check if: + * - we could not read in chunk size + * - we got a negative chunk size + * - chunk size is greater then remaining size + * - chunk size is not followed by (CR)LF|NUL + */ + if ( (n_ptr == e_ptr) || (chunk_len < 0) || (chunk_len > rest) || + (*n_ptr && (eol_mismatch = (n_ptr != http_locate_eol(e_ptr, &EOL_len))))) { + /* don't fail on apperently not encoded data */ + if (e_ptr == encoded) { + memcpy(*decoded, encoded, encoded_len); + *decoded_len = encoded_len; + return encoded + encoded_len; + } else { + efree(*decoded); + if (eol_mismatch) { + if (EOL_len == 2) { + http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Invalid character (expected 0x0D 0x0A; got: 0x%X 0x%X)", *n_ptr, *(n_ptr + 1)); + } else { + http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Invalid character (expected 0x0A; got: 0x%X)", *n_ptr); + } + } else { + char *error = estrndup(n_ptr, strcspn(n_ptr, "\r\n ")); + http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Invalid chunk size: '%s' at pos %d", error, n_ptr - encoded); + efree(error); + } + return NULL; + } + } else { + e_ptr = n_ptr; + } + + /* reached the end */ + if (!chunk_len) { + break; + } + + memcpy(d_ptr, e_ptr += EOL_len, chunk_len); + d_ptr += chunk_len; + e_ptr += chunk_len + EOL_len; + *decoded_len += chunk_len; + } + + return e_ptr; +} +/* }}} */ + #ifdef HTTP_HAVE_ZLIB #include #define HTTP_GZMAXTRY 10 #define HTTP_GZBUFLEN(l) (l + (l / 1000) + 16 + 1) -ZEND_EXTERN_MODULE_GLOBALS(http); - static const char http_gzencode_header[] = { (const char) 0x1f, (const char) 0x8b, @@ -194,9 +260,9 @@ PHP_HTTP_API STATUS _http_encoding_gzdecode(const char *data, size_t data_len, c cmp += (unsigned) (data[data_len-6] << 16); cmp += (unsigned) (data[data_len-5] << 24); len = (unsigned) (data[data_len-4]); - len += (unsigned) (data[data_len-4] << 8); - len += (unsigned) (data[data_len-4] << 16); - len += (unsigned) (data[data_len-4] << 24); + len += (unsigned) (data[data_len-3] << 8); + len += (unsigned) (data[data_len-2] << 16); + len += (unsigned) (data[data_len-1] << 24); if (cmp != crc) { http_error(HE_NOTICE, HTTP_E_ENCODING, "Could not verify data integrity: CRC check failed"); diff --git a/http_functions.c b/http_functions.c index ae08b4f..364e81f 100644 --- a/http_functions.c +++ b/http_functions.c @@ -755,7 +755,7 @@ PHP_FUNCTION(http_chunked_decode) RETURN_FALSE; } - if (NULL != http_chunked_decode(encoded, encoded_len, &decoded, &decoded_len)) { + if (NULL != http_encoding_dechunk(encoded, encoded_len, &decoded, &decoded_len)) { RETURN_STRINGL(decoded, (int) decoded_len, 0); } else { RETURN_FALSE; diff --git a/http_message_api.c b/http_message_api.c index 89f67e0..dd597fc 100644 --- a/http_message_api.c +++ b/http_message_api.c @@ -157,7 +157,7 @@ PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char size_t decoded_len; /* decode and replace Transfer-Encoding with Content-Length header */ - if (continue_at = http_chunked_decode(body, message + message_length - body, &decoded, &decoded_len)) { + if (continue_at = http_encoding_dechunk(body, message + message_length - body, &decoded, &decoded_len)) { zval *len; char *tmp; int tmp_len; diff --git a/php_http_api.h b/php_http_api.h index 4f40fa5..a6f19eb 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -84,9 +84,6 @@ PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_size, zen #define http_get_Request_body_ex(b, l, d) _http_get_request_body_ex((b), (l), (d) TSRMLS_CC) PHP_HTTP_API STATUS _http_get_request_body_ex(char **body, size_t *length, zend_bool dup TSRMLS_DC); -#define http_chunked_decode(e, el, d, dl) _http_chunked_decode((e), (el), (d), (dl) TSRMLS_CC) -PHP_HTTP_API const char *_http_chunked_decode(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC); - #define http_guess_content_type(mf, mm, d, l, m) _http_guess_content_type((mf), (mm), (d), (l), (m) TSRMLS_CC) PHP_HTTP_API char *_http_guess_content_type(const char *magic_file, long magic_mode, void *data_ptr, size_t data_len, http_send_mode mode TSRMLS_DC); diff --git a/php_http_encoding_api.h b/php_http_encoding_api.h index f559ee9..92a2f9a 100644 --- a/php_http_encoding_api.h +++ b/php_http_encoding_api.h @@ -18,10 +18,13 @@ #ifndef PHP_HTTP_ENCODING_API_H #define PHP_HTTP_ENCODING_API_H -#ifdef HTTP_HAVE_ZLIB - #include "php_http_std_defs.h" +#define http_encoding_dechunk(e, el, d, dl) _http_encoding_dechunk((e), (el), (d), (dl) TSRMLS_CC) +PHP_HTTP_API const char *_http_encoding_dechunk(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC); + +#ifdef HTTP_HAVE_ZLIB + #define http_encoding_gzencode(l, d, dl, r, rl) _http_encoding_gzencode((l), (d), (dl), (r), (rl) TSRMLS_CC) PHP_HTTP_API STATUS _http_encoding_gzencode(int level, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC); #define http_encoding_gzdecode(d, dl, r, rl) _http_encoding_gzdecode((d), (dl), (r), (rl) TSRMLS_CC)