header cleanups; fix IDE warnings
[m6w6/ext-http] / php_http_neon.c
index 5b26dfcecd3cd4a76eab4d138eaf89ef07eb9131..8a65237f8556962c579c34d47ca9ba703b959f5c 100644 (file)
@@ -1,9 +1,21 @@
+/*
+    +--------------------------------------------------------------------+
+    | PECL :: http                                                       |
+    +--------------------------------------------------------------------+
+    | Redistribution and use in source and binary forms, with or without |
+    | modification, are permitted provided that the conditions mentioned |
+    | in the accompanying LICENSE file are met.                          |
+    +--------------------------------------------------------------------+
+    | Copyright (c) 2004-2011, Michael Wallner <mike@php.net>            |
+    +--------------------------------------------------------------------+
+*/
+
+#include "php_http_api.h"
+
+#if PHP_HTTP_HAVE_NEON
 
-#include "php_http.h"
 #include "php_http_request.h"
 
-#include <ext/date/php_date.h>
-
 #include <neon/ne_auth.h>
 #include <neon/ne_compress.h>
 #include <neon/ne_session.h>
@@ -143,58 +155,34 @@ static void php_http_neon_progress_callback(void *ctx, ne_session_status status,
 {
        php_http_request_t *h = ctx;
        php_http_neon_request_t *neon = h->ctx;
+       TSRMLS_FETCH_FROM_CTX(h->ts);
 
        switch (status) {
                case ne_status_lookup:
+                       neon->progress.state.info = "resolve";
                        break;
                case ne_status_connecting:
+                       neon->progress.state.info = "connect";
                        break;
                case ne_status_connected:
+                       neon->progress.state.info = "connected";
                        break;
                case ne_status_sending:
+                       neon->progress.state.info = "send";
                        neon->progress.state.ul.total = info->sr.total;
                        neon->progress.state.ul.now = info->sr.progress;
                        break;
                case ne_status_recving:
+                       neon->progress.state.info = "receive";
                        neon->progress.state.dl.total = info->sr.total;
                        neon->progress.state.dl.now = info->sr.progress;
                        break;
                case ne_status_disconnected:
+                       neon->progress.state.info = "disconnected";
                        break;
        }
 
-       if (neon->progress.callback) {
-               zval retval;
-               TSRMLS_FETCH_FROM_CTX(h->ts);
-
-               INIT_PZVAL(&retval);
-               ZVAL_NULL(&retval);
-
-               with_error_handling(EH_NORMAL, NULL) {
-                       if (neon->progress.pass_state) {
-                               zval *param;
-
-                               MAKE_STD_ZVAL(param);
-                               array_init(param);
-                               add_assoc_double(param, "dltotal", neon->progress.state.dl.total);
-                               add_assoc_double(param, "dlnow", neon->progress.state.dl.now);
-                               add_assoc_double(param, "ultotal", neon->progress.state.ul.total);
-                               add_assoc_double(param, "ulnow", neon->progress.state.ul.now);
-
-                               neon->progress.in_cb = 1;
-                               call_user_function(EG(function_table), NULL, neon->progress.callback, &retval, 1, &param TSRMLS_CC);
-                               neon->progress.in_cb = 0;
-
-                               zval_ptr_dtor(&param);
-                       } else {
-                               neon->progress.in_cb = 1;
-                               call_user_function(EG(function_table), NULL, neon->progress.callback, &retval, 0, NULL TSRMLS_CC);
-                               neon->progress.in_cb = 0;
-                       }
-               } end_error_handling();
-
-               zval_dtor(&retval);
-       }
+       php_http_request_progress_notify(&neon->progress TSRMLS_CC);
 }
 
 /* helpers */
@@ -219,7 +207,7 @@ static inline zval *get_option(HashTable *cache, HashTable *options, char *key,
                ulong h = zend_hash_func(key, keylen);
 
                if (SUCCESS == zend_hash_quick_find(options, key, keylen, h, (void *) &zoption)) {
-                       zval *option = php_http_zsep(type, *zoption);
+                       zval *option = php_http_ztyp(type, *zoption);
 
                        if (cache) {
                                zval *cached = cache_option(cache, key, keylen, h, option);
@@ -239,6 +227,7 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
        zval *zoption;
        int range_req = 0;
        php_http_neon_request_t *neon = h->ctx;
+       TSRMLS_FETCH_FROM_CTX(h->ts);
 
        /* proxy */
        if ((zoption = get_option(&neon->options.cache, options, ZEND_STRS("proxyhost"), IS_STRING))) {
@@ -361,8 +350,8 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
                                        if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(rr), (void *) &re, &pos2)) {
                                                if (    ((Z_TYPE_PP(rb) == IS_LONG) || ((Z_TYPE_PP(rb) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(rb), Z_STRLEN_PP(rb), NULL, NULL, 1))) &&
                                                                ((Z_TYPE_PP(re) == IS_LONG) || ((Z_TYPE_PP(re) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(re), Z_STRLEN_PP(re), NULL, NULL, 1)))) {
-                                                       zval *rbl = php_http_zsep(IS_LONG, *rb);
-                                                       zval *rel = php_http_zsep(IS_LONG, *re);
+                                                       zval *rbl = php_http_ztyp(IS_LONG, *rb);
+                                                       zval *rel = php_http_ztyp(IS_LONG, *re);
 
                                                        if ((Z_LVAL_P(rbl) >= 0) && (Z_LVAL_P(rel) >= 0)) {
                                                                php_http_buffer_appendf(&rs, "%ld-%ld,", Z_LVAL_P(rbl), Z_LVAL_P(rel));
@@ -377,7 +366,8 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
 
                if (PHP_HTTP_BUFFER_LEN(&rs)) {
                        /* ignore last comma */
-                       php_http_buffer_appendf(&neon->options.headers, "Range: bytes=%.*s" PHP_HTTP_CRLF, rs.used - 1, rs.data);
+                       int used = rs.used > INT_MAX ? INT_MAX : rs.used;
+                       php_http_buffer_appendf(&neon->options.headers, "Range: bytes=%.*s" PHP_HTTP_CRLF, used - 1, rs.data);
                        range_req = 1;
                }
                php_http_buffer_dtor(&rs);
@@ -391,7 +381,7 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
 
                FOREACH_KEYVAL(pos, zoption, header_key, header_val) {
                        if (header_key.type == HASH_KEY_IS_STRING) {
-                               zval *header_cpy = php_http_zsep(IS_STRING, *header_val);
+                               zval *header_cpy = php_http_ztyp(IS_STRING, *header_val);
 
                                if (!strcasecmp(header_key.str, "range")) {
                                        range_req = 1;
@@ -447,7 +437,7 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
 
                        /* check whether cookies should not be urlencoded; default is to urlencode them */
                        if ((!(urlenc_cookies = get_option(&neon->options.cache, options, ZEND_STRS("encodecookies"), IS_BOOL))) || Z_BVAL_P(urlenc_cookies)) {
-                               php_http_url_encode_hash_recursive(HASH_OF(zoption), &neon->options.headers, "; ", lenof("; "), NULL, 0 TSRMLS_CC);
+                               php_http_url_encode_hash_ex(HASH_OF(zoption), &neon->options.headers, ZEND_STRS("; "), ZEND_STRS("="), NULL, 0 TSRMLS_CC);
                        } else {
                                HashPosition pos;
                                php_http_array_hashkey_t cookie_key = php_http_array_hashkey_init(0);
@@ -455,7 +445,7 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
 
                                FOREACH_KEYVAL(pos, zoption, cookie_key, cookie_val) {
                                        if (cookie_key.type == HASH_KEY_IS_STRING) {
-                                               zval *val = php_http_zsep(IS_STRING, *cookie_val);
+                                               zval *val = php_http_ztyp(IS_STRING, *cookie_val);
                                                php_http_buffer_appendf(&neon->options.headers, "%s=%s; ", cookie_key.str, Z_STRVAL_P(val));
                                                zval_ptr_dtor(&val);
                                        }
@@ -494,13 +484,13 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
                        }
                }
                if (SUCCESS == zend_hash_find(Z_ARRVAL_P(zoption), ZEND_STRS("key"), (void *) &zssl)) {
-                       zval *cpy = php_http_zsep(IS_STRING, *zssl);
+                       zval *cpy = php_http_ztyp(IS_STRING, *zssl);
                        ne_ssl_client_cert *cc = ne_ssl_clicert_read(Z_STRVAL_P(cpy));
 
                        if (cc) {
                                if (ne_ssl_clicert_encrypted(cc)) {
                                        if (SUCCESS == zend_hash_find(Z_ARRVAL_P(zoption), ZEND_STRS("keypasswd"), (void *) &zssl)) {
-                                               zval *cpy = php_http_zsep(IS_STRING, *zssl);
+                                               zval *cpy = php_http_ztyp(IS_STRING, *zssl);
 
                                                if (NE_OK == ne_ssl_clicert_decrypt(cc, Z_STRVAL_P(cpy))) {
                                                        neon->options.ssl.clicert = cc;
@@ -517,7 +507,7 @@ static STATUS set_options(php_http_request_t *h, HashTable *options)
                        zval_ptr_dtor(&cpy);
                }
                if (SUCCESS == zend_hash_find(Z_ARRVAL_P(zoption), ZEND_STRS("cert"), (void *) &zssl)) {
-                       zval *cpy = php_http_zsep(IS_STRING, *zssl);
+                       zval *cpy = php_http_ztyp(IS_STRING, *zssl);
                        ne_ssl_certificate *tc = ne_ssl_cert_read(Z_STRVAL_P(cpy));
 
                        if (tc) {
@@ -553,18 +543,21 @@ static php_http_request_t *php_http_neon_request_copy(php_http_request_t *from,
        if (to) {
                return php_http_neon_request_init(to, NULL);
        } else {
-               return php_http_request_init(NULL, from->ops, NULL TSRMLS_CC);
+               return php_http_request_init(NULL, from->ops, from->rf, NULL TSRMLS_CC);
        }
 }
 
 static void php_http_neon_request_dtor(php_http_request_t *h)
 {
        php_http_neon_request_t *ctx = h->ctx;
+       TSRMLS_FETCH_FROM_CTX(h->ts);
 
        php_http_neon_request_reset(h);
        php_http_buffer_dtor(&ctx->options.headers);
        zend_hash_destroy(&ctx->options.cache);
 
+       php_http_request_progress_dtor(&ctx->progress TSRMLS_CC);
+
        efree(ctx);
        h->ctx = NULL;
 }
@@ -572,6 +565,7 @@ static void php_http_neon_request_dtor(php_http_request_t *h)
 static STATUS php_http_neon_request_reset(php_http_request_t *h)
 {
        php_http_neon_request_t *neon = h->ctx;
+       TSRMLS_FETCH_FROM_CTX(h->ts);
 
        php_http_buffer_reset(&neon->options.headers);
        STR_SET(neon->options.useragent, NULL);
@@ -607,15 +601,7 @@ static STATUS php_http_neon_request_reset(php_http_request_t *h)
        neon->options.timeout.read = 0;
        neon->options.timeout.connect = 0;
 
-       if (neon->progress.callback) {
-               zval_ptr_dtor(&neon->progress.callback);
-               neon->progress.callback = NULL;
-       }
-       neon->progress.pass_state = 0;
-       neon->progress.state.dl.now = 0;
-       neon->progress.state.dl.total = 0;
-       neon->progress.state.ul.now = 0;
-       neon->progress.state.ul.total = 0;
+       php_http_request_progress_dtor(&neon->progress TSRMLS_CC);
 
        return SUCCESS;
 }
@@ -632,7 +618,7 @@ static STATUS php_http_neon_request_exec(php_http_request_t *h, php_http_request
        php_http_neon_request_t *neon = h->ctx;
        TSRMLS_FETCH_FROM_CTX(h->ts);
 
-       if (!(meth = php_http_request_method_name(meth_id))) {
+       if (!(meth = php_http_request_method_name(meth_id TSRMLS_CC))) {
                php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST_METHOD, "Unsupported request method: %d (%s)", meth, url);
                return FAILURE;
        }
@@ -645,20 +631,21 @@ static STATUS php_http_neon_request_exec(php_http_request_t *h, php_http_request
        if (neon->options.port) {
                purl->port = neon->options.port;
        } else if (!purl->port) {
+               purl->port = 80;
+               if (strncasecmp(purl->scheme, "http", 4)) {
 #ifdef HAVE_GETSERVBYNAME
-               struct servent *se;
+                       struct servent *se;
 
-               if ((se = getservbyname(purl->scheme, "tcp")) && se->s_port) {
-                       purl->port = ntohs(se->s_port);
-               } else
+                       if ((se = getservbyname(purl->scheme, "tcp")) && se->s_port) {
+                               purl->port = ntohs(se->s_port);
+                       }
 #endif
-               if (!strcasecmp(purl->scheme, "https")) {
+               } else if (purl->scheme[4] == 's') {
                        purl->port = 443;
-               } else {
-                       purl->port = 80;
                }
        }
 
+       /* never returns NULL */
        session = ne_session_create(purl->scheme, purl->host, purl->port);
        if (neon->options.proxy.host) {
                switch (neon->options.proxy.type) {
@@ -786,6 +773,7 @@ retry:
 static STATUS php_http_neon_request_setopt(php_http_request_t *h, php_http_request_setopt_opt_t opt, void *arg)
 {
        php_http_neon_request_t *neon = h->ctx;
+       TSRMLS_FETCH_FROM_CTX(h->ts);
 
        switch (opt) {
                case PHP_HTTP_REQUEST_OPT_SETTINGS:
@@ -793,16 +781,14 @@ static STATUS php_http_neon_request_setopt(php_http_request_t *h, php_http_reque
                        break;
 
                case PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK:
-                       if (neon->progress.callback) {
-                               zval_ptr_dtor(&neon->progress.callback);
+                       if (neon->progress.in_cb) {
+                               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST, "Cannot change progress callback while executing it");
+                               return FAILURE;
                        }
-                       if ((neon->progress.callback = arg)) {
-                               Z_ADDREF_P(neon->progress.callback);
+                       if (neon->progress.callback) {
+                               php_http_request_progress_dtor(&neon->progress TSRMLS_CC);
                        }
-                       break;
-
-               case PHP_HTTP_REQUEST_OPT_PROGRESS_CALLBACK_WANTS_STATE:
-                       neon->progress.pass_state = *((int *)arg);
+                       neon->progress.callback = arg;
                        break;
 
                case PHP_HTTP_REQUEST_OPT_COOKIES_ENABLE:
@@ -825,7 +811,7 @@ static STATUS php_http_neon_request_getopt(php_http_request_t *h, php_http_reque
 
        switch (opt) {
                case PHP_HTTP_REQUEST_OPT_PROGRESS_INFO:
-                       memcpy(arg, &neon->progress, sizeof(neon->progress));
+                       *((php_http_request_progress_t **) arg) = &neon->progress;
                        break;
 
                case PHP_HTTP_REQUEST_OPT_TRANSFER_INFO:
@@ -838,7 +824,14 @@ static STATUS php_http_neon_request_getopt(php_http_request_t *h, php_http_reque
        return SUCCESS;
 }
 
+static php_http_resource_factory_ops_t php_http_neon_resource_factory_ops = {
+               NULL,
+               NULL,
+               NULL
+};
+
 static php_http_request_ops_t php_http_neon_request_ops = {
+       &php_http_neon_resource_factory_ops,
        php_http_neon_request_init,
        php_http_neon_request_copy,
        php_http_neon_request_dtor,
@@ -853,6 +846,25 @@ PHP_HTTP_API php_http_request_ops_t *php_http_neon_get_request_ops(void)
        return &php_http_neon_request_ops;
 }
 
+#define PHP_HTTP_BEGIN_ARGS(method, req_args)  PHP_HTTP_BEGIN_ARGS_EX(HttpNEON, method, 0, req_args)
+#define PHP_HTTP_EMPTY_ARGS(method)                            PHP_HTTP_EMPTY_ARGS_EX(HttpNEON, method, 0)
+#define PHP_HTTP_NEON_ME(method, visibility)   PHP_ME(HttpNEON, method, PHP_HTTP_ARGS(HttpNEON, method), visibility)
+#define PHP_HTTP_NEON_ALIAS(method, func)      PHP_HTTP_STATIC_ME_ALIAS(method, func, PHP_HTTP_ARGS(HttpNEON, method))
+#define PHP_HTTP_NEON_MALIAS(me, al, vis)      ZEND_FENTRY(me, ZEND_MN(HttpNEON_##al), PHP_HTTP_ARGS(HttpNEON, al), vis)
+
+PHP_HTTP_EMPTY_ARGS(__construct);
+
+zend_class_entry *php_http_neon_class_entry;
+zend_function_entry php_http_neon_method_entry[] = {
+       PHP_HTTP_NEON_ME(__construct, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+
+       EMPTY_FUNCTION_ENTRY
+};
+
+PHP_METHOD(HttpNEON, __construct) {
+}
+
+
 PHP_MINIT_FUNCTION(http_neon)
 {
        php_http_request_factory_driver_t driver = {
@@ -863,22 +875,25 @@ PHP_MINIT_FUNCTION(http_neon)
                return FAILURE;
        }
 
+       PHP_HTTP_REGISTER_CLASS(http, NEON, http_neon, php_http_neon_class_entry, 0);
+
        /*
        * Auth Constants
        */
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_BASIC"), NE_AUTH_BASIC TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_DIGEST"), NE_AUTH_DIGEST TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_NTLM"), NE_AUTH_NTLM TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_GSSNEG"), NE_AUTH_GSSAPI TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("AUTH_ANY"), NE_AUTH_ALL TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_BASIC"), NE_AUTH_BASIC TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_DIGEST"), NE_AUTH_DIGEST TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_NTLM"), NE_AUTH_NTLM TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_GSSAPI"), NE_AUTH_GSSAPI TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_GSSNEG"), NE_AUTH_NEGOTIATE TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("AUTH_ANY"), NE_AUTH_ALL TSRMLS_CC);
 
        /*
        * Proxy Type Constants
        */
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_SOCKS4"), NE_SOCK_SOCKSV4 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_SOCKS4A"), NE_SOCK_SOCKSV4A TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_SOCKS5"), NE_SOCK_SOCKSV5 TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_request_class_entry, ZEND_STRL("PROXY_HTTP"), -1 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("PROXY_SOCKS4"), NE_SOCK_SOCKSV4 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("PROXY_SOCKS4A"), NE_SOCK_SOCKSV4A TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("PROXY_SOCKS5"), NE_SOCK_SOCKSV5 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_neon_class_entry, ZEND_STRL("PROXY_HTTP"), -1 TSRMLS_CC);
 
        if (NE_OK != ne_sock_init()) {
                return FAILURE;
@@ -891,3 +906,15 @@ PHP_MSHUTDOWN_FUNCTION(http_neon)
        ne_sock_exit();
        return SUCCESS;
 }
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+