- update
[m6w6/ext-http] / http_functions.c
index 5190d5b48bad8e64c61584467239581466ecdc00..9b57b64204d8254bcf2ae0a34834b5ac4c227734 100644 (file)
 
 /* $Id$ */
 
-#define _WINSOCKAPI_
-#define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
-
 #ifdef HAVE_CONFIG_H
 #      include "config.h"
 #endif
 
 #include "php.h"
 #include "php_ini.h"
-#include "snprintf.h"
 #include "ext/standard/info.h"
 #include "ext/session/php_session.h"
 #include "ext/standard/php_string.h"
-#include "ext/standard/php_smart_str.h"
 
 #include "SAPI.h"
 
+#include "phpstr/phpstr.h"
+
 #include "php_http.h"
+#include "php_http_std_defs.h"
 #include "php_http_api.h"
+#include "php_http_auth_api.h"
 #include "php_http_curl_api.h"
-#include "php_http_std_defs.h"
+#include "php_http_cache_api.h"
+#include "php_http_curl_api.h"
+#include "php_http_date_api.h"
+#include "php_http_headers_api.h"
+#include "php_http_message_api.h"
+#include "php_http_send_api.h"
+#include "php_http_url_api.h"
 
-ZEND_DECLARE_MODULE_GLOBALS(http)
+ZEND_EXTERN_MODULE_GLOBALS(http)
 
 /* {{{ proto string http_date([int timestamp])
  *
@@ -61,7 +66,7 @@ PHP_FUNCTION(http_date)
 }
 /* }}} */
 
-/* {{{ proto string http_absolute_uri(string url[, string proto])
+/* {{{ proto string http_absolute_uri(string url[, string proto[, string host[, int port]]])
  *
  * This function returns an absolute URI constructed from url.
  * If the url is already abolute but a different proto was supplied,
@@ -80,14 +85,15 @@ PHP_FUNCTION(http_date)
  */
 PHP_FUNCTION(http_absolute_uri)
 {
-       char *url = NULL, *proto = NULL;
-       int url_len = 0, proto_len = 0;
+       char *url = NULL, *proto = NULL, *host = NULL;
+       int url_len = 0, proto_len = 0, host_len = 0;
+       long port = 0;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &url, &url_len, &proto, &proto_len) != SUCCESS) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ssl", &url, &url_len, &proto, &proto_len, &host, &host_len, &port) != SUCCESS) {
                RETURN_FALSE;
        }
 
-       RETURN_STRING(http_absolute_uri(url, proto), 0);
+       RETURN_STRING(http_absolute_uri_ex(url, url_len, proto, proto_len, host, host_len, port), 0);
 }
 /* }}} */
 
@@ -269,7 +275,7 @@ PHP_FUNCTION(http_send_content_disposition)
 }
 /* }}} */
 
-/* {{{ proto bool http_match_modified([int timestamp])
+/* {{{ proto bool http_match_modified([int timestamp[, for_range = false]])
  *
  * Matches the given timestamp against the clients "If-Modified-Since" resp.
  * "If-Unmodified-Since" HTTP headers.
@@ -278,8 +284,9 @@ PHP_FUNCTION(http_send_content_disposition)
 PHP_FUNCTION(http_match_modified)
 {
        long t = -1;
+       zend_bool for_range = 0;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &t) != SUCCESS) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &t, &for_range) != SUCCESS) {
                RETURN_FALSE;
        }
 
@@ -288,11 +295,14 @@ PHP_FUNCTION(http_match_modified)
                t = (long) time(NULL);
        }
 
-       RETURN_BOOL(http_modified_match("HTTP_IF_MODIFIED_SINCE", t) || http_modified_match("HTTP_IF_UNMODIFIED_SINCE", t));
+       if (for_range) {
+               RETURN_BOOL(http_modified_match("HTTP_IF_UNMODIFIED_SINCE", t));
+       }
+       RETURN_BOOL(http_modified_match("HTTP_IF_MODIFIED_SINCE", t));
 }
 /* }}} */
 
