prepared for libevent2 usage in config.w32, though libevent usage seems to be broken...
[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 php_http_message_object_set_body(obj, zbody TSRMLS_CC);
38 }
39
40 if (obj->message) {
41 php_http_message_set_type(obj->message, PHP_HTTP_REQUEST);
42 if (body_obj) {
43 php_http_message_body_free(&obj->message->body);
44 obj->message->body = body_obj->body;
45 }
46 } else {
47 obj->message = php_http_message_init(NULL, PHP_HTTP_REQUEST, body_obj ? body_obj->body : NULL TSRMLS_CC);
48 }
49
50 if (meth_str && meth_len) {
51 PHP_HTTP_INFO(obj->message).request.method = estrndup(meth_str, meth_len);
52 }
53 if (url_str && url_len) {
54 PHP_HTTP_INFO(obj->message).request.url = estrndup(url_str, url_len);
55 }
56 if (zheaders) {
57 array_copy(Z_ARRVAL_P(zheaders), &obj->message->hdrs);
58 }
59 }
60 } end_error_handling();
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
71 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ct_str, &ct_len)) {
72 int invalid = 0;
73
74 if (ct_len) {
75 PHP_HTTP_CHECK_CONTENT_TYPE(ct_str, invalid = 1);
76 }
77
78 if (!invalid) {
79 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
80 zval *zct;
81
82 MAKE_STD_ZVAL(zct);
83 ZVAL_STRINGL(zct, ct_str, ct_len, 1);
84 zend_hash_update(&obj->message->hdrs, "Content-Type", sizeof("Content-Type"), (void *) &zct, sizeof(void *), NULL);
85 }
86 }
87 RETVAL_ZVAL(getThis(), 1, 0);
88 }
89
90 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getContentType, 0, 0, 0)
91 ZEND_END_ARG_INFO();
92 static PHP_METHOD(HttpClientRequest, getContentType)
93 {
94 if (SUCCESS == zend_parse_parameters_none()) {
95 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
96 zval *zct = php_http_message_header(obj->message, ZEND_STRL("Content-Type"), 1);
97
98 RETURN_ZVAL(zct, 0, 1);
99 }
100 RETURN_FALSE;
101 }
102
103 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setQuery, 0, 0, 0)
104 ZEND_ARG_INFO(0, query_data)
105 ZEND_END_ARG_INFO();
106 static PHP_METHOD(HttpClientRequest, setQuery)
107 {
108 zval *qdata = NULL;
109
110 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!", &qdata)) {
111 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
112 php_url *old_url = NULL, new_url = {NULL};
113 char empty[] = "";
114
115 if (qdata) {
116 zval arr, str;
117
118 INIT_PZVAL(&arr);
119 array_init(&arr);
120 INIT_PZVAL(&str);
121 ZVAL_NULL(&str);
122
123 php_http_querystring_update(&arr, qdata, &str TSRMLS_CC);
124 new_url.query = Z_STRVAL(str);
125 zval_dtor(&arr);
126 } else {
127 new_url.query = &empty[0];
128 }
129
130 if (obj->message->http.info.request.url) {
131 old_url = php_url_parse(obj->message->http.info.request.url);
132 efree(obj->message->http.info.request.url);
133 }
134
135 php_http_url(PHP_HTTP_URL_REPLACE, old_url, &new_url, NULL, &obj->message->http.info.request.url, NULL TSRMLS_CC);
136
137 if (old_url) {
138 php_url_free(old_url);
139 }
140 if (new_url.query != &empty[0]) {
141 STR_FREE(new_url.query);
142 }
143 }
144 RETVAL_ZVAL(getThis(), 1, 0);
145 }
146
147 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getQuery, 0, 0, 0)
148 ZEND_END_ARG_INFO();
149 static PHP_METHOD(HttpClientRequest, getQuery)
150 {
151 if (SUCCESS == zend_parse_parameters_none()) {
152 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
153
154 if (obj->message->http.info.request.url) {
155 php_url *purl = php_url_parse(obj->message->http.info.request.url);
156
157 if (purl) {
158 if (purl->query) {
159 RETVAL_STRING(purl->query, 0);
160 purl->query = NULL;
161 }
162 php_url_free(purl);
163 }
164 }
165 }
166 }
167
168 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_addQuery, 0, 0, 1)
169 ZEND_ARG_INFO(0, query_data)
170 ZEND_END_ARG_INFO();
171 static PHP_METHOD(HttpClientRequest, addQuery)
172 {
173 zval *qdata;
174
175 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &qdata)) {
176 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
177 php_url *old_url = NULL, new_url = {NULL};
178
179 zval arr, str;
180
181 INIT_PZVAL(&arr);
182 array_init(&arr);
183 INIT_PZVAL(&str);
184 ZVAL_NULL(&str);
185
186 php_http_querystring_update(&arr, qdata, &str TSRMLS_CC);
187 new_url.query = Z_STRVAL(str);
188 zval_dtor(&arr);
189
190 if (obj->message->http.info.request.url) {
191 old_url = php_url_parse(obj->message->http.info.request.url);
192 efree(obj->message->http.info.request.url);
193 }
194
195 php_http_url(PHP_HTTP_URL_JOIN_QUERY, old_url, &new_url, NULL, &obj->message->http.info.request.url, NULL TSRMLS_CC);
196
197 if (old_url) {
198 php_url_free(old_url);
199 }
200 STR_FREE(new_url.query);
201 }
202 RETVAL_ZVAL(getThis(), 1, 0);
203 }
204
205 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setOptions, 0, 0, 0)
206 ZEND_ARG_ARRAY_INFO(0, options, 1)
207 ZEND_END_ARG_INFO();
208 static PHP_METHOD(HttpClientRequest, setOptions)
209 {
210 zval *opts = NULL;
211
212 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) {
213 php_http_client_options_set(getThis(), opts TSRMLS_CC);
214
215 RETVAL_ZVAL(getThis(), 1, 0);
216 }
217 }
218
219 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getOptions, 0, 0, 0)
220 ZEND_END_ARG_INFO();
221 static PHP_METHOD(HttpClientRequest, getOptions)
222 {
223 if (SUCCESS == zend_parse_parameters_none()) {
224 zval *zoptions = zend_read_property(php_http_client_request_class_entry, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC);
225 RETURN_ZVAL(zoptions, 1, 0);
226 }
227 RETURN_FALSE;
228 }
229
230 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_setSslOptions, 0, 0, 0)
231 ZEND_ARG_ARRAY_INFO(0, ssl_options, 1)
232 ZEND_END_ARG_INFO();
233 static PHP_METHOD(HttpClientRequest, setSslOptions)
234 {
235 zval *opts = NULL;
236
237 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) {
238 php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 1 TSRMLS_CC);
239
240 RETVAL_ZVAL(getThis(), 1, 0);
241 }
242 }
243
244 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_addSslOptions, 0, 0, 0)
245 ZEND_ARG_ARRAY_INFO(0, ssl_options, 1)
246 ZEND_END_ARG_INFO();
247 static PHP_METHOD(HttpClientRequest, addSslOptions)
248 {
249 zval *opts = NULL;
250
251 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts)) {
252 php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 0 TSRMLS_CC);
253
254 RETVAL_ZVAL(getThis(), 1, 0);
255 }
256 }
257
258 ZEND_BEGIN_ARG_INFO_EX(ai_HttpClientRequest_getSslOptions, 0, 0, 0)
259 ZEND_END_ARG_INFO();
260 static PHP_METHOD(HttpClientRequest, getSslOptions)
261 {
262 if (SUCCESS == zend_parse_parameters_none()) {
263 php_http_client_options_get_subr(getThis(), ZEND_STRS("ssl"), return_value TSRMLS_CC);
264 }
265 }
266
267 static zend_function_entry php_http_client_request_methods[] = {
268 PHP_ME(HttpClientRequest, __construct, ai_HttpClientRequest___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
269 PHP_ME(HttpClientRequest, setContentType, ai_HttpClientRequest_setContentType, ZEND_ACC_PUBLIC)
270 PHP_ME(HttpClientRequest, getContentType, ai_HttpClientRequest_getContentType, ZEND_ACC_PUBLIC)
271 PHP_ME(HttpClientRequest, setQuery, ai_HttpClientRequest_setQuery, ZEND_ACC_PUBLIC)
272 PHP_ME(HttpClientRequest, getQuery, ai_HttpClientRequest_getQuery, ZEND_ACC_PUBLIC)
273 PHP_ME(HttpClientRequest, addQuery, ai_HttpClientRequest_addQuery, ZEND_ACC_PUBLIC)
274 PHP_ME(HttpClientRequest, setOptions, ai_HttpClientRequest_setOptions, ZEND_ACC_PUBLIC)
275 PHP_ME(HttpClientRequest, getOptions, ai_HttpClientRequest_getOptions, ZEND_ACC_PUBLIC)
276 PHP_ME(HttpClientRequest, setSslOptions, ai_HttpClientRequest_setSslOptions, ZEND_ACC_PUBLIC)
277 PHP_ME(HttpClientRequest, getSslOptions, ai_HttpClientRequest_getSslOptions, ZEND_ACC_PUBLIC)
278 PHP_ME(HttpClientRequest, addSslOptions, ai_HttpClientRequest_addSslOptions, ZEND_ACC_PUBLIC)
279 EMPTY_FUNCTION_ENTRY
280 };
281
282 zend_class_entry *php_http_client_request_class_entry;
283
284 PHP_MINIT_FUNCTION(http_client_request)
285 {
286 zend_class_entry ce = {0};
287
288 INIT_NS_CLASS_ENTRY(ce, "http\\Client", "Request", php_http_client_request_methods);
289 php_http_client_request_class_entry = zend_register_internal_class_ex(&ce, php_http_message_class_entry, NULL TSRMLS_CC);
290
291 zend_declare_property_null(php_http_client_request_class_entry, ZEND_STRL("options"), ZEND_ACC_PROTECTED TSRMLS_CC);
292
293 return SUCCESS;
294 }
295
296 /*
297 * Local variables:
298 * tab-width: 4
299 * c-basic-offset: 4
300 * End:
301 * vim600: noet sw=4 ts=4 fdm=marker
302 * vim<600: noet sw=4 ts=4
303 */
304