X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_api.c;h=4718e3d1b1fcdcbc4233e05526dc53768aaacb82;hp=eb0fab4ddfa89a09c5a2277a7c55deaefa8bb70e;hb=318bb3459a12dc26362978413cde00cde6616d89;hpb=42b9ebf42fbd6b4a111bff5dcdac9e43601381a0 diff --git a/http_api.c b/http_api.c index eb0fab4..4718e3d 100644 --- a/http_api.c +++ b/http_api.c @@ -15,6 +15,7 @@ /* $Id$ */ +#define _WINSOCKAPI_ #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS #ifdef HAVE_CONFIG_H @@ -146,6 +147,8 @@ static int check_tzone(char *tzone); static char *pretty_key(char *key, int key_len, int uctitle, int xhyphen); +static int http_ob_stack_get(php_ob_buffer *, php_ob_buffer **); + /* {{{ HAVE_CURL */ #ifdef HTTP_HAVE_CURL #define http_curl_initbuf(m) _http_curl_initbuf((m) TSRMLS_CC) @@ -290,7 +293,7 @@ static STATUS _http_send_chunk(const void *data, const size_t begin, break; case SEND_DATA: - return len == php_body_write(data + begin, len TSRMLS_CC) + return len == php_body_write(((char *)data) + begin, len TSRMLS_CC) ? SUCCESS : FAILURE; break; @@ -834,6 +837,21 @@ static char *pretty_key(char *key, int key_len, int uctitle, int xhyphen) } /* }}} */ +/* {{{ static STATUS http_ob_stack_get(php_ob_buffer *, php_ob_buffer **) */ +static STATUS http_ob_stack_get(php_ob_buffer *o, php_ob_buffer **s) +{ + static int i = 0; + php_ob_buffer *b = emalloc(sizeof(php_ob_buffer)); + b->handler_name = estrdup(o->handler_name); + b->buffer = estrndup(o->buffer, o->text_length); + b->text_length = o->text_length; + b->chunk_size = o->chunk_size; + b->erase = o->erase; + s[i++] = b; + return SUCCESS; +} +/* }}} */ + /* }}} internals */ /* {{{ public API */ @@ -1067,7 +1085,7 @@ PHP_HTTP_API void _http_ob_etaghandler(char *output, uint output_len, { char etag[33] = { 0 }; unsigned char digest[16]; - + if (mode & PHP_OUTPUT_HANDLER_START) { PHP_MD5Init(&HTTP_G(etag_md5)); } @@ -1076,7 +1094,7 @@ PHP_HTTP_API void _http_ob_etaghandler(char *output, uint output_len, if (mode & PHP_OUTPUT_HANDLER_END) { PHP_MD5Final(digest, &HTTP_G(etag_md5)); - + /* just do that if desired */ if (HTTP_G(etag_started)) { make_digest(etag, digest); @@ -1094,6 +1112,44 @@ PHP_HTTP_API void _http_ob_etaghandler(char *output, uint output_len, } /* }}} */ +/* {{{ STATUS http_start_ob_handler(php_output_handler_func_t, char *, uint, zend_bool) */ +PHP_HTTP_API STATUS _http_start_ob_handler(php_output_handler_func_t handler_func, + char *handler_name, uint chunk_size, zend_bool erase TSRMLS_DC) +{ + php_ob_buffer **stack; + int count, i; + + if (count = OG(ob_nesting_level)) { + stack = ecalloc(sizeof(php_ob_buffer), count); + + if (count > 1) { + zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP, + (int (*)(void *elem, void *)) http_ob_stack_get, stack); + } + + if (count > 0) { + http_ob_stack_get(&OG(active_ob_buffer), stack); + } + + while (OG(ob_nesting_level)) { + php_end_ob_buffer(0, 0 TSRMLS_CC); + } + } + + php_ob_set_internal_handler(handler_func, chunk_size, handler_name, erase TSRMLS_CC); + + for (i = 0; i < count; i++) { + php_ob_buffer *s = stack[i]; + if (strcmp(s->handler_name, "default output handler")) { + php_start_ob_buffer_named(s->handler_name, s->chunk_size, s->erase TSRMLS_CC); + } + php_body_write(s->buffer, s->text_length TSRMLS_CC); + } + + return SUCCESS; +} +/* }}} */ + /* {{{ int http_modified_match(char *, int) */ PHP_HTTP_API int _http_modified_match(const char *entry, const time_t t TSRMLS_DC) { @@ -1541,7 +1597,7 @@ PHP_HTTP_API STATUS _http_send(const void *data_ptr, const size_t data_size, efree(etag); return FAILURE; } - + /* send 304 Not Modified if etag matches */ if ((!is_range_request) && http_etag_match("HTTP_IF_NONE_MATCH", etag)) { efree(etag); @@ -1834,18 +1890,30 @@ PHP_HTTP_API void _http_get_request_headers(zval *array TSRMLS_DC) PHP_HTTP_API STATUS _http_get(const char *URL, HashTable *options, HashTable *info, char **data, size_t *data_len TSRMLS_DC) { + STATUS rs; CURL *ch = curl_easy_init(); if (!ch) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initialize curl"); return FAILURE; } + + rs = http_get_ex(ch, URL, options, info, data, data_len); + curl_easy_cleanup(ch); + return rs; +} +/* }}} */ +/* {{{ STATUS http_get_ex(CURL *, char *, HashTable *, HashTable *, char **, size_t *) */ +PHP_HTTP_API STATUS _http_get_ex(CURL *ch, const char *URL, HashTable *options, + HashTable *info, char **data, size_t *data_len TSRMLS_DC) +{ http_curl_initbuf(CURLBUF_EVRY); http_curl_setopts(ch, URL, options); + curl_easy_setopt(ch, CURLOPT_NOBODY, 0); + curl_easy_setopt(ch, CURLOPT_POST, 0); if (CURLE_OK != curl_easy_perform(ch)) { - curl_easy_cleanup(ch); http_curl_freebuf(CURLBUF_EVRY); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not perform request"); return FAILURE; @@ -1853,31 +1921,38 @@ PHP_HTTP_API STATUS _http_get(const char *URL, HashTable *options, if (info) { http_curl_getinfo(ch, info); } - curl_easy_cleanup(ch); - http_curl_movebuf(CURLBUF_EVRY, data, data_len); - return SUCCESS; } -/* }}} */ /* {{{ STATUS http_head(char *, HashTable *, HashTable *, char **data, size_t *) */ PHP_HTTP_API STATUS _http_head(const char *URL, HashTable *options, HashTable *info, char **data, size_t *data_len TSRMLS_DC) { + STATUS rs; CURL *ch = curl_easy_init(); if (!ch) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initialize curl"); return FAILURE; } + + rs = http_head_ex(ch, URL, options, info, data, data_len); + curl_easy_cleanup(ch); + return rs; +} +/* }}} */ +/* {{{ STATUS http_head_ex(CURL *, char *, HashTable *, HashTable *, char **data, size_t *) */ +PHP_HTTP_API STATUS _http_head_ex(CURL *ch, const char *URL, HashTable *options, + HashTable *info, char **data, size_t *data_len TSRMLS_DC) +{ http_curl_initbuf(CURLBUF_HDRS); http_curl_setopts(ch, URL, options); curl_easy_setopt(ch, CURLOPT_NOBODY, 1); + curl_easy_setopt(ch, CURLOPT_POST, 0); if (CURLE_OK != curl_easy_perform(ch)) { - curl_easy_cleanup(ch); http_curl_freebuf(CURLBUF_HDRS); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not perform request"); return FAILURE; @@ -1885,26 +1960,33 @@ PHP_HTTP_API STATUS _http_head(const char *URL, HashTable *options, if (info) { http_curl_getinfo(ch, info); } - curl_easy_cleanup(ch); - http_curl_movebuf(CURLBUF_HDRS, data, data_len); - return SUCCESS; } -/* }}} */ /* {{{ STATUS http_post_data(char *, char *, size_t, HashTable *, HashTable *, char **, size_t *) */ PHP_HTTP_API STATUS _http_post_data(const char *URL, char *postdata, size_t postdata_len, HashTable *options, HashTable *info, char **data, size_t *data_len TSRMLS_DC) { + STATUS rs; CURL *ch = curl_easy_init(); if (!ch) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initialize curl"); return FAILURE; } + rs = http_post_data_ex(ch, URL, postdata, postdata_len, options, info, data, data_len); + curl_easy_cleanup(ch); + return rs; +} +/* }}} */ +/* {{{ STATUS http_post_data_ex(CURL *, char *, char *, size_t, HashTable *, HashTable *, char **, size_t *) */ +PHP_HTTP_API STATUS _http_post_data_ex(CURL *ch, const char *URL, char *postdata, + size_t postdata_len, HashTable *options, HashTable *info, char **data, + size_t *data_len TSRMLS_DC) +{ http_curl_initbuf(CURLBUF_EVRY); http_curl_setopts(ch, URL, options); curl_easy_setopt(ch, CURLOPT_POST, 1); @@ -1912,7 +1994,6 @@ PHP_HTTP_API STATUS _http_post_data(const char *URL, char *postdata, curl_easy_setopt(ch, CURLOPT_POSTFIELDSIZE, postdata_len); if (CURLE_OK != curl_easy_perform(ch)) { - curl_easy_cleanup(ch); http_curl_freebuf(CURLBUF_EVRY); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not perform request"); return FAILURE; @@ -1920,10 +2001,7 @@ PHP_HTTP_API STATUS _http_post_data(const char *URL, char *postdata, if (info) { http_curl_getinfo(ch, info); } - curl_easy_cleanup(ch); - http_curl_movebuf(CURLBUF_EVRY, data, data_len); - return SUCCESS; } /* }}} */