X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_api.c;h=9943cd8f49cf55a516ff9bb3f49edd16b017bcef;hp=abc2c9beeb155a925b1b4e8dcf52568bc8ba0d86;hb=39feb7a7e30bb4b393a6f76aa2f35d4e9275523e;hpb=bb1f32fd5d06b9b9ace6517c177b0fe58c9ff57c diff --git a/http_api.c b/http_api.c index abc2c9b..9943cd8 100644 --- a/http_api.c +++ b/http_api.c @@ -22,6 +22,7 @@ #include "SAPI.h" #include "ext/standard/url.h" +#include "ext/standard/head.h" #include "php_http.h" #include "php_http_std_defs.h" @@ -175,6 +176,7 @@ void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...) vspprintf(&message, 0, format, args); zend_throw_exception(http_exception_get_for_code(code), message, code TSRMLS_CC); + efree(message); } else #endif php_verror(NULL, "", type, format, args TSRMLS_CC); @@ -193,7 +195,7 @@ void _http_log_ex(char *file, const char *ident, const char *message TSRMLS_DC) strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", php_localtime_r(&now, &nowtm)); #define HTTP_LOG_WRITE(file, type, msg) \ - if (file && strlen(file)) { \ + if (file && *file) { \ php_stream *log = php_stream_open_wrapper(file, "ab", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL); \ \ if (log) { \ @@ -220,7 +222,7 @@ STATUS _http_exit_ex(int status, char *header, char *body, zend_bool send_header } } - if (body) { + if (php_header(TSRMLS_C) && body) { PHPWRITE(body, strlen(body)); } @@ -228,6 +230,8 @@ STATUS _http_exit_ex(int status, char *header, char *body, zend_bool send_header { case 301: http_log(HTTP_G(log).redirect, "301-REDIRECT", header); break; case 302: http_log(HTTP_G(log).redirect, "302-REDIRECT", header); break; + case 303: http_log(HTTP_G(log).redirect, "303-REDIRECT", header); break; + case 307: http_log(HTTP_G(log).redirect, "307-REDIRECT", header); break; case 304: http_log(HTTP_G(log).cache, "304-CACHE", header); break; case 405: http_log(HTTP_G(log).allowed_methods, "405-ALLOWED", header); break; default: http_log(NULL, header, body); break; @@ -295,24 +299,28 @@ PHP_HTTP_API const char *_http_chunked_decode(const char *encoded, size_t encode { const char *e_ptr; char *d_ptr; + long rest; *decoded_len = 0; *decoded = ecalloc(1, encoded_len); d_ptr = *decoded; e_ptr = encoded; - while (((e_ptr - encoded) - encoded_len) > 0) { - size_t chunk_len = 0, EOL_len = 0; - int eol_mismatch = 0; + 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) || (*n_ptr && (eol_mismatch = n_ptr != http_locate_eol(e_ptr, &EOL_len)))) { + 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); @@ -358,15 +366,19 @@ PHP_HTTP_API char *_http_guess_content_type(const char *magicfile, long magicmod char *ct = NULL; #ifdef HTTP_HAVE_MAGIC - struct magic_set *magic = magic_open(magicmode); + /* magic_load() fails if MAGIC_MIME is set because it + cowardly adds .mime to the file name */ + struct magic_set *magic = magic_open(magicmode &~ MAGIC_MIME); if (!magic) { http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Invalid magic mode: %ld", magicmode); } else if (-1 == magic_load(magic, magicfile)) { - http_error_ex(HE_WARNING, HTTP_E_RUNTIME, "Failed to load magic database '%s'", magicfile); + http_error_ex(HE_WARNING, HTTP_E_RUNTIME, "Failed to load magic database '%s' (%s)", magicfile, magic_error(magic)); } else { const char *ctype = NULL; + magic_setflags(magic, magicmode); + switch (data_mode) { case SEND_RSRC: