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