- start open_basedir checks
[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_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)
32 {
33 if (!body) {
34 body = emalloc_rel(sizeof(http_request_body));
35 }
36
37 body->type = type;
38 body->free = free;
39 body->data = data;
40 body->size = size;
41
42 return body;
43 }
44 /* }}} */
45
46 /* {{{ http_request_body *http_request_body_fill(http_request_body *body, HashTable *, HashTable *) */
47 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)
48 {
49 if (files && (zend_hash_num_elements(files) > 0)) {
50 char *key = NULL;
51 ulong idx;
52 zval **data;
53 HashPosition pos;
54 struct curl_httppost *http_post_data[2] = {NULL, NULL};
55
56 /* normal data */
57 FOREACH_HASH_KEYVAL(pos, fields, key, idx, data) {
58 CURLcode err;
59 if (key) {
60 zval *orig = *data;
61
62 convert_to_string_ex(data);
63 err = curl_formadd(&http_post_data[0], &http_post_data[1],
64 CURLFORM_COPYNAME, key,
65 CURLFORM_COPYCONTENTS, Z_STRVAL_PP(data),
66 CURLFORM_CONTENTSLENGTH, (long) Z_STRLEN_PP(data),
67 CURLFORM_END
68 );
69
70 if (orig != *data) {
71 zval_ptr_dtor(data);
72 }
73
74 if (CURLE_OK != err) {
75 http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post fields: %s", curl_easy_strerror(err));
76 curl_formfree(http_post_data[0]);
77 return NULL;
78 }
79
80 /* reset */
81 key = NULL;
82 }
83 }
84
85 /* file data */
86 FOREACH_HASH_VAL(pos, files, data) {
87 zval **file, **type, **name;
88
89 if (Z_TYPE_PP(data) != IS_ARRAY) {
90 http_error(HE_NOTICE, HTTP_E_INVALID_PARAM, "Unrecognized type of post file array entry");
91 } else if ( SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "name", sizeof("name"), (void **) &name) ||
92 SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "type", sizeof("type"), (void **) &type) ||
93 SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "file", sizeof("file"), (void **) &file)) {
94 http_error(HE_NOTICE, HTTP_E_INVALID_PARAM, "Post file array entry misses either 'name', 'type' or 'file' entry");
95 } else {
96 CURLcode err;
97
98 HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_PP(file), curl_formfree(http_post_data[0]); return NULL);
99
100 err = curl_formadd(&http_post_data[0], &http_post_data[1],
101 CURLFORM_COPYNAME, Z_STRVAL_PP(name),
102 CURLFORM_FILE, Z_STRVAL_PP(file),
103 CURLFORM_CONTENTTYPE, Z_STRVAL_PP(type),
104 CURLFORM_END
105 );
106 if (CURLE_OK != err) {
107 http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post files: %s", curl_easy_strerror(err));
108 curl_formfree(http_post_data[0]);
109 return NULL;
110 }
111 }
112 }
113
114 return http_request_body_init_rel(body, HTTP_REQUEST_BODY_CURLPOST, http_post_data[0], 0, 1);
115
116 } else {
117 char *encoded;
118 size_t encoded_len;
119
120 if (SUCCESS != http_urlencode_hash_ex(fields, 1, NULL, 0, &encoded, &encoded_len)) {
121 http_error(HE_WARNING, HTTP_E_ENCODING, "Could not encode post data");
122 return NULL;
123 }
124
125 return http_request_body_init_rel(body, HTTP_REQUEST_BODY_CSTRING, encoded, encoded_len, 1);
126 }
127 }
128
129
130 /* {{{ void http_request_body_dtor(http_request_body *) */
131 PHP_HTTP_API void _http_request_body_dtor(http_request_body *body TSRMLS_DC)
132 {
133 if (body && body->free) {
134 switch (body->type)
135 {
136 case HTTP_REQUEST_BODY_CSTRING:
137 if (body->data) {
138 efree(body->data);
139 }
140 break;
141
142 case HTTP_REQUEST_BODY_CURLPOST:
143 curl_formfree(body->data);
144 break;
145
146 case HTTP_REQUEST_BODY_UPLOADFILE:
147 php_stream_close(body->data);
148 break;
149 }
150 }
151 }
152 /* }}} */
153
154 /* {{{ void http_request_body_free(http_request_body *) */
155 PHP_HTTP_API void _http_request_body_free(http_request_body **body TSRMLS_DC)
156 {
157 if (*body) {
158 http_request_body_dtor(*body);
159 efree(*body);
160 *body = NULL;
161 }
162 }
163 /* }}} */
164
165 #endif /* HTTP_HAVE_CURL */
166
167 /*
168 * Local variables:
169 * tab-width: 4
170 * c-basic-offset: 4
171 * End:
172 * vim600: noet sw=4 ts=4 fdm=marker
173 * vim<600: noet sw=4 ts=4
174 */