X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=http_api.c;h=0b0eea748831e87098ab354dacad0f3a778b57a1;hb=0dbc3c8eb4ec78fd58d6cc1c80e5189f5ae91094;hp=04e012133e8d94ace630d136b7c0e6908c201dcb;hpb=64de794f91af7565602a1183c5ed3fda2de99f35;p=m6w6%2Fext-http diff --git a/http_api.c b/http_api.c index 04e0121..0b0eea7 100644 --- a/http_api.c +++ b/http_api.c @@ -6,22 +6,17 @@ | modification, are permitted provided that the conditions mentioned | | in the accompanying LICENSE file are met. | +--------------------------------------------------------------------+ - | Copyright (c) 2004-2005, Michael Wallner | + | Copyright (c) 2004-2006, Michael Wallner | +--------------------------------------------------------------------+ */ /* $Id$ */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - +#define HTTP_WANT_SAPI #include "php_http.h" -#include "SAPI.h" #include "php_output.h" #include "ext/standard/url.h" -#include "ext/standard/head.h" #include "php_http_api.h" #include "php_http_send_api.h" @@ -30,8 +25,6 @@ # include "php_http_exception_object.h" #endif -ZEND_EXTERN_MODULE_GLOBALS(http); - PHP_MINIT_FUNCTION(http_support) { HTTP_LONG_CONSTANT("HTTP_SUPPORT", HTTP_SUPPORT); @@ -56,7 +49,7 @@ PHP_HTTP_API long _http_support(long feature) #ifdef HTTP_HAVE_MAGIC support |= HTTP_SUPPORT_MAGICMIME; #endif -#if defined(HTTP_HAVE_ZLIB) || defined(HAVE_ZLIB) +#ifdef HTTP_HAVE_ZLIB support |= HTTP_SUPPORT_ENCODINGS; #endif @@ -102,13 +95,14 @@ void _http_key_list_default_decoder(const char *encoded, size_t encoded_len, cha /* {{{ */ STATUS _http_parse_key_list(const char *list, HashTable *items, char separator, http_key_list_decode_t decode, zend_bool first_entry_is_name_value_pair TSRMLS_DC) { - const char *key = list, *val = NULL; + char *str = estrdup(list), *key = str, *val = NULL; int vallen = 0, keylen = 0, done = 0; zval array; INIT_ZARR(array, items); - if (!(val = strchr(list, '='))) { + if (!(val = strchr(str, '='))) { + efree(str); return FAILURE; } @@ -126,16 +120,27 @@ STATUS _http_parse_key_list(const char *list, HashTable *items, char separator, } #define HTTP_KEYLIST_FIXKEY() \ { \ - while (isspace(*key)) ++key; \ - keylen = val - key; \ - while (isspace(key[keylen - 1])) --keylen; \ + while (isspace(*key)) ++key; \ + keylen = val - key; \ + while (isspace(key[keylen - 1])) --keylen; \ } #define HTTP_KEYLIST_FIXVAL() \ { \ + ++val; \ + while (isspace(*val)) ++val; \ + vallen = key - val; \ + while (isspace(val[vallen - 1])) --vallen; \ + if (val[0] == '"' && val[vallen - 1] == '"') { \ + int i; \ ++val; \ - while (isspace(*val)) ++val; \ - vallen = key - val; \ - while (isspace(val[vallen - 1])) --vallen; \ + vallen -= 2; \ + for (i = 0; i < vallen; ++i) { \ + if (val[i] == '\\' && val[i+1] == '"' && (!i || val[i-1] != '\\')) { \ + memmove(&val[i], &val[i+1], vallen - i); \ + --vallen; \ + } \ + } \ + } \ } HTTP_KEYLIST_FIXKEY(); @@ -148,6 +153,7 @@ STATUS _http_parse_key_list(const char *list, HashTable *items, char separator, key = val + strlen(val); HTTP_KEYLIST_FIXVAL(); HTTP_KEYLIST_VAL(&array, "value", val, vallen); + efree(str); return SUCCESS; } /* additional info appended */ @@ -180,6 +186,7 @@ STATUS _http_parse_key_list(const char *list, HashTable *items, char separator, efree(keydup); } while (!done); + efree(str); return SUCCESS; } /* }}} */ @@ -209,9 +216,9 @@ void _http_log_ex(char *file, const char *ident, const char *message TSRMLS_DC) { time_t now; struct tm nowtm; - char datetime[128]; + char datetime[20] = {0}; - time(&now); + now = HTTP_GET_REQUEST_TIME(); strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", php_localtime_r(&now, &nowtm)); #define HTTP_LOG_WRITE(file, type, msg) \ @@ -226,7 +233,7 @@ void _http_log_ex(char *file, const char *ident, const char *message TSRMLS_DC) } HTTP_LOG_WRITE(file, ident, message); - HTTP_LOG_WRITE(HTTP_G(log).composite, ident, message); + HTTP_LOG_WRITE(HTTP_G->log.composite, ident, message); } /* }}} */ @@ -248,25 +255,26 @@ STATUS _http_exit_ex(int status, char *header, char *body, zend_bool send_header } php_end_ob_buffers(0 TSRMLS_CC); - if (php_header(TSRMLS_C) && body) { + if ((SUCCESS == sapi_send_headers(TSRMLS_C)) && body) { PHPWRITE(body, strlen(body)); } switch (status) { - 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; + 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 305: http_log(HTTP_G->log.redirect, "305-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; } STR_FREE(header); STR_FREE(body); - if (HTTP_G(force_exit)) { + if (HTTP_G->force_exit) { zend_bailout(); } else { php_ob_set_internal_handler(http_ob_blackhole, 4096, "blackhole", 0 TSRMLS_CC); @@ -314,16 +322,78 @@ PHP_HTTP_API STATUS _http_get_request_body_ex(char **body, size_t *length, zend_ { *length = 0; *body = NULL; - + if (SG(request_info).raw_post_data) { *length = SG(request_info).raw_post_data_length; - *body = (char *) (dup ? estrndup(SG(request_info).raw_post_data, *length) : SG(request_info).raw_post_data); + *body = SG(request_info).raw_post_data; + + if (dup) { + *body = estrndup(*body, *length); + } + return SUCCESS; + } else if (sapi_module.read_post && !HTTP_G->read_post_data) { + char buf[4096]; + int len; + + HTTP_G->read_post_data = 1; + + while (0 < (len = sapi_module.read_post(buf, sizeof(buf) TSRMLS_CC))) { + *body = erealloc(*body, *length + len + 1); + memcpy(*body + *length, buf, len); + *length += len; + (*body)[*length] = '\0'; + } + + /* check for error */ + if (len < 0) { + STR_FREE(*body); + *length = 0; + return FAILURE; + } + + SG(request_info).raw_post_data = *body; + SG(request_info).raw_post_data_length = *length; + + if (dup) { + *body = estrndup(*body, *length); + } return SUCCESS; } + return FAILURE; } /* }}} */ +/* {{{ php_stream *_http_get_request_body_stream(void) */ +PHP_HTTP_API php_stream *_http_get_request_body_stream(TSRMLS_D) +{ + php_stream *s = NULL; + + if (SG(request_info).raw_post_data) { + s = php_stream_open_wrapper("php://input", "rb", 0, NULL); + } else if (sapi_module.read_post && !HTTP_G->read_post_data) { + HTTP_G->read_post_data = 1; + + if ((s = php_stream_temp_new())) { + char buf[4096]; + int len; + + while (0 < (len = sapi_module.read_post(buf, sizeof(buf) TSRMLS_CC))) { + php_stream_write(s, buf, len); + } + + if (len < 0) { + php_stream_close(s); + s = NULL; + } else { + php_stream_rewind(s); + } + } + } + + return s; +} +/* }}} */ /* * Local variables: