better PHP-5.3 compatibility
[m6w6/ext-http] / php_http_curl_client_datashare.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-2011, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #include "php_http_api.h"
14
15 #if PHP_HTTP_HAVE_CURL
16
17 typedef struct php_http_curl_client_datashare {
18 CURLSH *handle;
19 } php_http_curl_client_datashare_t;
20
21
22 static void *php_http_curlsh_ctor(void *opaque TSRMLS_DC)
23 {
24 return curl_share_init();
25 }
26
27 static void php_http_curlsh_dtor(void *opaque, void *handle TSRMLS_DC)
28 {
29 curl_share_cleanup(handle);
30 }
31
32
33 /* datashare handler ops */
34
35 static php_http_client_datashare_t *php_http_curl_client_datashare_init(php_http_client_datashare_t *h, void *handle)
36 {
37 php_http_curl_client_datashare_t *curl;
38 TSRMLS_FETCH_FROM_CTX(h->ts);
39
40 if (!handle && !(handle = php_http_resource_factory_handle_ctor(h->rf TSRMLS_CC))) {
41 php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_DATASHARE, "could not initialize curl share handle");
42 return NULL;
43 }
44
45 curl = ecalloc(1, sizeof(*curl));
46 curl->handle = handle;
47 h->ctx = curl;
48
49 return h;
50 }
51
52 static void php_http_curl_client_datashare_dtor(php_http_client_datashare_t *h)
53 {
54 php_http_curl_client_datashare_t *curl = h->ctx;
55 TSRMLS_FETCH_FROM_CTX(h->ts);
56
57 php_http_resource_factory_handle_dtor(h->rf, curl->handle TSRMLS_CC);
58
59 efree(curl);
60 h->ctx = NULL;
61 }
62
63 static STATUS php_http_curl_client_datashare_attach(php_http_client_datashare_t *h, php_http_client_t *r)
64 {
65 CURLcode rc;
66 php_http_curl_client_datashare_t *curl = h->ctx;
67 php_http_curl_client_t *recurl = r->ctx;
68 TSRMLS_FETCH_FROM_CTX(h->ts);
69
70 if (r->ops != php_http_curl_client_get_ops()) {
71 php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_DATASHARE, "Cannot attach a non-curl client to this datashare");
72 return FAILURE;
73 }
74
75 if (CURLE_OK != (rc = curl_easy_setopt(recurl->handle, CURLOPT_SHARE, curl->handle))) {
76 php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_DATASHARE, "Could not attach request to the datashare: %s", curl_easy_strerror(rc));
77 return FAILURE;
78 }
79 return SUCCESS;
80 }
81
82 static STATUS php_http_curl_client_datashare_detach(php_http_client_datashare_t *h, php_http_client_t *r)
83 {
84 CURLcode rc;
85 php_http_curl_client_t *recurl = r->ctx;
86 TSRMLS_FETCH_FROM_CTX(h->ts);
87
88
89 if (r->ops != php_http_curl_client_get_ops()) {
90 php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_DATASHARE, "Cannot attach a non-curl client to this datashare");
91 return FAILURE;
92 }
93
94 if (CURLE_OK != (rc = curl_easy_setopt(recurl->handle, CURLOPT_SHARE, NULL))) {
95 php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_DATASHARE, "Could not detach request from the datashare: %s", curl_share_strerror(rc));
96 return FAILURE;
97 }
98 return SUCCESS;
99 }
100
101 static STATUS php_http_curl_client_datashare_setopt(php_http_client_datashare_t *h, php_http_client_datashare_setopt_opt_t opt, void *arg)
102 {
103 CURLSHcode rc;
104 php_http_curl_client_datashare_t *curl = h->ctx;
105
106 switch (opt) {
107 case PHP_HTTP_CLIENT_DATASHARE_OPT_COOKIES:
108 if (CURLSHE_OK != (rc = curl_share_setopt(curl->handle, *((zend_bool *) arg) ? CURLSHOPT_SHARE : CURLSHOPT_UNSHARE, CURL_LOCK_DATA_COOKIE))) {
109 TSRMLS_FETCH_FROM_CTX(h->ts);
110
111 php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_DATASHARE, "Could not %s sharing of cookie data: %s", *((zend_bool *) arg) ? "enable" : "disable", curl_share_strerror(rc));
112 return FAILURE;
113 }
114 break;
115
116 case PHP_HTTP_CLIENT_DATASHARE_OPT_RESOLVER:
117 if (CURLSHE_OK != (rc = curl_share_setopt(curl->handle, *((zend_bool *) arg) ? CURLSHOPT_SHARE : CURLSHOPT_UNSHARE, CURL_LOCK_DATA_DNS))) {
118 TSRMLS_FETCH_FROM_CTX(h->ts);
119
120 php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_DATASHARE, "Could not %s sharing of resolver data: %s", *((zend_bool *) arg) ? "enable" : "disable", curl_share_strerror(rc));
121 return FAILURE;
122 }
123 break;
124
125 #if PHP_HTTP_CURL_VERSION(7,23,0)
126 case PHP_HTTP_CLIENT_DATASHARE_OPT_SSLSESSIONS:
127 if (CURLSHE_OK != (rc = curl_share_setopt(curl->handle, *((zend_bool *) arg) ? CURLSHOPT_SHARE : CURLSHOPT_UNSHARE, CURL_LOCK_DATA_SSL_SESSION))) {
128 TSRMLS_FETCH_FROM_CTX(h->ts);
129
130 php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_DATASHARE, "Could not %s sharing of SSL session data: %s", *((zend_bool *) arg) ? "enable" : "disable", curl_share_strerror(rc));
131 return FAILURE;
132 }
133 break;
134 #endif
135
136 default:
137 return FAILURE;
138 }
139
140 return SUCCESS;
141 }
142
143 static php_http_resource_factory_ops_t php_http_curlsh_resource_factory_ops = {
144 php_http_curlsh_ctor,
145 NULL,
146 php_http_curlsh_dtor
147 };
148
149 static php_http_client_datashare_ops_t php_http_curl_client_datashare_ops = {
150 &php_http_curlsh_resource_factory_ops,
151 php_http_curl_client_datashare_init,
152 NULL /* copy */,
153 php_http_curl_client_datashare_dtor,
154 NULL /*reset */,
155 php_http_curl_client_datashare_attach,
156 php_http_curl_client_datashare_detach,
157 php_http_curl_client_datashare_setopt,
158 (php_http_new_t) php_http_curl_client_datashare_object_new_ex,
159 php_http_curl_client_datashare_get_class_entry
160 };
161
162 PHP_HTTP_API php_http_client_datashare_ops_t *php_http_curl_client_datashare_get_ops(void)
163 {
164 return &php_http_curl_client_datashare_ops;
165 }
166
167 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpClientDataShare, method, 0, req_args)
168 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpClientDataShare, method, 0)
169 #define PHP_HTTP_RSHARE_ME(method, visibility) PHP_ME(HttpClientDataShare, method, PHP_HTTP_ARGS(HttpClientDataShare, method), visibility)
170
171 static zend_class_entry *php_http_curl_client_datashare_class_entry;
172
173 zend_class_entry *php_http_curl_client_datashare_get_class_entry(void)
174 {
175 return php_http_curl_client_datashare_class_entry;
176 }
177
178 static zend_function_entry php_http_curl_client_datashare_method_entry[] = {
179 EMPTY_FUNCTION_ENTRY
180 };
181
182 zend_object_value php_http_curl_client_datashare_object_new(zend_class_entry *ce TSRMLS_DC)
183 {
184 return php_http_curl_client_datashare_object_new_ex(ce, NULL, NULL TSRMLS_CC);
185 }
186
187 zend_object_value php_http_curl_client_datashare_object_new_ex(zend_class_entry *ce, php_http_client_datashare_t *share, php_http_client_datashare_object_t **ptr TSRMLS_DC)
188 {
189 zend_object_value ov;
190 php_http_client_datashare_object_t *o;
191
192 o = ecalloc(1, sizeof(*o));
193 zend_object_std_init((zend_object *) o, ce TSRMLS_CC);
194 object_properties_init((zend_object *) o, ce);
195
196 if (share) {
197 o->share = share;
198 } else {
199 o->share = php_http_client_datashare_init(NULL, &php_http_curl_client_datashare_ops, NULL, NULL TSRMLS_CC);
200 }
201
202 if (ptr) {
203 *ptr = o;
204 }
205
206 ov.handle = zend_objects_store_put(o, NULL, php_http_client_datashare_object_free, NULL TSRMLS_CC);
207 ov.handlers = php_http_client_datashare_get_object_handlers();
208
209 return ov;
210 }
211
212
213 PHP_MINIT_FUNCTION(http_curl_client_datashare)
214 {
215 if (SUCCESS != php_http_persistent_handle_provide(ZEND_STRL("http_client_datashare.curl"), &php_http_curlsh_resource_factory_ops, NULL, NULL)) {
216 return FAILURE;
217 }
218
219 PHP_HTTP_REGISTER_CLASS(http\\Curl\\Client, DataShare, http_curl_client_datashare, php_http_client_datashare_get_class_entry(), 0);
220 php_http_curl_client_datashare_class_entry->create_object = php_http_curl_client_datashare_object_new;
221 return SUCCESS;
222 }
223
224 #endif /* PHP_HTTP_HAVE_CURL */
225
226 /*
227 * Local variables:
228 * tab-width: 4
229 * c-basic-offset: 4
230 * End:
231 * vim600: noet sw=4 ts=4 fdm=marker
232 * vim<600: noet sw=4 ts=4
233 */
234