-/* {{{ proto bool http_match_etag(string etag)
+/* {{{ proto bool http_match_etag(string etag[, for_range = false])
  *
  * This matches the given ETag against the clients
  * "If-Match" resp. "If-None-Match" HTTP headers.
@@ -302,12 +312,16 @@ PHP_FUNCTION(http_match_etag)
 {
        int etag_len;
        char *etag;
+       zend_bool for_range = 0;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &etag, &etag_len) != SUCCESS) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &etag, &etag_len, &for_range) != SUCCESS) {
                RETURN_FALSE;
        }
 
-       RETURN_BOOL(http_etag_match("HTTP_IF_NONE_MATCH", etag) || http_etag_match("HTTP_IF_MATCH", etag));
+       if (for_range) {
+               RETURN_BOOL(http_etag_match("HTTP_IF_MATCH", etag));
+       }
+       RETURN_BOOL(http_etag_match("HTTP_IF_NONE_MATCH", etag));
 }
 /* }}} */
 
@@ -367,7 +381,7 @@ PHP_FUNCTION(http_cache_last_modified)
  */
 PHP_FUNCTION(http_cache_etag)
 {
-       char *etag;
+       char *etag = NULL;
        int etag_len = 0;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &etag, &etag_len) != SUCCESS) {
@@ -459,7 +473,8 @@ PHP_FUNCTION(http_redirect)
                }
        }
 
-       URI = http_absolute_uri(url, NULL);
+       URI = http_absolute_uri(url);
+
        if (query_len) {
                snprintf(LOC, HTTP_URI_MAXLEN + sizeof("Location: "), "Location: %s?%s", URI, query);
                sprintf(RED, "Redirecting to <a href=\"%s?%s\">%s?%s</a>.\n", URI, query, URI, query);
@@ -493,7 +508,7 @@ PHP_FUNCTION(http_send_data)
 
        convert_to_string_ex(&zdata);
        http_send_header("Accept-Ranges: bytes");
-       RETURN_SUCCESS(http_send_data(zdata));
+       RETURN_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)));
 }
 /* }}} */
 
@@ -504,15 +519,18 @@ PHP_FUNCTION(http_send_data)
  */
 PHP_FUNCTION(http_send_file)
 {
-       zval *zfile;
+       char *file;
+       int flen = 0;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zfile) != SUCCESS) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &flen) != SUCCESS) {
+               RETURN_FALSE;
+       }
+       if (!flen) {
                RETURN_FALSE;
        }
 
-       convert_to_string_ex(&zfile);
        http_send_header("Accept-Ranges: bytes");
-       RETURN_SUCCESS(http_send_file(zfile));
+       RETURN_SUCCESS(http_send_file(file));
 }
 /* }}} */
 
@@ -584,7 +602,7 @@ PHP_FUNCTION(http_split_response)
                RETURN_FALSE;
        }
 
-       convert_to_string_ex(&zresponse);
+       convert_to_string(zresponse);
 
        MAKE_STD_ZVAL(zbody);
        MAKE_STD_ZVAL(zheaders);
@@ -619,7 +637,7 @@ PHP_FUNCTION(http_parse_headers)
                header_len = rnrn - header + 2;
        }
        if (SUCCESS != http_parse_headers(header, header_len, return_value)) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP header");
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP headers");
                zval_dtor(return_value);
                RETURN_FALSE;
        }
@@ -631,9 +649,7 @@ PHP_FUNCTION(http_parse_headers)
  */
 PHP_FUNCTION(http_get_request_headers)
 {
-       if (ZEND_NUM_ARGS()) {
-               WRONG_PARAM_COUNT;
-       }
+       NO_ARGS;
 
        array_init(return_value);
        http_get_request_headers(return_value);
@@ -670,6 +686,13 @@ PHP_FUNCTION(http_get_request_headers)
  *  - cookies:          array, list of cookies as associative array
  *                      like array("cookie" => "value")
  *  - cookiestore:      string, path to a file where cookies are/will be stored
+ *  - resume:           int, byte offset to start the download from;
+ *                      if the server supports ranges
+ *  - maxfilesize:      int, maximum file size that should be downloaded;
+ *                      has no effect, if the size of the requested entity is not known
+ *  - lastmodified:     int, timestamp for If-(Un)Modified-Since header
+ *  - timeout:          int, seconds the request may take
+ *  - connecttimeout:   int, seconds the connect may take
  * </pre>
  *
  * The optional third parameter will be filled with some additional information
@@ -721,7 +744,7 @@ PHP_FUNCTION(http_get)
                array_init(info);
        }
 
