add current state of refactoring
[m6w6/ext-http] / php_http_client_datashare_curl.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_client_datashare_curl {
18 CURLSH *handle;
19 } php_http_client_datashare_curl_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_client_datashare_curl_init(php_http_client_datashare_t *h, void *handle)
36 {
37 php_http_client_datashare_curl_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_client_datashare_curl_dtor(php_http_client_datashare_t *h)
53 {
54 php_http_client_datashare_curl_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_client_datashare_curl_attach(php_http_client_datashare_t *h, php_http_client_t *r)
64 {
65 CURLcode rc;
66 php_http_client_datashare_curl_t *curl = h->ctx;
67 php_http_client_curl_t *recurl = r->ctx;
68 TSRMLS_FETCH_FROM_CTX(h->ts);
69
70 if (CURLE_OK != (rc = curl_easy_setopt(recurl->handle, CURLOPT_SHARE, curl->handle))) {
71 php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_DATASHARE, "Could not attach request to the datashare: %s", curl_easy_strerror(rc));
72 return FAILURE;
73 }
74 return SUCCESS;
75 }
76
77 static STATUS php_http_client_datashare_curl_detach(php_http_client_datashare_t *h, php_http_client_t *r)
78 {
79 CURLcode rc;
80 php_http_client_curl_t *recurl = r->ctx;
81 TSRMLS_FETCH_FROM_CTX(h->ts);
82
83
84 if (CURLE_OK != (rc = curl_easy_setopt(recurl->handle, CURLOPT_SHARE, NULL))) {
85 php_http_error(HE_WARNING, PHP_HTTP_E_CLIENT_DATASHARE, "Could not detach request from the datashare: %s", curl_share_strerror(rc));
86 return FAILURE;
87 }
88 return SUCCESS;
89 }
90
91 static STATUS php_http_client_datashare_curl_setopt(php_http_client_datashare_t *h, php_http_client_datashare_setopt_opt_t opt, void *arg)
92 {
93 CURLSHcode rc;
94 php_http_client_datashare_curl_t *curl = h->ctx;
95
96 switch (opt) {
97 case PHP_HTTP_CLIENT_DATASHARE_OPT_COOKIES:
98 if (CURLSHE_OK != (rc = curl_share_setopt(curl->handle, *((zend_bool *) arg) ? CURLSHOPT_SHARE : CURLSHOPT_UNSHARE, CURL_LOCK_DATA_COOKIE))) {
99 TSRMLS_FETCH_FROM_CTX(h->ts);
100
101 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));
102 return FAILURE;
103 }
104 break;
105
106 case PHP_HTTP_CLIENT_DATASHARE_OPT_RESOLVER:
107 if (CURLSHE_OK != (rc = curl_share_setopt(curl->handle, *((zend_bool *) arg) ? CURLSHOPT_SHARE : CURLSHOPT_UNSHARE, CURL_LOCK_DATA_DNS))) {
108 TSRMLS_FETCH_FROM_CTX(h->ts);
109
110 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));
111 return FAILURE;
112 }
113 break;
114
115 #if PHP_HTTP_CURL_VERSION(7,23,0)
116 case PHP_HTTP_CLIENT_DATASHARE_OPT_SSLSESSIONS:
117 if (CURLSHE_OK != (rc = curl_share_setopt(curl->handle, *((zend_bool *) arg) ? CURLSHOPT_SHARE : CURLSHOPT_UNSHARE, CURL_LOCK_DATA_SSL_SESSION))) {
118 TSRMLS_FETCH_FROM_CTX(h->ts);
119
120 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));
121 return FAILURE;
122 }
123 break;
124 #endif
125
126 default:
127 return FAILURE;
128 }
129
130 return SUCCESS;
131 }
132
133 static php_http_resource_factory_ops_t php_http_curlsh_resource_factory_ops = {
134 php_http_curlsh_ctor,
135 NULL,
136 php_http_curlsh_dtor
137 };
138
139 static php_http_client_datashare_ops_t php_http_client_datashare_curl_ops = {
140 &php_http_curlsh_resource_factory_ops,
141 php_http_client_datashare_curl_init,
142 NULL /* copy */,
143 php_http_client_datashare_curl_dtor,
144 NULL /*reset */,
145 php_http_client_datashare_curl_attach,
146 php_http_client_datashare_curl_detach,
147 php_http_client_datashare_curl_setopt,
148 };
149
150 PHP_HTTP_API php_http_client_datashare_ops_t *php_http_client_datashare_curl_get_ops(void)
151 {
152 return &php_http_client_datashare_curl_ops;
153 }
154
155 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpClientDataShare, method, 0, req_args)
156 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpClientDataShare, method, 0)
157 #define PHP_HTTP_RSHARE_ME(method, visibility) PHP_ME(HttpClientDataShare, method, PHP_HTTP_ARGS(HttpClientDataShare, method), visibility)
158
159 zend_class_entry *php_http_client_datashare_curl_class_entry;
160 zend_function_entry php_http_client_datashare_curl_method_entry[] = {
161 EMPTY_FUNCTION_ENTRY
162 };
163
164 zend_object_value php_http_client_datashare_curl_object_new(zend_class_entry *ce TSRMLS_DC)
165 {
166 return php_http_client_datashare_curl_object_new_ex(ce, NULL, NULL TSRMLS_CC);
167 }
168
169 zend_object_value php_http_client_datashare_curl_object_new_ex(zend_class_entry *ce, php_http_client_datashare_t *share, php_http_client_datashare_object_t **ptr TSRMLS_DC)
170 {
171 zend_object_value ov;
172 php_http_client_datashare_object_t *o;
173
174 o = ecalloc(1, sizeof(*o));
175 zend_object_std_init((zend_object *) o, ce TSRMLS_CC);
176 object_properties_init((zend_object *) o, ce);
177
178 if (share) {
179 o->share = share;
180 } else {
181 o->share = php_http_client_datashare_init(NULL, &php_http_client_datashare_curl_ops, NULL, NULL TSRMLS_CC);
182 }
183
184 if (ptr) {
185 *ptr = o;
186 }
187
188 ov.handle = zend_objects_store_put(o, NULL, php_http_client_datashare_object_free, NULL TSRMLS_CC);
189 ov.handlers = php_http_client_datashare_get_object_handlers();
190
191 return ov;
192 }
193
194
195 PHP_MINIT_FUNCTION(http_client_datashare_curl)
196 {
197 if (SUCCESS != php_http_persistent_handle_provide(ZEND_STRL("http_client_datashare.curl"), &php_http_curlsh_resource_factory_ops, NULL, NULL)) {
198 return FAILURE;
199 }
200
201 PHP_HTTP_REGISTER_CLASS(http\\Client\\DataShare, CURL, http_client_datashare_curl, php_http_client_datashare_class_entry, 0);
202 php_http_client_datashare_curl_class_entry->create_object = php_http_client_datashare_curl_object_new;
203 return SUCCESS;
204 }
205
206 #endif /* PHP_HTTP_HAVE_CURL */
207
208 /*
209 * Local variables:
210 * tab-width: 4
211 * c-basic-offset: 4
212 * End:
213 * vim600: noet sw=4 ts=4 fdm=marker
214 * vim<600: noet sw=4 ts=4
215 */
216