X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=http_functions.c;h=617d223f1f335d381bdd085c04c7654c48a0dfa8;hb=refs%2Ftags%2FRELEASE_0_13_0;hp=ba2bd56135717d73c50e2ad40693e5179f29e5cd;hpb=4f5d70d375dac27459a80c1e5271697c1f46c675;p=m6w6%2Fext-http
diff --git a/http_functions.c b/http_functions.c
index ba2bd56..617d223 100644
--- a/http_functions.c
+++ b/http_functions.c
@@ -18,23 +18,22 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-
#include "php.h"
+
+#include "SAPI.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "ext/session/php_session.h"
#include "ext/standard/php_string.h"
-
-#include "SAPI.h"
-
-#include "phpstr/phpstr.h"
+#if defined(HAVE_PHP_SESSION) && !defined(COMPILE_DL_SESSION)
+# include "ext/session/php_session.h"
+#endif
#include "php_http.h"
#include "php_http_std_defs.h"
#include "php_http_api.h"
-#include "php_http_auth_api.h"
#include "php_http_request_api.h"
#include "php_http_cache_api.h"
+#include "php_http_request_method_api.h"
#include "php_http_request_api.h"
#include "php_http_date_api.h"
#include "php_http_headers_api.h"
@@ -42,6 +41,8 @@
#include "php_http_send_api.h"
#include "php_http_url_api.h"
+#include "phpstr/phpstr.h"
+
ZEND_EXTERN_MODULE_GLOBALS(http)
/* {{{ proto string http_date([int timestamp])
@@ -203,7 +204,7 @@ PHP_FUNCTION(http_send_status)
RETURN_FALSE;
}
if (status < 100 || status > 510) {
- http_error_ex(E_WARNING, HTTP_E_HEADER, "Invalid HTTP status code (100-510): %d", status);
+ http_error_ex(HE_WARNING, HTTP_E_HEADER, "Invalid HTTP status code (100-510): %d", status);
RETURN_FALSE;
}
@@ -407,7 +408,7 @@ PHP_FUNCTION(ob_etaghandler)
}
Z_TYPE_P(return_value) = IS_STRING;
- http_ob_etaghandler(data, data_len, &Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value), mode);
+ http_ob_etaghandler(data, data_len, &Z_STRVAL_P(return_value), (uint *) &Z_STRLEN_P(return_value), mode);
}
/* }}} */
@@ -416,7 +417,7 @@ PHP_FUNCTION(ob_etaghandler)
* Use with http_send() API.
*
* Example:
- *
+ *
+ *
*/
PHP_FUNCTION(http_throttle)
{
@@ -458,30 +459,65 @@ PHP_FUNCTION(http_redirect)
{
int url_len;
size_t query_len = 0;
- zend_bool session = 0, permanent = 0;
+ zend_bool session = 0, permanent = 0, free_params = 0;
zval *params = NULL;
- char *query, *url, *URI,
- LOC[HTTP_URI_MAXLEN + sizeof("Location: ")],
- RED[HTTP_URI_MAXLEN * 2 + sizeof("Redirecting to %s?%s.\n")];
+ char *query = NULL, *url = NULL, *URI, *LOC, *RED = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sa!/bb", &url, &url_len, ¶ms, &session, &permanent) != SUCCESS) {
RETURN_FALSE;
}
/* append session info */
- if (session && (PS(session_status) == php_session_active)) {
+ if (session) {
if (!params) {
+ free_params = 1;
MAKE_STD_ZVAL(params);
array_init(params);
}
- if (add_assoc_string(params, PS(session_name), PS(id), 1) != SUCCESS) {
- http_error(E_WARNING, HTTP_E_ENCODE, "Could not append session information");
+#ifdef HAVE_PHP_SESSION
+# ifdef COMPILE_DL_SESSION
+ if (SUCCESS == zend_get_module_started("session")) {
+ zval nm_retval, id_retval, func;
+
+ INIT_PZVAL(&func);
+ INIT_PZVAL(&nm_retval);
+ INIT_PZVAL(&id_retval);
+ ZVAL_NULL(&nm_retval);
+ ZVAL_NULL(&id_retval);
+
+ ZVAL_STRINGL(&func, "session_id", lenof("session_id"), 0);
+ call_user_function(EG(function_table), NULL, &func, &id_retval, 0, NULL TSRMLS_CC);
+ ZVAL_STRINGL(&func, "session_name", lenof("session_name"), 0);
+ call_user_function(EG(function_table), NULL, &func, &nm_retval, 0, NULL TSRMLS_CC);
+
+ if ( Z_TYPE(nm_retval) == IS_STRING && Z_STRLEN(nm_retval) &&
+ Z_TYPE(id_retval) == IS_STRING && Z_STRLEN(id_retval)) {
+ if (add_assoc_stringl_ex(params, Z_STRVAL(nm_retval), Z_STRLEN(nm_retval)+1,
+ Z_STRVAL(id_retval), Z_STRLEN(id_retval), 0) != SUCCESS) {
+ http_error(HE_WARNING, HTTP_E_RUNTIME, "Could not append session information");
+ }
+ }
+ }
+# else
+ if (PS(session_status) == php_session_active) {
+ if (add_assoc_string(params, PS(session_name), PS(id), 1) != SUCCESS) {
+ http_error(HE_WARNING, HTTP_E_RUNTIME, "Could not append session information");
+ }
}
+# endif
+#endif
}
/* treat params array with http_build_query() */
if (params) {
if (SUCCESS != http_urlencode_hash_ex(Z_ARRVAL_P(params), 0, NULL, 0, &query, &query_len)) {
+ if (free_params) {
+ zval_dtor(params);
+ FREE_ZVAL(params);
+ }
+ if (query) {
+ efree(query);
+ }
RETURN_FALSE;
}
}
@@ -489,20 +525,27 @@ PHP_FUNCTION(http_redirect)
URI = http_absolute_uri(url);
if (query_len) {
- snprintf(LOC, HTTP_URI_MAXLEN + sizeof("Location: "), "Location: %s?%s", URI, query);
- sprintf(RED, "Redirecting to %s?%s.\n", URI, query, URI, query);
- efree(query);
+ spprintf(&LOC, 0, "Location: %s?%s", URI, query);
+ if (SG(request_info).request_method && strcmp(SG(request_info).request_method, "HEAD")) {
+ spprintf(&RED, 0, "Redirecting to %s?%s.\n", URI, query, URI, query);
+ }
} else {
- snprintf(LOC, HTTP_URI_MAXLEN + sizeof("Location: "), "Location: %s", URI);
- sprintf(RED, "Redirecting to %s.\n", URI, URI);
+ spprintf(&LOC, 0, "Location: %s", URI);
+ if (SG(request_info).request_method && strcmp(SG(request_info).request_method, "HEAD")) {
+ spprintf(&RED, 0, "Redirecting to %s.\n", URI, URI);
+ }
}
+
efree(URI);
-
- if ((SUCCESS == http_send_header(LOC)) && (SUCCESS == http_send_status((permanent ? 301 : 302)))) {
- php_body_write(RED, strlen(RED) TSRMLS_CC);
- RETURN_TRUE;
+ if (query) {
+ efree(query);
+ }
+ if (free_params) {
+ zval_dtor(params);
+ FREE_ZVAL(params);
}
- RETURN_FALSE;
+
+ RETURN_SUCCESS(http_exit_ex(permanent ? 301 : 302, LOC, RED, 1));
}
/* }}} */
@@ -572,60 +615,75 @@ PHP_FUNCTION(http_send_stream)
PHP_FUNCTION(http_chunked_decode)
{
char *encoded = NULL, *decoded = NULL;
- int encoded_len = 0, decoded_len = 0;
+ size_t decoded_len = 0;
+ int encoded_len = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &encoded, &encoded_len) != SUCCESS) {
RETURN_FALSE;
}
if (NULL != http_chunked_decode(encoded, encoded_len, &decoded, &decoded_len)) {
- RETURN_STRINGL(decoded, decoded_len, 0);
+ RETURN_STRINGL(decoded, (int) decoded_len, 0);
} else {
RETURN_FALSE;
}
}
/* }}} */
-/* {{{ proto array http_split_response(string http_response)
- *
- * This function splits an HTTP response into an array with headers and the
- * content body. The returned array may look simliar to the following example:
+/* {{{ proto object http_parse_message(string message)
*
+ * Parses (a) http_message(s) into a simple recursive object structure:
+ *
*
*
- *
* array( - * 'Response Status' => '200 Ok', - * 'Content-Type' => 'text/plain', - * 'Content-Language' => 'en-US' - * ), - * 1 => "Hello World!" - * ); + * print_r(http_parse_message(http_get(URL, array('redirect' => 3))); + * + * stdClass object + * ( + * [type] => 2 + * [httpVersion] => 1.1 + * [responseCode] => 200 + * [headers] => Array + * ( + * [Content-Length] => 3 + * [Server] => Apache + * ) + * [body] => Hi! + * [parentMessage] => stdClass object + * ( + * [type] => 2 + * [httpVersion] => 1.1 + * [responseCode] => 302 + * [headers] => Array + * ( + * [Content-Length] => 0 + * [Location] => ... + * ) + * [body] => + * [parentMessage] => ... + * ) + * ) * ?> **/ -PHP_FUNCTION(http_split_response) +PHP_FUNCTION(http_parse_message) { - zval *zresponse, *zbody, *zheaders; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zresponse) != SUCCESS) { - RETURN_FALSE; + char *message; + int message_len; + http_message *msg = NULL; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &message, &message_len)) { + RETURN_NULL(); } - - convert_to_string(zresponse); - - MAKE_STD_ZVAL(zbody); - MAKE_STD_ZVAL(zheaders); - array_init(zheaders); - - if (SUCCESS != http_split_response(zresponse, zheaders, zbody)) { - http_error(E_WARNING, HTTP_E_PARSE, "Could not parse HTTP response"); - RETURN_FALSE; + + + if (msg = http_message_parse(message, message_len)) { + object_init(return_value); + http_message_tostruct_recursive(msg, return_value); + http_message_free(&msg); + } else { + RETURN_NULL(); } - - array_init(return_value); - add_index_zval(return_value, 0, zheaders); - add_index_zval(return_value, 1, zbody); } /* }}} */ @@ -643,7 +701,6 @@ PHP_FUNCTION(http_parse_headers) array_init(return_value); if (SUCCESS != http_parse_headers(header, return_value)) { - http_error(E_WARNING, HTTP_E_PARSE, "Could not parse HTTP headers"); zval_dtor(return_value); RETURN_FALSE; } @@ -652,6 +709,7 @@ PHP_FUNCTION(http_parse_headers) /* {{{ proto array http_get_request_headers(void) * + * Get a list of incoming HTTP headers. */ PHP_FUNCTION(http_get_request_headers) { @@ -662,6 +720,43 @@ PHP_FUNCTION(http_get_request_headers) } /* }}} */ +/* {{{ proto string http_get_request_body(void) + * + * Get the raw request body (e.g. POST or PUT data). + */ +PHP_FUNCTION(http_get_request_body) +{ + char *body; + size_t length; + + NO_ARGS; + + if (SUCCESS == http_get_request_body(&body, &length)) { + RETURN_STRINGL(body, (int) length, 0); + } else { + RETURN_NULL(); + } +} +/* }}} */ + +/* {{{ proto bool http_match_request_header(string header, string value[, bool match_case = false]) + * + * Match an incoming HTTP header. + */ +PHP_FUNCTION(http_match_request_header) +{ + char *header, *value; + int header_len, value_len; + zend_bool match_case = 0; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &header, &header_len, &value, &value_len, &match_case)) { + RETURN_FALSE; + } + + RETURN_BOOL(http_match_request_header_ex(header, value, match_case)); +} +/* }}} */ + /* {{{ HAVE_CURL */ #ifdef HTTP_HAVE_CURL @@ -700,7 +795,6 @@ PHP_FUNCTION(http_get_request_headers) * - timeout: int, seconds the request may take * - connecttimeout: int, seconds the connect may take * - onprogress: mixed, progress callback - * - ondebug: mixed, debug callback * * * The optional third parameter will be filled with some additional information @@ -728,7 +822,6 @@ PHP_FUNCTION(http_get_request_headers) * 'content_type' => 'text/html; charset=iso-8859-1', * 'redirect_time' => 0, * 'redirect_count' => 0, - * 'private' => '', * 'http_connectcode' => 0, * 'httpauth_avail' => 0, * 'proxyauth_avail' => 0, @@ -754,7 +847,7 @@ PHP_FUNCTION(http_get) phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); if (SUCCESS == http_get(URL, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { - RETURN_PHPSTR_VAL(response); + RETURN_PHPSTR_VAL(&response); } else { RETURN_FALSE; } @@ -785,14 +878,14 @@ PHP_FUNCTION(http_head) phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); if (SUCCESS == http_head(URL, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { - RETURN_PHPSTR_VAL(response); + RETURN_PHPSTR_VAL(&response); } else { RETURN_FALSE; } } /* }}} */ -/* {{{ proto string http_post_data(string url, string data[, array options[, &info]]) +/* {{{ proto string http_post_data(string url, string data[, array options[, array &info]]) * * Performs an HTTP POST request, posting data. * Returns the HTTP response as string. @@ -821,11 +914,10 @@ PHP_FUNCTION(http_post_data) phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); if (SUCCESS == http_post(URL, &body, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { - RETVAL_PHPSTR_VAL(response); + RETVAL_PHPSTR_VAL(&response); } else { RETVAL_FALSE; } - http_request_body_dtor(&body); } /* }}} */ @@ -858,7 +950,7 @@ PHP_FUNCTION(http_post_fields) phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); if (SUCCESS == http_post(URL, &body, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { - RETVAL_PHPSTR_VAL(response); + RETVAL_PHPSTR_VAL(&response); } else { RETVAL_FALSE; } @@ -868,6 +960,9 @@ PHP_FUNCTION(http_post_fields) /* {{{ proto string http_put_file(string url, string file[, array options[, array &info]]) * + * Performs an HTTP PUT request, uploading file. + * Returns the HTTP response as string. + * See http_get() for a full list of available options. */ PHP_FUNCTION(http_put_file) { @@ -902,7 +997,7 @@ PHP_FUNCTION(http_put_file) phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); if (SUCCESS == http_put(URL, &body, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { - RETVAL_PHPSTR_VAL(response); + RETVAL_PHPSTR_VAL(&response); } else { RETVAL_FALSE; } @@ -912,6 +1007,9 @@ PHP_FUNCTION(http_put_file) /* {{{ proto string http_put_stream(string url, resource stream[, array options[, array &info]]) * + * Performs an HTTP PUT request, uploading stream. + * Returns the HTTP response as string. + * See http_get() for a full list of available options. */ PHP_FUNCTION(http_put_stream) { @@ -943,19 +1041,16 @@ PHP_FUNCTION(http_put_stream) phpstr_init_ex(&response, HTTP_CURLBUF_SIZE, 0); if (SUCCESS == http_put(URL, &body, options ? Z_ARRVAL_P(options) : NULL, info ? Z_ARRVAL_P(info) : NULL, &response)) { - RETURN_PHPSTR_VAL(response); + RETURN_PHPSTR_VAL(&response); } else { RETURN_NULL(); } } /* }}} */ -/* {{{ proto bool http_request() - */ -/* }}} */ - /* {{{ proto long http_request_method_register(string method) * + * Register a custom request method. */ PHP_FUNCTION(http_request_method_register) { @@ -976,6 +1071,7 @@ PHP_FUNCTION(http_request_method_register) /* {{{ proto bool http_request_method_unregister(mixed method) * + * Unregister a previously registered custom request method. */ PHP_FUNCTION(http_request_method_unregister) { @@ -1011,6 +1107,7 @@ PHP_FUNCTION(http_request_method_unregister) /* {{{ proto long http_request_method_exists(mixed method) * + * Check if a request method is registered (or available by default). */ PHP_FUNCTION(http_request_method_exists) { @@ -1042,6 +1139,7 @@ PHP_FUNCTION(http_request_method_exists) /* {{{ proto string http_request_method_name(long method) * + * Get the literal string representation of a standard or registered request method. */ PHP_FUNCTION(http_request_method_name) { @@ -1059,116 +1157,6 @@ PHP_FUNCTION(http_request_method_name) #endif /* }}} HAVE_CURL */ - -/* {{{ proto bool http_auth_basic(string user, string pass[, string realm = "Restricted"]) - * - * Example: - *
- * Authorization failed!'); - * } - * ?> - *- */ -PHP_FUNCTION(http_auth_basic) -{ - char *realm = NULL, *user, *pass, *suser, *spass; - int r_len, u_len, p_len; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", &user, &u_len, &pass, &p_len, &realm, &r_len) != SUCCESS) { - RETURN_FALSE; - } - - if (!realm) { - realm = "Restricted"; - } - - if (SUCCESS != http_auth_credentials(&suser, &spass)) { - http_auth_header("Basic", realm); - RETURN_FALSE; - } - - if (strcasecmp(suser, user)) { - http_auth_header("Basic", realm); - RETURN_FALSE; - } - - if (strcmp(spass, pass)) { - http_auth_header("Basic", realm); - RETURN_FALSE; - } - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ proto bool http_auth_basic_cb(mixed callback[, string realm = "Restricted"]) - * - * Example: - *
- * quoteSmart($user); - * if (strlen($realpass = $db->getOne($query)) { - * return $pass === $realpass; - * } - * return false; - * } - * if (!http_auth_basic_cb('auth_cb')) { - * die('- */ -PHP_FUNCTION(http_auth_basic_cb) -{ - zval *cb; - char *realm = NULL, *user, *pass; - int r_len; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|s", &cb, &realm, &r_len) != SUCCESS) { - RETURN_FALSE; - } - - if (!realm) { - realm = "Restricted"; - } - - if (SUCCESS != http_auth_credentials(&user, &pass)) { - http_auth_header("Basic", realm); - RETURN_FALSE; - } - { - zval *zparams[2] = {NULL, NULL}, retval; - int result = 0; - - MAKE_STD_ZVAL(zparams[0]); - MAKE_STD_ZVAL(zparams[1]); - ZVAL_STRING(zparams[0], user, 0); - ZVAL_STRING(zparams[1], pass, 0); - - if (SUCCESS == call_user_function(EG(function_table), NULL, cb, - &retval, 2, zparams TSRMLS_CC)) { - result = Z_LVAL(retval); - } - - efree(user); - efree(pass); - efree(zparams[0]); - efree(zparams[1]); - - if (!result) { - http_auth_header("Basic", realm); - } - - RETURN_BOOL(result); - } -} -/* }}}*/ - /* {{{ Sara Golemons http_build_query() */ #ifndef ZEND_ENGINE_2 @@ -1186,7 +1174,7 @@ PHP_FUNCTION(http_build_query) } if (Z_TYPE_P(formdata) != IS_ARRAY && Z_TYPE_P(formdata) != IS_OBJECT) { - http_error(E_WARNING, HTTP_E_PARAM, "Parameter 1 expected to be Array or Object. Incorrect value given."); + http_error(HE_WARNING, HTTP_E_INVALID_PARAM, "Parameter 1 expected to be Array or Object. Incorrect value given."); RETURN_FALSE; } @@ -1196,12 +1184,12 @@ PHP_FUNCTION(http_build_query) formstr = phpstr_new(); if (SUCCESS != http_urlencode_hash_implementation_ex(HASH_OF(formdata), formstr, arg_sep, prefix, prefix_len, NULL, 0, NULL, 0, (Z_TYPE_P(formdata) == IS_OBJECT ? formdata : NULL))) { - phpstr_free(formstr); + phpstr_free(&formstr); RETURN_FALSE; } if (!formstr->used) { - phpstr_free(formstr); + phpstr_free(&formstr); RETURN_NULL(); } @@ -1213,7 +1201,6 @@ PHP_FUNCTION(http_build_query) PHP_FUNCTION(http_test) { - RETURN_NULL(); } /* @@ -1224,3 +1211,4 @@ PHP_FUNCTION(http_test) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ +Authorization failed
'); - * } - * ?> - *