src/server/safs/proxy.c

changeset 706
df64b4b79912
parent 700
658f4c02b4c5
equal deleted inserted replaced
705:30de3bfd0412 706:df64b4b79912
35 #include <ctype.h> 35 #include <ctype.h>
36 #include <string.h> 36 #include <string.h>
37 37
38 #include "../util/pblock.h" 38 #include "../util/pblock.h"
39 #include "../util/util.h" 39 #include "../util/util.h"
40 #include "../util/io.h"
40 #include "../proxy/httpclient.h" 41 #include "../proxy/httpclient.h"
41 42
42 43
43 typedef struct ProxyRequest { 44 typedef struct ProxyRequest {
44 Session *sn; 45 Session *sn;
45 Request *rq; 46 Request *rq;
47
48 HttpClient *client;
46 49
47 /* 50 /*
48 * request header rewrite map 51 * request header rewrite map
49 * name: header name 52 * name: header name
50 * value: header value or an empty string, if the header should be removed 53 * value: header value or an empty string, if the header should be removed
57 * value: header value or an empty string, if the header should be removed 60 * value: header value or an empty string, if the header should be removed
58 */ 61 */
59 pblock *response_header_rewrite; 62 pblock *response_header_rewrite;
60 63
61 /* 64 /*
65 * event structure for sn->csd
66 */
67 Event event;
68
69 /*
62 * Has the response started (proxy_response_start called) 70 * Has the response started (proxy_response_start called)
63 */ 71 */
64 int response_started; 72 int response_started;
73
74 /*
75 * reference counter
76 */
77 int ref;
65 } ProxyRequest; 78 } ProxyRequest;
79
80 static void proxy_unref(ProxyRequest *proxy) {
81 if(--proxy->ref == 0) {
82 http_client_free(proxy->client);
83 free(proxy);
84 }
85 }
66 86
67 static int proxy_response_start(HttpClient *client, int status, char *message, void *userdata) { 87 static int proxy_response_start(HttpClient *client, int status, char *message, void *userdata) {
68 ProxyRequest *proxy = userdata; 88 ProxyRequest *proxy = userdata;
69 89
70 HeaderArray *headers = client->response_headers; 90 HeaderArray *headers = client->response_headers;
108 if(!proxy->response_started) { 128 if(!proxy->response_started) {
109 protocol_status(proxy->sn, proxy->rq, 502, NULL); 129 protocol_status(proxy->sn, proxy->rq, 502, NULL);
110 ret = REQ_ABORTED; 130 ret = REQ_ABORTED;
111 } 131 }
112 132
113 http_client_free(client);
114
115 nsapi_function_return(proxy->sn, proxy->rq, ret); 133 nsapi_function_return(proxy->sn, proxy->rq, ret);
134
135 proxy_unref(proxy);
136 }
137
138 static int proxy_request_read_event(EventHandler *eh, Event *event) {
139 ProxyRequest *proxy = event->cookie;
140 if(http_client_process(proxy->client)) {
141 if(proxy->client->error == 0) {
142 return 1;
143 }
144 }
145 return 0;
146 }
147
148 static int proxy_request_read_finished(EventHandler *eh, Event *event) {
149 ProxyRequest *proxy = event->cookie;
150 proxy_unref(proxy);
151 return 0;
116 } 152 }
117 153
118 static ssize_t proxy_request_read(HttpClient *client, void *buf, size_t nbytes, void *userdata) { 154 static ssize_t proxy_request_read(HttpClient *client, void *buf, size_t nbytes, void *userdata) {
119 ProxyRequest *proxy = userdata; 155 ProxyRequest *proxy = userdata;
120 int ret = netbuf_getbytes(proxy->sn->inbuf, buf, nbytes); 156 int ret = netbuf_getbytes(proxy->sn->inbuf, buf, nbytes);
121 if(ret == NETBUF_EOF) { 157 if(ret == NETBUF_EOF) {
122 ret = 0; 158 ret = 0;
123 } 159 } else if(ret < 0) {
124 // TODO: handle errors 160 IOStream *st = proxy->sn->csd;
161 if(st->io_errno == EWOULDBLOCK) {
162 ret = HTTP_CLIENT_CALLBACK_WOULD_BLOCK;
163 // is there already an poll event for csd?
164 if(!proxy->event.cookie) {
165 proxy->ref++;
166 proxy->event.cookie = proxy;
167 proxy->event.fn = proxy_request_read_event;
168 proxy->event.finish = proxy_request_read_finished;
169 if(event_pollin(client->ev, st, &proxy->event)) {
170 ret = HTTP_CLIENT_CALLBACK_ERROR;
171 }
172 }
173 } else {
174 ret = HTTP_CLIENT_CALLBACK_ERROR;
175 }
176 }
177
125 return ret; 178 return ret;
126 } 179 }
127 180
128 static ssize_t proxy_response_write(HttpClient *client, void *buf, size_t nbytes, void *userdata) { 181 static ssize_t proxy_response_write(HttpClient *client, void *buf, size_t nbytes, void *userdata) {
129 ProxyRequest *proxy = userdata; 182 ProxyRequest *proxy = userdata;
226 279
227 // remove some response headers, that were previously set by ObjectType 280 // remove some response headers, that were previously set by ObjectType
228 // or other SAFs 281 // or other SAFs
229 pblock_removekey(pb_key_content_type, rq->srvhdrs); 282 pblock_removekey(pb_key_content_type, rq->srvhdrs);
230 283
231 ProxyRequest *proxy = pool_malloc(sn->pool, sizeof(ProxyRequest)); 284 ProxyRequest *proxy = malloc(sizeof(ProxyRequest));
232 proxy->sn = sn; 285 proxy->sn = sn;
233 proxy->rq = rq; 286 proxy->rq = rq;
234 proxy->request_header_rewrite = pblock_create_pool(sn->pool, 16); 287 proxy->request_header_rewrite = pblock_create_pool(sn->pool, 16);
235 proxy->response_header_rewrite = pblock_create_pool(sn->pool, 16); 288 proxy->response_header_rewrite = pblock_create_pool(sn->pool, 16);
236 proxy->response_started = 0; 289 proxy->response_started = 0;
290 proxy->ref = 1;
237 291
238 // Some request/response headers should be removed or altered 292 // Some request/response headers should be removed or altered
239 // An empty string means, the header should be removed 293 // An empty string means, the header should be removed
240 pblock_nvinsert("host", "", proxy->request_header_rewrite); 294 pblock_nvinsert("host", "", proxy->request_header_rewrite);
241 pblock_nvinsert("connection", "", proxy->request_header_rewrite); 295 pblock_nvinsert("connection", "", proxy->request_header_rewrite);
247 // setup HttpClient 301 // setup HttpClient
248 HttpClient *client = http_client_new(ev); 302 HttpClient *client = http_client_new(ev);
249 if(!client) { 303 if(!client) {
250 return REQ_ABORTED; 304 return REQ_ABORTED;
251 } 305 }
306 proxy->client = client;
252 307
253 if(http_client_set_method(client, method)) { 308 if(http_client_set_method(client, method)) {
254 http_client_free(client); 309 http_client_free(client);
255 return REQ_ABORTED; 310 return REQ_ABORTED;
256 } 311 }

mercurial