X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=http_api.c;h=0b0eea748831e87098ab354dacad0f3a778b57a1;hb=0dbc3c8eb4ec78fd58d6cc1c80e5189f5ae91094;hp=6046052f1be597943442acb832b0109d00ea4b62;hpb=32e91737086db53bb1fd9ed9f79d693c43ec459f;p=m6w6%2Fext-http diff --git a/http_api.c b/http_api.c index 6046052..0b0eea7 100644 --- a/http_api.c +++ b/http_api.c @@ -12,13 +12,9 @@ /* $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" @@ -99,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; } @@ -123,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(); @@ -145,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 */ @@ -177,6 +186,7 @@ STATUS _http_parse_key_list(const char *list, HashTable *items, char separator, efree(keydup); } while (!done); + efree(str); return SUCCESS; } /* }}} */ @@ -206,11 +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]; - - HTTP_CHECK_OPEN_BASEDIR(file, return); + 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) \ @@ -225,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); } /* }}} */ @@ -253,19 +261,20 @@ STATUS _http_exit_ex(int status, char *header, char *body, zend_bool send_header 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); @@ -313,18 +322,21 @@ 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; - } - - /* PHP only reads POST */ - if (sapi_module.read_post) { + } 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); @@ -333,23 +345,55 @@ PHP_HTTP_API STATUS _http_get_request_body_ex(char **body, size_t *length, zend_ } /* check for error */ - if (len >= 0) { - /* connect to sapi module so it'll be freed */ - if (!dup) { - SG(request_info).raw_post_data = *body; - SG(request_info).raw_post_data_length = *length; - } - return SUCCESS; - } else { + 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: