- less custom macro cruft
[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-2013, 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 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest___construct, 0, 0, 0)
20 ZEND_ARG_INFO(0, method)
21 ZEND_ARG_INFO(0, url)
22 ZEND_ARG_ARRAY_INFO(0, headers, 1)
23 ZEND_ARG_OBJ_INFO(0, body, http\\Message\\Body, 1)
24 ZEND_END_ARG_INFO();
25 static PHP_METHOD(HttpClientRequest, __construct)
26 {
27 char *meth_str = NULL, *url_str = NULL;
28 int meth_len = 0, url_len = 0;
29 zval *zheaders = NULL, *zbody = NULL;
30
31 with_error_handling(EH_THROW, php_http_exception_class_entry) {
32 if (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)) {
33 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
34 php_http_message_body_object_t *body_obj = NULL;
35
36 if (zbody) {
37 body_obj = zend_object_store_get_object(zbody TSRMLS_CC);
38 Z_OBJ_ADDREF_P(zbody);
39 obj->body->zv = Z_OBJVAL_P(zbody);
40 php_http_message_body_addref(body_obj->body);
41 }
42
43 if (obj->message) {
44 php_http_message_set_type(obj->message, PHP_HTTP_REQUEST);
45 if (body_obj) {
46 php_http_message_body_free(&obj->message->body);
47 obj->message->body = body_obj->body;
48 }
49 } else {
50 obj->message = php_http_message_init(NULL, PHP_HTTP_REQUEST, body_obj ? body_obj->body : NULL TSRMLS_CC);
51 }
52
53 if (meth_str && meth_len) {
54 PHP_HTTP_INFO(obj->message).request.method = estrndup(meth_str, meth_len);
55 }
56 if (url_str && url_len) {
57 PHP_HTTP_INFO(obj->message).request.url = estrndup(url_str, url_len);
58 }
59 if (zheaders) {
60 array_copy(Z_ARRVAL_P(zheaders), &obj->message->hdrs);
61 }
62 }
63 } end_error_handling();
64 }
65
66 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setContentType, 0, 0, 1)
67 ZEND_ARG_INFO(0, content_type)
68 ZEND_END_ARG_INFO();
69 static PHP_METHOD(HttpClientRequest, setContentType)
70 {
71 char *ct_str;
72 int ct_len;
73
74 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ct_str, &ct_len)) {
75 int invalid = 0;
76
77 if (ct_len) {
78 PHP_HTTP_CHECK_CONTENT_TYPE(ct_str, invalid = 1);
79 }
80
81 if (!invalid) {
82 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
83 zval *zct;
84
85 MAKE_STD_ZVAL(zct);
86 ZVAL_STRINGL(zct, ct_str, ct_len, 1);
87 zend_hash_update(&obj->message->hdrs, "Content-Type", sizeof("Content-Type"), (void *) &zct, sizeof(void *), NULL);
88 }
89 }
90 RETVAL_ZVAL(getThis(), 1, 0);
91 }
92
93 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getContentType, 0, 0, 0)
94 ZEND_END_ARG_INFO();
95 static PHP_METHOD(HttpClientRequest, getContentType)
96 {
97 if (SUCCESS == zend_parse_parameters_none()) {
98 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
99 zval *zct = php_http_message_header(obj->message, ZEND_STRL("Content-Type"), 1);
100
101 RETURN_ZVAL(zct, 0, 1);
102 }
103 RETURN_FALSE;
104 }
105
106 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setQuery, 0, 0, 0)
107 ZEND_ARG_INFO(0, query_data)
108 ZEND_END_ARG_INFO();
109 static PHP_METHOD(HttpClientRequest, setQuery)
110 {
111 zval *qdata = NULL;
112
113 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!", &qdata)) {
114 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
115 php_url *old_url = NULL, new_url = {NULL};
116 char empty[] = "";
117
118 if (qdata) {
119 zval arr, str;
120
121 INIT_PZVAL(&arr);
122 array_init(&arr);
123 INIT_PZVAL(&str);
124 ZVAL_NULL(&str);
125
126 php_http_querystring_update(&arr, qdata, &str TSRMLS_CC);
127 new_url.query = Z_STRVAL(str);
128 zval_dtor(&arr);
129 } else {
130 new_url.query = &empty[0];
131 }
132
133 if (obj->message->http.info.request.url) {
134 old_url = php_url_parse(obj->message->http.info.request.url);
135 efree(obj->message->http.info.request.url);
136 }
137
138 php_http_url(PHP_HTTP_URL_REPLACE, old_url, &new_url, NULL, &obj->message->http.info.request.url, NULL TSRMLS_CC);
139
140 if (old_url) {
141 php_url_free(old_url);
142 }
143 if (new_url.query != &empty[0]) {
144 STR_FREE(new_url.query);
145 }
146 }
147 RETVAL_ZVAL(getThis(), 1, 0);
148 }
149
150 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getQuery, 0, 0, 0)
151 ZEND_END_ARG_INFO();
152 static PHP_METHOD(HttpClientRequest, getQuery)
153 {
154 if (SUCCESS == zend_parse_parameters_none()) {
155 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
156
157 if (obj->message->http.info.request.url) {
158 php_url *purl = php_url_parse(obj->message->http.info.request.url);
159
160 if (purl) {
161 if (purl->query) {
162 RETVAL_STRING(purl->query, 0);
163 purl->query = NULL;
164 }
165 php_url_free(purl);
166 }
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;
177
178 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &qdata)) {
179 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
180 php_url *old_url = NULL, new_url = {NULL};
181
182 zval arr, str;
183
184 INIT_PZVAL(&arr);
185 array_init(&arr);
186 INIT_PZVAL(&str);
187 ZVAL_NULL(&str);
188
189 php_http_querystring_update(&arr, qdata, &str TSRMLS_CC);
190 new_url.query = Z_STRVAL(str);
191 zval_dtor(&arr);
192
193 if (obj->message->http.info.request.url) {
194 old_url = php_url_parse(obj->message->http.info.request.url);
195 efree(obj->message->http.info.request.url);
196 }
197
198 php_http_url(PHP_HTTP_URL_JOIN_QUERY, old_url, &new_url, NULL, &obj->message->http.info.request.url, NULL TSRMLS_CC);
199
200 if (old_url) {
201 php_url_free(old_url);
202 }
203 STR_FREE(new_url.query);
204 }
205 RETVAL_ZVAL(getThis(), 1, 0);
206 }
207
208 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setOptions, 0, 0, 0)
209 ZEND_ARG_ARRAY_INFO(0, options, 1)
210 ZEND_END_ARG_INFO();
211 static PHP_METHOD(HttpClientRequest, setOptions)
212 {
213 zval *opts = NULL;
214
215 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) {
216 php_http_client_options_set(getThis(), opts TSRMLS_CC);
217
218 RETVAL_ZVAL(getThis(), 1, 0);
219 }
220 }
221
222 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getOptions, 0, 0, 0)
223 ZEND_END_ARG_INFO();
224 static PHP_METHOD(HttpClientRequest, getOptions)
225 {
226 if (SUCCESS == zend_parse_parameters_none()) {
227 zval *zoptions = zend_read_property(php_http_client_request_class_entry, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC);
228 RETURN_ZVAL(zoptions, 1, 0);
229 }
230 RETURN_FALSE;
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 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) {
241 php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 1 TSRMLS_CC);
242
243 RETVAL_ZVAL(getThis(), 1, 0);
244 }
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 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) {
255 php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 0 TSRMLS_CC);
256
257 RETVAL_ZVAL(getThis(), 1, 0);
258 }
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_STRS("ssl"), return_value TSRMLS_CC);
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 zend_class_entry *php_http_client_request_class_entry;
286
287 PHP_MINIT_FUNCTION(http_client_request)
288 {
289 zend_class_entry ce = {0};
290
291 INIT_NS_CLASS_ENTRY(ce, "http\\Client", "Request", php_http_client_request_methods);
292 php_http_client_request_class_entry = zend_register_internal_class_ex(&ce, php_http_message_class_entry, NULL TSRMLS_CC);
293
294 zend_declare_property_null(php_http_client_request_class_entry, ZEND_STRL("options"), ZEND_ACC_PROTECTED TSRMLS_CC);
295
296 return SUCCESS;
297 }
298
299 /*
300 * Local variables:
301 * tab-width: 4
302 * c-basic-offset: 4
303 * End:
304 * vim600: noet sw=4 ts=4 fdm=marker
305 * vim<600: noet sw=4 ts=4
306 */
307