Merge branch 'R_2_0'
[m6w6/ext-http] / php_http_client_request.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-2014, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #include "php_http_api.h"
14
15 void php_http_client_options_set_subr(zval *this_ptr, char *key, size_t len, zval *opts, int overwrite TSRMLS_DC);
16 void php_http_client_options_set(zval *this_ptr, zval *opts TSRMLS_DC);
17 void php_http_client_options_get_subr(zval *this_ptr, char *key, size_t len, zval *return_value TSRMLS_DC);
18
19 #define PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj) \
20 do { \
21 if (!obj->message) { \
22 obj->message = php_http_message_init(NULL, PHP_HTTP_REQUEST, NULL TSRMLS_CC); \
23 } \
24 } while(0)
25
26 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest___construct, 0, 0, 0)
27 ZEND_ARG_INFO(0, method)
28 ZEND_ARG_INFO(0, url)
29 ZEND_ARG_ARRAY_INFO(0, headers, 1)
30 ZEND_ARG_OBJ_INFO(0, body, http\\Message\\Body, 1)
31 ZEND_END_ARG_INFO();
32 static PHP_METHOD(HttpClientRequest, __construct)
33 {
34 char *meth_str = NULL, *url_str = NULL;
35 int meth_len = 0, url_len = 0;
36 zval *zheaders = NULL, *zbody = NULL;
37 php_http_message_object_t *obj;
38
39 php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!a!O!", &meth_str, &meth_len, &url_str, &url_len, &zheaders, &zbody, php_http_message_body_class_entry), invalid_arg, return);
40
41 obj = zend_object_store_get_object(getThis() TSRMLS_CC);
42
43 if (obj->message) {
44 php_http_message_set_type(obj->message, PHP_HTTP_REQUEST);
45 } else {
46 obj->message = php_http_message_init(NULL, PHP_HTTP_REQUEST, NULL TSRMLS_CC);
47 }
48
49 if (zbody) {
50 php_http_expect(SUCCESS == php_http_message_object_set_body(obj, zbody TSRMLS_CC), unexpected_val, return);
51 }
52 if (meth_str && meth_len) {
53 PHP_HTTP_INFO(obj->message).request.method = estrndup(meth_str, meth_len);
54 }
55 if (url_str && url_len) {
56 PHP_HTTP_INFO(obj->message).request.url = estrndup(url_str, url_len);
57 }
58 if (zheaders) {
59 array_copy(Z_ARRVAL_P(zheaders), &obj->message->hdrs);
60 }
61 }
62
63 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setContentType, 0, 0, 1)
64 ZEND_ARG_INFO(0, content_type)
65 ZEND_END_ARG_INFO();
66 static PHP_METHOD(HttpClientRequest, setContentType)
67 {
68 char *ct_str;
69 int ct_len;
70 php_http_message_object_t *obj;
71 zval *zct;
72
73 php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ct_str, &ct_len), invalid_arg, return);
74
75 if (ct_len && !strchr(ct_str, '/')) {
76 php_http_throw(unexpected_val, "Content type \"%s\" does not seem to contain a primary and a secondary part", ct_str);
77 return;
78 }
79
80 obj = zend_object_store_get_object(getThis() TSRMLS_CC);
81
82 PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj);
83
84 MAKE_STD_ZVAL(zct);
85 ZVAL_STRINGL(zct, ct_str, ct_len, 1);
86 zend_hash_update(&obj->message->hdrs, "Content-Type", sizeof("Content-Type"), (void *) &zct, sizeof(void *), NULL);
87
88 RETVAL_ZVAL(getThis(), 1, 0);
89 }
90
91 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getContentType, 0, 0, 0)
92 ZEND_END_ARG_INFO();
93 static PHP_METHOD(HttpClientRequest, getContentType)
94 {
95 if (SUCCESS == zend_parse_parameters_none()) {
96 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
97 zval *zct;
98
99 PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj);
100
101 php_http_message_update_headers(obj->message);
102 zct = php_http_message_header(obj->message, ZEND_STRL("Content-Type"), 1);
103 if (zct) {
104 RETURN_ZVAL(zct, 0, 1);
105 }
106 }
107 }
108
109 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setQuery, 0, 0, 0)
110 ZEND_ARG_INFO(0, query_data)
111 ZEND_END_ARG_INFO();
112 static PHP_METHOD(HttpClientRequest, setQuery)
113 {
114 zval *qdata = NULL;
115 php_http_message_object_t *obj;
116 php_url *old_url = NULL, new_url = {NULL};
117 char empty[] = "";
118
119 php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!", &qdata), invalid_arg, return);
120
121 obj = zend_object_store_get_object(getThis() TSRMLS_CC);
122
123 PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj);
124
125 if (qdata) {
126 zval arr, str;
127
128 INIT_PZVAL(&arr);
129 array_init(&arr);
130 INIT_PZVAL(&str);
131 ZVAL_NULL(&str);
132
133 php_http_expect(SUCCESS == php_http_querystring_update(&arr, qdata, &str TSRMLS_CC), bad_querystring,
134 zval_dtor(&arr);
135 return;
136 );
137 new_url.query = Z_STRVAL(str);
138 zval_dtor(&arr);
139 } else {
140 new_url.query = &empty[0];
141 }
142
143 if (obj->message->http.info.request.url) {
144 old_url = php_url_parse(obj->message->http.info.request.url);
145 efree(obj->message->http.info.request.url);
146 }
147
148 php_http_url(PHP_HTTP_URL_REPLACE, old_url, &new_url, NULL, &obj->message->http.info.request.url, NULL TSRMLS_CC);
149
150 if (old_url) {
151 php_url_free(old_url);
152 }
153 if (new_url.query != &empty[0]) {
154 STR_FREE(new_url.query);
155 }
156
157 RETVAL_ZVAL(getThis(), 1, 0);
158 }
159
160 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getQuery, 0, 0, 0)
161 ZEND_END_ARG_INFO();
162 static PHP_METHOD(HttpClientRequest, getQuery)
163 {
164 if (SUCCESS == zend_parse_parameters_none()) {
165 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
166
167 PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj);
168
169 if (obj->message->http.info.request.url) {
170 php_url *purl = php_url_parse(obj->message->http.info.request.url);
171
172 if (purl) {
173 if (purl->query) {
174 RETVAL_STRING(purl->query, 0);
175 purl->query = NULL;
176 }
177 php_url_free(purl);
178 }
179 }
180 }
181 }
182
183 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_addQuery, 0, 0, 1)
184 ZEND_ARG_INFO(0, query_data)
185 ZEND_END_ARG_INFO();
186 static PHP_METHOD(HttpClientRequest, addQuery)
187 {
188 zval *qdata, arr, str;
189 php_http_message_object_t *obj;
190 php_url *old_url = NULL, new_url = {NULL};
191
192 php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &qdata), invalid_arg, return);
193
194 obj = zend_object_store_get_object(getThis() TSRMLS_CC);
195
196 PHP_HTTP_CLIENT_REQUEST_OBJECT_INIT(obj);
197
198 INIT_PZVAL(&arr);
199 array_init(&arr);
200 INIT_PZVAL(&str);
201 ZVAL_NULL(&str);
202
203 php_http_expect(SUCCESS == php_http_querystring_update(&arr, qdata, &str TSRMLS_CC), bad_querystring,
204 zval_dtor(&arr);
205 return;
206 );
207 new_url.query = Z_STRVAL(str);
208 zval_dtor(&arr);
209
210 if (obj->message->http.info.request.url) {
211 old_url = php_url_parse(obj->message->http.info.request.url);
212 efree(obj->message->http.info.request.url);
213 }
214
215 php_http_url(PHP_HTTP_URL_JOIN_QUERY, old_url, &new_url, NULL, &obj->message->http.info.request.url, NULL TSRMLS_CC);
216
217 if (old_url) {
218 php_url_free(old_url);
219 }
220 STR_FREE(new_url.query);
221
222 RETVAL_ZVAL(getThis(), 1, 0);
223 }
224
225 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setOptions, 0, 0, 0)
226 ZEND_ARG_ARRAY_INFO(0, options, 1)
227 ZEND_END_ARG_INFO();
228 static PHP_METHOD(HttpClientRequest, setOptions)
229 {
230 zval *opts = NULL;
231
232 php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return);
233
234 php_http_client_options_set(getThis(), opts TSRMLS_CC);
235
236 RETVAL_ZVAL(getThis(), 1, 0);
237 }
238
239 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getOptions, 0, 0, 0)
240 ZEND_END_ARG_INFO();
241 static PHP_METHOD(HttpClientRequest, getOptions)
242 {
243 if (SUCCESS == zend_parse_parameters_none()) {
244 zval *zoptions = zend_read_property(php_http_client_request_class_entry, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC);
245 RETURN_ZVAL(zoptions, 1, 0);
246 }
247 }
248
249 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setSslOptions, 0, 0, 0)
250 ZEND_ARG_ARRAY_INFO(0, ssl_options, 1)
251 ZEND_END_ARG_INFO();
252 static PHP_METHOD(HttpClientRequest, setSslOptions)
253 {
254 zval *opts = NULL;
255
256 php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return);
257
258 php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 1 TSRMLS_CC);
259
260 RETVAL_ZVAL(getThis(), 1, 0);
261 }
262
263 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_addSslOptions, 0, 0, 0)
264 ZEND_ARG_ARRAY_INFO(0, ssl_options, 1)
265 ZEND_END_ARG_INFO();
266 static PHP_METHOD(HttpClientRequest, addSslOptions)
267 {
268 zval *opts = NULL;
269
270 php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return);
271
272 php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 0 TSRMLS_CC);
273
274 RETVAL_ZVAL(getThis(), 1, 0);
275 }
276
277 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getSslOptions, 0, 0, 0)
278 ZEND_END_ARG_INFO();
279 static PHP_METHOD(HttpClientRequest, getSslOptions)
280 {
281 if (SUCCESS == zend_parse_parameters_none()) {
282 php_http_client_options_get_subr(getThis(), ZEND_STRS("ssl"), return_value TSRMLS_CC);
283 }
284 }
285
286 static zend_function_entry php_http_client_request_methods[] = {
287 PHP_ME(HttpClientRequest, __construct, ai_HttpClientRequest___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
288 PHP_ME(HttpClientRequest, setContentType, ai_HttpClientRequest_setContentType, ZEND_ACC_PUBLIC)
289 PHP_ME(HttpClientRequest, getContentType, ai_HttpClientRequest_getContentType, ZEND_ACC_PUBLIC)
290 PHP_ME(HttpClientRequest, setQuery, ai_HttpClientRequest_setQuery, ZEND_ACC_PUBLIC)
291 PHP_ME(HttpClientRequest, getQuery, ai_HttpClientRequest_getQuery, ZEND_ACC_PUBLIC)
292 PHP_ME(HttpClientRequest, addQuery, ai_HttpClientRequest_addQuery, ZEND_ACC_PUBLIC)
293 PHP_ME(HttpClientRequest, setOptions, ai_HttpClientRequest_setOptions, ZEND_ACC_PUBLIC)
294 PHP_ME(HttpClientRequest, getOptions, ai_HttpClientRequest_getOptions, ZEND_ACC_PUBLIC)
295 PHP_ME(HttpClientRequest, setSslOptions, ai_HttpClientRequest_setSslOptions, ZEND_ACC_PUBLIC)
296 PHP_ME(HttpClientRequest, getSslOptions, ai_HttpClientRequest_getSslOptions, ZEND_ACC_PUBLIC)
297 PHP_ME(HttpClientRequest, addSslOptions, ai_HttpClientRequest_addSslOptions, ZEND_ACC_PUBLIC)
298 EMPTY_FUNCTION_ENTRY
299 };
300
301 zend_class_entry *php_http_client_request_class_entry;
302
303 PHP_MINIT_FUNCTION(http_client_request)
304 {
305 zend_class_entry ce = {0};
306
307 INIT_NS_CLASS_ENTRY(ce, "http\\Client", "Request", php_http_client_request_methods);
308 php_http_client_request_class_entry = zend_register_internal_class_ex(&ce, php_http_message_class_entry, NULL TSRMLS_CC);
309
310 zend_declare_property_null(php_http_client_request_class_entry, ZEND_STRL("options"), ZEND_ACC_PROTECTED TSRMLS_CC);
311
312 return SUCCESS;
313 }
314
315 /*
316 * Local variables:
317 * tab-width: 4
318 * c-basic-offset: 4
319 * End:
320 * vim600: noet sw=4 ts=4 fdm=marker
321 * vim<600: noet sw=4 ts=4
322 */
323