X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_functions.c;h=8fc26f2cd4ef46b93ef2197daa68a845923e7cc3;hp=fe19c24376d7b3de49eeed7d6f2d4f619794b4ac;hb=refs%2Fheads%2Fv1.7.x;hpb=350e41a4710d4c0f45e30e5d59f28f438292ad42 diff --git a/http_functions.c b/http_functions.c index fe19c24..8fc26f2 100644 --- a/http_functions.c +++ b/http_functions.c @@ -6,7 +6,7 @@ | modification, are permitted provided that the conditions mentioned | | in the accompanying LICENSE file are met. | +--------------------------------------------------------------------+ - | Copyright (c) 2004-2006, Michael Wallner | + | Copyright (c) 2004-2010, Michael Wallner | +--------------------------------------------------------------------+ */ @@ -43,6 +43,7 @@ PHP_FUNCTION(http_date) { long t = -1; + char *date; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &t) != SUCCESS) { RETURN_FALSE; @@ -52,17 +53,22 @@ PHP_FUNCTION(http_date) t = HTTP_G->request.time; } - RETURN_STRING(http_date(t), 0); + if (!(date = http_date(t))) { + http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Could not compose date of timestamp %ld", t); + RETURN_FALSE; + } + + RETURN_STRING(date, 0); } /* }}} */ -/* {{{ proto string http_build_url([mixed url[, mixed parts[, int flags = HTTP_URL_REPLACE[, array &new_url]]]]) +/* {{{ proto string http_build_url([mixed url[, mixed parts[, int flags = HTTP_URL_REPLACE|HTTP_URL_FROM_ENV[, array &new_url]]]]) Build an URL. */ PHP_FUNCTION(http_build_url) { char *url_str = NULL; size_t url_len = 0; - long flags = HTTP_URL_REPLACE; + long flags = HTTP_URL_REPLACE|HTTP_URL_FROM_ENV; zval *z_old_url = NULL, *z_new_url = NULL, *z_composed_url = NULL; php_url *old_url = NULL, *new_url = NULL, *composed_url = NULL; @@ -148,18 +154,41 @@ PHP_FUNCTION(http_build_str) } /* }}} */ -#define HTTP_DO_NEGOTIATE(type, supported, rs_array) \ -{ \ - HashTable *result; \ - if ((result = http_negotiate_ ##type(supported))) { \ +#define HTTP_DO_NEGOTIATE_DEFAULT(supported) \ + { \ + zval **value; \ + \ + zend_hash_internal_pointer_reset(Z_ARRVAL_P(supported)); \ + if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(supported), (void *) &value)) { \ + RETVAL_ZVAL(*value, 1, 0); \ + } else { \ + RETVAL_NULL(); \ + } \ + } + +#define HTTP_DO_NEGOTIATE_HANDLE_DEFAULT(supported, rs_array) \ + HTTP_DO_NEGOTIATE_DEFAULT(supported); \ + if (rs_array) { \ + HashPosition pos; \ + zval **value_ptr; \ + \ + FOREACH_VAL(pos, supported, value_ptr) { \ + zval *value = http_zsep(IS_STRING, *value_ptr); \ + add_assoc_double(rs_array, Z_STRVAL_P(value), 1.0); \ + zval_ptr_dtor(&value); \ + } \ + } + +#define HTTP_DO_NEGOTIATE_HANDLE_RESULT(result, supported, rs_array) \ + { \ char *key; \ uint key_len; \ ulong idx; \ \ - if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(result, &key, &key_len, &idx, 1, NULL)) { \ + if (zend_hash_num_elements(result) && HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(result, &key, &key_len, &idx, 1, NULL)) { \ RETVAL_STRINGL(key, key_len-1, 0); \ } else { \ - RETVAL_NULL(); \ + HTTP_DO_NEGOTIATE_DEFAULT(supported); \ } \ \ if (rs_array) { \ @@ -168,28 +197,17 @@ PHP_FUNCTION(http_build_str) \ zend_hash_destroy(result); \ FREE_HASHTABLE(result); \ - \ - } else { \ - zval **value; \ - \ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(supported)); \ - if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(supported), (void *) &value)) { \ - RETVAL_ZVAL(*value, 1, 0); \ + } + +#define HTTP_DO_NEGOTIATE(type, supported, rs_array) \ + { \ + HashTable *result; \ + if ((result = http_negotiate_ ##type(supported))) { \ + HTTP_DO_NEGOTIATE_HANDLE_RESULT(result, supported, rs_array); \ } else { \ - RETVAL_NULL(); \ + HTTP_DO_NEGOTIATE_HANDLE_DEFAULT(supported, rs_array); \ } \ - \ - if (rs_array) { \ - HashPosition pos; \ - zval **value; \ - \ - FOREACH_VAL(pos, supported, value) { \ - convert_to_string_ex(value); \ - add_assoc_double(rs_array, Z_STRVAL_PP(value), 1.0); \ - } \ - } \ - } \ -} + } /* {{{ proto string http_negotiate_language(array supported[, array &result]) Negotiate the clients preferred language. */ @@ -229,7 +247,7 @@ PHP_FUNCTION(http_negotiate_charset) } /* }}} */ -/* {{{ proto string http_negotiate_ctype(array supported[, array &result]) +/* {{{ proto string http_negotiate_content_type(array supported[, array &result]) Negotiate the clients preferred content type. */ PHP_FUNCTION(http_negotiate_content_type) { @@ -248,11 +266,35 @@ PHP_FUNCTION(http_negotiate_content_type) } /* }}} */ +/* {{{ proto string http_negotiate(mixed value, array supported[, array &result]) + Negotiate the user supplied value. */ +PHP_FUNCTION(http_negotiate) +{ + zval *value, *supported, *rs_array = NULL; + HashTable *rs; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za|z", &value, &supported, &rs_array)) { + RETURN_FALSE; + } + + if (rs_array) { + zval_dtor(rs_array); + array_init(rs_array); + } + + if ((rs = http_negotiate_z(value, Z_ARRVAL_P(supported), http_negotiate_default_func))) { + HTTP_DO_NEGOTIATE_HANDLE_RESULT(rs, supported, rs_array); + } else { + HTTP_DO_NEGOTIATE_HANDLE_DEFAULT(supported, rs_array); + } +} +/* }}} */ + /* {{{ proto bool http_send_status(int status) Send HTTP status code. */ PHP_FUNCTION(http_send_status) { - int status = 0; + long status = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &status) != SUCCESS) { RETURN_FALSE; @@ -488,7 +530,7 @@ PHP_FUNCTION(http_redirect) } } - URI = http_absolute_url(url); + URI = http_absolute_url_ex(url, HTTP_URL_FROM_ENV); if (query_len) { spprintf(&LOC, 0, "Location: %s?%s", URI, query); @@ -671,10 +713,9 @@ PHP_FUNCTION(http_parse_cookie) if (allowed_extras_array) { allowed_extras = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(allowed_extras_array)) + 1, sizeof(char *)); FOREACH_VAL(pos, allowed_extras_array, entry) { - ZVAL_ADDREF(*entry); - convert_to_string_ex(entry); - allowed_extras[i++] = estrndup(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry)); - zval_ptr_dtor(entry); + zval *data = http_zsep(IS_STRING, *entry); + allowed_extras[i++] = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data)); + zval_ptr_dtor(&data); } } @@ -729,15 +770,18 @@ PHP_FUNCTION(http_parse_params) RETURN_FALSE; } - params = ecalloc(1, sizeof(zval)); + MAKE_STD_ZVAL(params); array_init(params); if (SUCCESS != http_parse_params(param, flags, Z_ARRVAL_P(params))) { - zval_dtor(params); - FREE_ZVAL(params); + zval_ptr_dtor(¶ms); RETURN_FALSE; } + object_init(return_value); add_property_zval(return_value, "params", params); +#ifdef ZEND_ENGINE_2 + zval_ptr_dtor(¶ms); +#endif } /* }}} */ @@ -802,10 +846,6 @@ PHP_FUNCTION(http_match_request_header) } /* }}} */ -/* {{{ HAVE_CURL */ -#ifdef HTTP_HAVE_CURL -#ifdef HTTP_HAVE_PERSISTENT_HANDLES - /* {{{ proto object http_persistent_handles_count() */ PHP_FUNCTION(http_persistent_handles_count) { @@ -830,7 +870,7 @@ PHP_FUNCTION(http_persistent_handles_clean) } /* }}} */ -/* {{{ proto string http_persistent_handles_ident(string ident) */ +/* {{{ proto string http_persistent_handles_ident([string ident]) */ PHP_FUNCTION(http_persistent_handles_ident) { char *ident_str = NULL; @@ -845,14 +885,15 @@ PHP_FUNCTION(http_persistent_handles_ident) } /* }}} */ -#endif /* HTTP_HAVE_PERSISTENT_HANDLES */ +/* {{{ HAVE_CURL */ +#ifdef HTTP_HAVE_CURL #define RETVAL_RESPONSE_OR_BODY(request) \ { \ zval **bodyonly; \ \ /* check if only the body should be returned */ \ - if (options && (SUCCESS == zend_hash_find(Z_ARRVAL_P(options), "bodyonly", sizeof("bodyonly"), (void *) &bodyonly)) && zval_is_true(*bodyonly)) { \ + if (options && (SUCCESS == zend_hash_find(Z_ARRVAL_P(options), "bodyonly", sizeof("bodyonly"), (void *) &bodyonly)) && i_zend_is_true(*bodyonly)) { \ http_message *msg = http_message_parse(PHPSTR_VAL(&request.conv.response), PHPSTR_LEN(&request.conv.response)); \ \ if (msg) { \