-       if (SUCCESS == http_get(URL, HASH_ORNULL(options), HASH_ORNULL(info), &data, &data_len)) {
+       if (SUCCESS == http_get(URL, Z_ARRVAL_P(options), Z_ARRVAL_P(info), &data, &data_len)) {
                RETURN_STRINGL(data, data_len, 0);
        } else {
                RETURN_FALSE;
@@ -751,7 +774,7 @@ PHP_FUNCTION(http_head)
                array_init(info);
        }
 
-       if (SUCCESS == http_head(URL, HASH_ORNULL(options), HASH_ORNULL(info), &data, &data_len)) {
+       if (SUCCESS == http_head(URL, Z_ARRVAL_P(options), Z_ARRVAL_P(info), &data, &data_len)) {
                RETURN_STRINGL(data, data_len, 0);
        } else {
                RETURN_FALSE;
@@ -781,7 +804,7 @@ PHP_FUNCTION(http_post_data)
                array_init(info);
        }
 
-       if (SUCCESS == http_post_data(URL, postdata, (size_t) postdata_len, HASH_ORNULL(options), HASH_ORNULL(info), &data, &data_len)) {
+       if (SUCCESS == http_post_data(URL, postdata, (size_t) postdata_len, Z_ARRVAL_P(options), Z_ARRVAL_P(info), &data, &data_len)) {
                RETURN_STRINGL(data, data_len, 0);
        } else {
                RETURN_FALSE;
@@ -811,7 +834,7 @@ PHP_FUNCTION(http_post_array)
                array_init(info);
        }
 
-       if (SUCCESS == http_post_array(URL, Z_ARRVAL_P(postdata), HASH_ORNULL(options), HASH_ORNULL(info), &data, &data_len)) {
+       if (SUCCESS == http_post_array(URL, Z_ARRVAL_P(postdata), Z_ARRVAL_P(options), Z_ARRVAL_P(info), &data, &data_len)) {
                RETURN_STRINGL(data, data_len, 0);
        } else {
                RETURN_FALSE;
@@ -880,7 +903,6 @@ PHP_FUNCTION(http_auth_basic)
  *     }
  *     return false;
  * }
- *
  * if (!http_auth_basic_cb('auth_cb')) {
  *     die('<h1>Authorization failed</h1>');
  * }
@@ -934,18 +956,18 @@ PHP_FUNCTION(http_auth_basic_cb)
 /* }}}*/
 
 /* {{{ Sara Golemons http_build_query() */
-#ifndef ZEND_ENGINE_2 
+#ifndef ZEND_ENGINE_2
 
-/* {{{ proto string http_build_query(mixed formdata [, string prefix])
+/* {{{ proto string http_build_query(mixed formdata [, string prefix[, string arg_separator]])
    Generates a form-encoded query string from an associative array or object. */
 PHP_FUNCTION(http_build_query)
 {
        zval *formdata;
-       char *prefix = NULL;
-       int prefix_len = 0;
-       smart_str formstr = {0};
+       char *prefix = NULL, *arg_sep = INI_STR("arg_separator.output");
+       int prefix_len = 0, arg_sep_len = strlen(arg_sep);
+       phpstr *formstr;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|s", &formdata, &prefix, &prefix_len) != SUCCESS) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ss", &formdata, &prefix, &prefix_len, &arg_sep, &arg_sep_len) != SUCCESS) {
                RETURN_FALSE;
        }
 
@@ -954,25 +976,31 @@ PHP_FUNCTION(http_build_query)
                RETURN_FALSE;
        }
 
-       if (php_url_encode_hash_ex(HASH_OF(formdata), &formstr, prefix, prefix_len, NULL, 0, NULL, 0, (Z_TYPE_P(formdata) == IS_OBJECT ? formdata : NULL) TSRMLS_CC) == FAILURE) {
-               if (formstr.c) {
-                       efree(formstr.c);
-               }
+       if (!arg_sep_len) {
+               arg_sep = HTTP_URL_ARGSEP;
+       }
+
+       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) TSRMLS_CC)) {
+               phpstr_free(formstr);
                RETURN_FALSE;
        }
 
-       if (!formstr.c) {
+       if (!formstr->used) {
+               phpstr_free(formstr);
                RETURN_NULL();
        }
 
-       smart_str_0(&formstr);
-
-       RETURN_STRINGL(formstr.c, formstr.len, 0);
+       RETURN_PHPSTR_PTR(formstr);
 }
 /* }}} */
 #endif /* !ZEND_ENGINE_2 */
 /* }}} */
 
+PHP_FUNCTION(http_test)
+{
+}
+
 /*
  * Local variables:
  * tab-width: 4
@@ -980,4 +1008,5 @@ PHP_FUNCTION(http_build_query)
  * End:
  * vim600: noet sw=4 ts=4 fdm=marker
  * vim<600: noet sw=4 ts=4
- */
\ No newline at end of file
+ */
+