- get rid of 1001 strict-aliasing warnings
[m6w6/ext-http] / http_request_body_api.c
index 423dda00aa77e8b23ad72c42efca7df077fa1807..fcaa635d00f54603a9ba1c820aa944e70427cef1 100644 (file)
@@ -6,16 +6,12 @@
     | modification, are permitted provided that the conditions mentioned |
     | in the accompanying LICENSE file are met.                          |
     +--------------------------------------------------------------------+
-    | Copyright (c) 2004-2005, Michael Wallner <mike@php.net>            |
+    | Copyright (c) 2004-2006, Michael Wallner <mike@php.net>            |
     +--------------------------------------------------------------------+
 */
 
 /* $Id$ */
 
-#ifdef HAVE_CONFIG_H
-#      include "config.h"
-#endif
-
 #define HTTP_WANT_CURL
 #include "php_http.h"
 
 #include "php_http_url_api.h"
 #include "php_http_request_body_api.h"
 
-ZEND_EXTERN_MODULE_GLOBALS(http);
-
 /* {{{ http_request_body *http_request_body_new() */
-PHP_HTTP_API http_request_body *_http_request_body_new(ZEND_FILE_LINE_D ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
+PHP_HTTP_API http_request_body *_http_request_body_init_ex(http_request_body *body, int type, void *data, size_t size, zend_bool free ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
 {
-       return (http_request_body *) ecalloc_rel(1, sizeof(http_request_body));
+       if (!body) {
+               body = emalloc_rel(sizeof(http_request_body));
+       }
+       
+       body->type = type;
+       body->free = free;
+       body->priv = 0;
+       body->data = data;
+       body->size = size;
+       
+       return body;
 }
 /* }}} */
 
-/* {{{ STATUS http_request_body_fill(http_request_body *body, HashTable *, HashTable *) */
-PHP_HTTP_API STATUS _http_request_body_fill(http_request_body *body, HashTable *fields, HashTable *files TSRMLS_DC)
+/* {{{ http_request_body *http_request_body_fill(http_request_body *body, HashTable *, HashTable *) */
+PHP_HTTP_API http_request_body *_http_request_body_fill(http_request_body *body, HashTable *fields, HashTable *files ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
 {
        if (files && (zend_hash_num_elements(files) > 0)) {
                char *key = NULL;
@@ -45,31 +49,33 @@ PHP_HTTP_API STATUS _http_request_body_fill(http_request_body *body, HashTable *
                struct curl_httppost *http_post_data[2] = {NULL, NULL};
 
                /* normal data */
-               FOREACH_HASH_KEYVAL(pos, fields, key, idx, data) {
-                       CURLcode err;
-                       if (key) {
-                               zval *orig = *data;
-                               
-                               convert_to_string_ex(data);
-                               err = curl_formadd(&http_post_data[0], &http_post_data[1],
-                                       CURLFORM_COPYNAME,                      key,
-                                       CURLFORM_COPYCONTENTS,          Z_STRVAL_PP(data),
-                                       CURLFORM_CONTENTSLENGTH,        (long) Z_STRLEN_PP(data),
-                                       CURLFORM_END
-                               );
-                               
-                               if (orig != *data) {
-                                       zval_ptr_dtor(data);
+               if (fields) {
+                       FOREACH_HASH_KEYVAL(pos, fields, key, idx, data) {
+                               if (key) {
+                                       CURLcode err;
+                                       zval *orig = *data;
+                                       
+                                       convert_to_string_ex(data);
+                                       err = curl_formadd(&http_post_data[0], &http_post_data[1],
+                                               CURLFORM_COPYNAME,                      key,
+                                               CURLFORM_COPYCONTENTS,          Z_STRVAL_PP(data),
+                                               CURLFORM_CONTENTSLENGTH,        (long) Z_STRLEN_PP(data),
+                                               CURLFORM_END
+                                       );
+                                       
+                                       if (orig != *data) {
+                                               zval_ptr_dtor(data);
+                                       }
+                                       
+                                       if (CURLE_OK != err) {
+                                               http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post fields: %s", curl_easy_strerror(err));
+                                               curl_formfree(http_post_data[0]);
+                                               return NULL;
+                                       }
+       
+                                       /* reset */
+                                       key = NULL;
                                }
-                               
-                               if (CURLE_OK != err) {
-                                       http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post fields: %s", curl_easy_strerror(err));
-                                       curl_formfree(http_post_data[0]);
-                                       return FAILURE;
-                               }
-
-                               /* reset */
-                               key = NULL;
                        }
                }
 
@@ -79,67 +85,88 @@ PHP_HTTP_API STATUS _http_request_body_fill(http_request_body *body, HashTable *
                        
                        if (Z_TYPE_PP(data) != IS_ARRAY) {
                                http_error(HE_NOTICE, HTTP_E_INVALID_PARAM, "Unrecognized type of post file array entry");
-                       } else if (     SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "name", sizeof("name"), (void **) &name) ||
-                                               SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "type", sizeof("type"), (void **) &type) ||
-                                               SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "file", sizeof("file"), (void **) &file)) {
+                       } else if (     SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "name", sizeof("name"), (void *) &name) ||
+                                               SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "type", sizeof("type"), (void *) &type) ||
+                                               SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "file", sizeof("file"), (void *) &file)) {
                                http_error(HE_NOTICE, HTTP_E_INVALID_PARAM, "Post file array entry misses either 'name', 'type' or 'file' entry");
                        } else {
-                               CURLcode err = curl_formadd(&http_post_data[0], &http_post_data[1],
+                               CURLcode err;
+                               const char *path;
+                               zval *ofile = *file, *otype = *type, *oname = *name;
+                               
+                               convert_to_string_ex(file);
+                               convert_to_string_ex(type);
+                               convert_to_string_ex(name);
+                               
+                               HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_PP(file), curl_formfree(http_post_data[0]); return NULL);
+                               
+                               /* this is blatant but should be sufficient for most cases */
+                               if (strncasecmp(Z_STRVAL_PP(file), "file://", lenof("file://"))) {
+                                       path = Z_STRVAL_PP(file);
+                               } else {
+                                       path = Z_STRVAL_PP(file) + lenof("file://");
+                               }
+                               
+                               err = curl_formadd(&http_post_data[0], &http_post_data[1],
                                        CURLFORM_COPYNAME,              Z_STRVAL_PP(name),
-                                       CURLFORM_FILE,                  Z_STRVAL_PP(file),
+                                       CURLFORM_FILE,                  path,
                                        CURLFORM_CONTENTTYPE,   Z_STRVAL_PP(type),
                                        CURLFORM_END
                                );
+                               
+                               if (ofile != *file) zval_ptr_dtor(file);
+                               if (otype != *type) zval_ptr_dtor(type);
+                               if (oname != *name) zval_ptr_dtor(name);
+                               
                                if (CURLE_OK != err) {
                                        http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post files: %s", curl_easy_strerror(err));
                                        curl_formfree(http_post_data[0]);
-                                       return FAILURE;
+                                       return NULL;
                                }
                        }
                }
+               
+               return http_request_body_init_rel(body, HTTP_REQUEST_BODY_CURLPOST, http_post_data[0], 0, 1);
 
-               body->type = HTTP_REQUEST_BODY_CURLPOST;
-               body->data = http_post_data[0];
-               body->size = 0;
-
-       } else {
+       } else if (fields) {
                char *encoded;
                size_t encoded_len;
 
                if (SUCCESS != http_urlencode_hash_ex(fields, 1, NULL, 0, &encoded, &encoded_len)) {
                        http_error(HE_WARNING, HTTP_E_ENCODING, "Could not encode post data");
-                       return FAILURE;
+                       return NULL;
                }
-
-               body->type = HTTP_REQUEST_BODY_CSTRING;
-               body->data = encoded;
-               body->size = encoded_len;
+               
+               return http_request_body_init_rel(body, HTTP_REQUEST_BODY_CSTRING, encoded, encoded_len, 1);
+       } else {
+               return http_request_body_init_rel(body, HTTP_REQUEST_BODY_CSTRING, estrndup("", 0), 0, 1);
        }
-
-       return SUCCESS;
 }
-/* }}} */
+
 
 /* {{{ void http_request_body_dtor(http_request_body *) */
 PHP_HTTP_API void _http_request_body_dtor(http_request_body *body TSRMLS_DC)
 {
        if (body) {
-               switch (body->type)
-               {
-                       case HTTP_REQUEST_BODY_CSTRING:
-                               if (body->data) {
-                                       efree(body->data);
-                               }
-                       break;
-
-                       case HTTP_REQUEST_BODY_CURLPOST:
-                               curl_formfree(body->data);
-                       break;
-
-                       case HTTP_REQUEST_BODY_UPLOADFILE:
-                               php_stream_close(body->data);
-                       break;
+               if (body->free) {
+                       switch (body->type)
+                       {
+                               case HTTP_REQUEST_BODY_CSTRING:
+                                       if (body->data) {
+                                               efree(body->data);
+                                       }
+                               break;
+       
+                               case HTTP_REQUEST_BODY_CURLPOST:
+                                       curl_formfree(body->data);
+                               break;
+       
+                               case HTTP_REQUEST_BODY_UPLOADFILE:
+                                       php_stream_close(body->data);
+                               break;
+                       }
                }
+               memset(body, 0, sizeof(http_request_body));
        }
 }
 /* }}} */