423dda00aa77e8b23ad72c42efca7df077fa1807
[m6w6/ext-http] / http_request_body_api.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: http |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2004-2005, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 /* $Id$ */
14
15 #ifdef HAVE_CONFIG_H
16 # include "config.h"
17 #endif
18
19 #define HTTP_WANT_CURL
20 #include "php_http.h"
21
22 #ifdef HTTP_HAVE_CURL
23
24 #include "php_http_api.h"
25 #include "php_http_url_api.h"
26 #include "php_http_request_body_api.h"
27
28 ZEND_EXTERN_MODULE_GLOBALS(http);
29
30 /* {{{ http_request_body *http_request_body_new() */
31 PHP_HTTP_API http_request_body *_http_request_body_new(ZEND_FILE_LINE_D ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
32 {
33 return (http_request_body *) ecalloc_rel(1, sizeof(http_request_body));
34 }
35 /* }}} */
36
37 /* {{{ STATUS http_request_body_fill(http_request_body *body, HashTable *, HashTable *) */
38 PHP_HTTP_API STATUS _http_request_body_fill(http_request_body *body, HashTable *fields, HashTable *files TSRMLS_DC)
39 {
40 if (files && (zend_hash_num_elements(files) > 0)) {
41 char *key = NULL;
42 ulong idx;
43 zval **data;
44 HashPosition pos;
45 struct curl_httppost *http_post_data[2] = {NULL, NULL};
46
47 /* normal data */
48 FOREACH_HASH_KEYVAL(pos, fields, key, idx, data) {
49 CURLcode err;
50 if (key) {
51 zval *orig = *data;
52
53 convert_to_string_ex(data);
54 err = curl_formadd(&http_post_data[0], &http_post_data[1],
55 CURLFORM_COPYNAME, key,
56 CURLFORM_COPYCONTENTS, Z_STRVAL_PP(data),
57 CURLFORM_CONTENTSLENGTH, (long) Z_STRLEN_PP(data),
58 CURLFORM_END
59 );
60
61 if (orig != *data) {
62 zval_ptr_dtor(data);
63 }
64
65 if (CURLE_OK != err) {
66 http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post fields: %s", curl_easy_strerror(err));
67 curl_formfree(http_post_data[0]);
68 return FAILURE;
69 }
70
71 /* reset */
72 key = NULL;
73 }
74 }
75
76 /* file data */
77 FOREACH_HASH_VAL(pos, files, data) {
78 zval **file, **type, **name;
79
80 if (Z_TYPE_PP(data) != IS_ARRAY) {
81 http_error(HE_NOTICE, HTTP_E_INVALID_PARAM, "Unrecognized type of post file array entry");
82 } else if ( SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "name", sizeof("name"), (void **) &name) ||
83 SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "type", sizeof("type"), (void **) &type) ||
84 SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "file", sizeof("file"), (void **) &file)) {
85 http_error(HE_NOTICE, HTTP_E_INVALID_PARAM, "Post file array entry misses either 'name', 'type' or 'file' entry");
86 } else {
87 CURLcode err = curl_formadd(&http_post_data[0], &http_post_data[1],
88 CURLFORM_COPYNAME, Z_STRVAL_PP(name),
89 CURLFORM_FILE, Z_STRVAL_PP(file),
90 CURLFORM_CONTENTTYPE, Z_STRVAL_PP(type),
91 CURLFORM_END
92 );
93 if (CURLE_OK != err) {
94 http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post files: %s", curl_easy_strerror(err));
95 curl_formfree(http_post_data[0]);
96 return FAILURE;
97 }
98 }
99 }
100
101 body->type = HTTP_REQUEST_BODY_CURLPOST;
102 body->data = http_post_data[0];
103 body->size = 0;
104
105 } else {
106 char *encoded;
107 size_t encoded_len;
108
109 if (SUCCESS != http_urlencode_hash_ex(fields, 1, NULL, 0, &encoded, &encoded_len)) {
110 http_error(HE_WARNING, HTTP_E_ENCODING, "Could not encode post data");
111 return FAILURE;
112 }
113
114 body->type = HTTP_REQUEST_BODY_CSTRING;
115 body->data = encoded;
116 body->size = encoded_len;
117 }
118
119 return SUCCESS;
120 }
121 /* }}} */
122
123 /* {{{ void http_request_body_dtor(http_request_body *) */
124 PHP_HTTP_API void _http_request_body_dtor(http_request_body *body TSRMLS_DC)
125 {
126 if (body) {
127 switch (body->type)
128 {
129 case HTTP_REQUEST_BODY_CSTRING:
130 if (body->data) {
131 efree(body->data);
132 }
133 break;
134
135 case HTTP_REQUEST_BODY_CURLPOST:
136 curl_formfree(body->data);
137 break;
138
139 case HTTP_REQUEST_BODY_UPLOADFILE:
140 php_stream_close(body->data);
141 break;
142 }
143 }
144 }
145 /* }}} */
146
147 /* {{{ void http_request_body_free(http_request_body *) */
148 PHP_HTTP_API void _http_request_body_free(http_request_body **body TSRMLS_DC)
149 {
150 if (*body) {
151 http_request_body_dtor(*body);
152 efree(*body);
153 *body = NULL;
154 }
155 }
156 /* }}} */
157
158 #endif /* HTTP_HAVE_CURL */
159
160 /*
161 * Local variables:
162 * tab-width: 4
163 * c-basic-offset: 4
164 * End:
165 * vim600: noet sw=4 ts=4 fdm=marker
166 * vim<600: noet sw=4 ts=4
167 */