#define http_globals_free(g) _http_globals_free((g) TSRMLS_CC)
static inline void _http_globals_free(zend_http_globals *G TSRMLS_DC)
{
+ if (G->request.headers) {
+ zend_hash_destroy(G->request.headers);
+ FREE_HASHTABLE(G->request.headers);
+ G->request.headers = NULL;
+ }
STR_SET(G->send.content_type, NULL);
STR_SET(G->send.unquoted_etag, NULL);
}
NO_ARGS;
array_init(return_value);
- http_get_request_headers(return_value);
+ http_get_request_headers(Z_ARRVAL_P(return_value));
}
/* }}} */
}
/* }}} */
-/* {{{ void http_get_request_headers_ex(HashTable *, zend_bool) */
-PHP_HTTP_API void _http_get_request_headers_ex(HashTable *headers, zend_bool prettify TSRMLS_DC)
+/* {{{ void http_get_request_headers(HashTable *) */
+PHP_HTTP_API void _http_get_request_headers(HashTable *headers TSRMLS_DC)
{
char *key = NULL;
ulong idx = 0;
uint keylen = 0;
- zval array, **hsv;
+ zval **hsv, **header;
HashPosition pos;
-
- Z_ARRVAL(array) = headers;
+
+ if (!HTTP_G->request.headers) {
+ ALLOC_HASHTABLE(HTTP_G->request.headers);
+ zend_hash_init(HTTP_G->request.headers, 0, NULL, ZVAL_PTR_DTOR, 0);
+
#ifdef ZEND_ENGINE_2
- zend_is_auto_global("_SERVER", lenof("_SERVER") TSRMLS_CC);
+ zend_is_auto_global("_SERVER", lenof("_SERVER") TSRMLS_CC);
#endif
- if (SUCCESS == zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void *) &hsv)) {
- FOREACH_KEYLEN(pos, *hsv, key, keylen, idx) {
- if (key && keylen > 6 && !strncmp(key, "HTTP_", 5)) {
- zval **header, *orig;
-
- key += 5;
- keylen -= 6;
- if (prettify) {
- key = pretty_key(estrndup(key, keylen), keylen, 1, 1);
- }
-
- zend_hash_get_current_data_ex(Z_ARRVAL_PP(hsv), (void *) &header, &pos);
-
- orig = *header;
- convert_to_string_ex(header);
- add_assoc_stringl(&array, key, Z_STRVAL_PP(header), Z_STRLEN_PP(header), 1);
- if (orig != *header) {
- zval_ptr_dtor(header);
- }
-
- if (prettify) {
- efree(key);
+
+ if (SUCCESS == zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void *) &hsv) && Z_TYPE_PP(hsv) == IS_ARRAY) {
+ FOREACH_KEYLEN(pos, *hsv, key, keylen, idx) {
+ if (key && keylen > 6 && !strncmp(key, "HTTP_", 5)) {
+ keylen -= 6;
+ key = pretty_key(estrndup(key + 5, keylen), keylen, 1, 1);
+
+ zend_hash_get_current_data_ex(Z_ARRVAL_PP(hsv), (void *) &header, &pos);
+ ZVAL_ADDREF(*header);
+ zend_hash_add(HTTP_G->request.headers, key, keylen + 1, (void *) header, sizeof(zval *), NULL);
+
+ STR_SET(key, NULL)
+ keylen = 0;
}
-
- key = NULL;
- keylen = 0;
}
}
}
+
+ if (headers) {
+ zend_hash_copy(headers, HTTP_G->request.headers, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+ }
}
/* }}} */
char *name;
uint name_len = strlen(header);
zend_bool result = 0;
- HashTable headers;
zval **data;
+ http_get_request_headers(NULL);
name = pretty_key(estrndup(header, name_len), name_len, 1, 1);
- zend_hash_init(&headers, 0, NULL, ZVAL_PTR_DTOR, 0);
- http_get_request_headers_ex(&headers, 1);
-
- if (SUCCESS == zend_hash_find(&headers, name, name_len+1, (void *) &data)) {
+ if (SUCCESS == zend_hash_find(HTTP_G->request.headers, name, name_len+1, (void *) &data)) {
+ convert_to_string_ex(data);
result = (match_case ? strcmp(Z_STRVAL_PP(data), value) : strcasecmp(Z_STRVAL_PP(data), value)) ? 0 : 1;
}
- zend_hash_destroy(&headers);
efree(name);
return result;
{
if (ch || (ch = curl_easy_init())) {
#if defined(ZTS)
- HTTP_CURL_OPT_EX(ch, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L);
#endif
- HTTP_CURL_OPT_EX(ch, CURLOPT_HEADER, 0L);
- HTTP_CURL_OPT_EX(ch, CURLOPT_FILETIME, 1L);
- HTTP_CURL_OPT_EX(ch, CURLOPT_AUTOREFERER, 1L);
- HTTP_CURL_OPT_EX(ch, CURLOPT_VERBOSE, 1L);
- HTTP_CURL_OPT_EX(ch, CURLOPT_HEADERFUNCTION, NULL);
- HTTP_CURL_OPT_EX(ch, CURLOPT_DEBUGFUNCTION, http_curl_raw_callback);
- HTTP_CURL_OPT_EX(ch, CURLOPT_READFUNCTION, http_curl_read_callback);
- HTTP_CURL_OPT_EX(ch, CURLOPT_IOCTLFUNCTION, http_curl_ioctl_callback);
- HTTP_CURL_OPT_EX(ch, CURLOPT_WRITEFUNCTION, http_curl_dummy_callback);
+ curl_easy_setopt(ch, CURLOPT_HEADER, 0L);
+ curl_easy_setopt(ch, CURLOPT_FILETIME, 1L);
+ curl_easy_setopt(ch, CURLOPT_AUTOREFERER, 1L);
+ curl_easy_setopt(ch, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(ch, CURLOPT_HEADERFUNCTION, NULL);
+ curl_easy_setopt(ch, CURLOPT_DEBUGFUNCTION, http_curl_raw_callback);
+ curl_easy_setopt(ch, CURLOPT_READFUNCTION, http_curl_read_callback);
+ curl_easy_setopt(ch, CURLOPT_IOCTLFUNCTION, http_curl_ioctl_callback);
+ curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, http_curl_dummy_callback);
/* set context */
if (request) {
- HTTP_CURL_OPT_EX(ch, CURLOPT_PRIVATE, request);
- HTTP_CURL_OPT_EX(ch, CURLOPT_DEBUGDATA, request);
- HTTP_CURL_OPT_EX(ch, CURLOPT_ERRORBUFFER, request->_error);
+ curl_easy_setopt(ch, CURLOPT_PRIVATE, request);
+ curl_easy_setopt(ch, CURLOPT_DEBUGDATA, request);
+ curl_easy_setopt(ch, CURLOPT_ERRORBUFFER, request->_error);
/* attach curl handle */
request->ch = ch;
{
if (*ch) {
/* avoid nasty segfaults with already cleaned up callbacks */
- HTTP_CURL_OPT_EX(*ch, CURLOPT_NOPROGRESS, 1L);
- HTTP_CURL_OPT_EX(*ch, CURLOPT_PROGRESSFUNCTION, NULL);
- HTTP_CURL_OPT_EX(*ch, CURLOPT_VERBOSE, 0L);
- HTTP_CURL_OPT_EX(*ch, CURLOPT_DEBUGFUNCTION, NULL);
+ curl_easy_setopt(*ch, CURLOPT_NOPROGRESS, 1L);
+ curl_easy_setopt(*ch, CURLOPT_PROGRESSFUNCTION, NULL);
+ curl_easy_setopt(*ch, CURLOPT_VERBOSE, 0L);
+ curl_easy_setopt(*ch, CURLOPT_DEBUGFUNCTION, NULL);
curl_easy_cleanup(*ch);
*ch = NULL;
}
struct _http_globals_request {
time_t time;
+ HashTable *headers;
struct _http_globals_request_methods {
char *allowed;
struct _http_globals_request_methods_custom {
#define http_parse_headers_cb(h, ht, p, f, d) _http_parse_headers_ex((h), (ht), (p), (f), (d) TSRMLS_CC)
PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, HashTable *headers, zend_bool prettify, http_info_callback callback_func, void **callback_data TSRMLS_DC);
-#define http_get_request_headers(h) _http_get_request_headers_ex(Z_ARRVAL_P(h), 1 TSRMLS_CC)
-#define http_get_request_headers_ex(h, p) _http_get_request_headers_ex((h), (p) TSRMLS_CC)
-PHP_HTTP_API void _http_get_request_headers_ex(HashTable *headers, zend_bool prettify TSRMLS_DC);
-
typedef char *(*negotiate_func_t)(const char *test, double *quality, HashTable *supported TSRMLS_DC);
#define http_negotiate_language_func _http_negotiate_language_func
#define http_get_request_ranges(r, l) _http_get_request_ranges((r), (l) TSRMLS_CC)
PHP_HTTP_API http_range_status _http_get_request_ranges(HashTable *ranges, size_t length TSRMLS_DC);
+#define http_get_request_headers(h) _http_get_request_headers((h) TSRMLS_CC)
+PHP_HTTP_API void _http_get_request_headers(HashTable *headers TSRMLS_DC);
+
#define http_match_request_header(h, v) http_match_request_header_ex((h), (v), 0)
#define http_match_request_header_ex(h, v, c) _http_match_request_header_ex((h), (v), (c) TSRMLS_CC)
PHP_HTTP_API zend_bool _http_match_request_header_ex(const char *header, const char *value, zend_bool match_case TSRMLS_DC);
# define curl_easy_strerror(dummy) "unknown error"
#endif
-#define HTTP_CURL_OPT(OPTION, p) HTTP_CURL_OPT_EX(request->ch, OPTION, (p))
-#define HTTP_CURL_OPT_EX(ch, OPTION, p) curl_easy_setopt((ch), OPTION, (p))
+#define HTTP_CURL_OPT(OPTION, p) curl_easy_setopt((request->ch), OPTION, (p))
#define HTTP_CURL_OPT_STRING(OPTION, ldiff, obdc) \
{ \