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