src/server/safs/proxy.c

changeset 707
5fb102d2c745
parent 706
df64b4b79912
equal deleted inserted replaced
706:df64b4b79912 707:5fb102d2c745
128 if(!proxy->response_started) { 128 if(!proxy->response_started) {
129 protocol_status(proxy->sn, proxy->rq, 502, NULL); 129 protocol_status(proxy->sn, proxy->rq, 502, NULL);
130 ret = REQ_ABORTED; 130 ret = REQ_ABORTED;
131 } 131 }
132 132
133 if(client->last_event != &proxy->event && proxy->event.fn != NULL) {
134 if(!ev_remove_poll(client->ev, proxy->event.object)) {
135 proxy_unref(proxy);
136 } else {
137 log_ereport(LOG_FAILURE, "proxy_response_finished: cannot remove poll");
138 }
139 proxy->event.finish = NULL;
140 }
141
142 // return to nsapi threadpool
143 net_setnonblock(proxy->sn->csd, 0);
133 nsapi_function_return(proxy->sn, proxy->rq, ret); 144 nsapi_function_return(proxy->sn, proxy->rq, ret);
134 145
135 proxy_unref(proxy); 146 proxy_unref(proxy);
136 } 147 }
137 148
138 static int proxy_request_read_event(EventHandler *eh, Event *event) { 149 static int proxy_request_read_event(EventHandler *eh, Event *event) {
139 ProxyRequest *proxy = event->cookie; 150 ProxyRequest *proxy = event->cookie;
140 if(http_client_process(proxy->client)) { 151 if(http_client_process(proxy->client, event)) {
141 if(proxy->client->error == 0) { 152 if(proxy->client->error == 0) {
142 return 1; 153 return 1;
143 } 154 }
144 } 155 }
145 return 0; 156 return 0;
159 } else if(ret < 0) { 170 } else if(ret < 0) {
160 IOStream *st = proxy->sn->csd; 171 IOStream *st = proxy->sn->csd;
161 if(st->io_errno == EWOULDBLOCK) { 172 if(st->io_errno == EWOULDBLOCK) {
162 ret = HTTP_CLIENT_CALLBACK_WOULD_BLOCK; 173 ret = HTTP_CLIENT_CALLBACK_WOULD_BLOCK;
163 // is there already an poll event for csd? 174 // is there already an poll event for csd?
164 if(!proxy->event.cookie) { 175 if(!proxy->event.fn) {
165 proxy->ref++; 176 proxy->ref++;
166 proxy->event.cookie = proxy; 177 proxy->event.cookie = proxy;
167 proxy->event.fn = proxy_request_read_event; 178 proxy->event.fn = proxy_request_read_event;
168 proxy->event.finish = proxy_request_read_finished; 179 proxy->event.finish = proxy_request_read_finished;
169 if(event_pollin(client->ev, st, &proxy->event)) { 180 if(event_pollin(client->ev, st, &proxy->event)) {
179 } 190 }
180 191
181 static ssize_t proxy_response_write(HttpClient *client, void *buf, size_t nbytes, void *userdata) { 192 static ssize_t proxy_response_write(HttpClient *client, void *buf, size_t nbytes, void *userdata) {
182 ProxyRequest *proxy = userdata; 193 ProxyRequest *proxy = userdata;
183 ssize_t ret = net_write(proxy->sn->csd, buf, nbytes); 194 ssize_t ret = net_write(proxy->sn->csd, buf, nbytes);
184 // TODO: handle errors 195 if(ret == NETBUF_EOF) {
196 ret = HTTP_CLIENT_CALLBACK_ERROR;
197 } else if(ret < 0) {
198 IOStream *st = proxy->sn->csd;
199 if(st->io_errno == EWOULDBLOCK) {
200 // Is there already an poll event for csd?
201 if(client->last_event == &proxy->event) {
202 // Yes, there is already an event, and it even is the event that triggert this call.
203 // Make sure it is a write event
204 proxy->event.events = EVENT_POLLOUT;
205 return HTTP_CLIENT_CALLBACK_WOULD_BLOCK;
206 } else if(proxy->event.fn != NULL) {
207 // There is an inactive event, probably a read event
208 // Remove the old event before we add a write event
209 if(ev_remove_poll(client->ev, proxy->event.object)) {
210 log_ereport(LOG_FAILURE, "proxy_response_write: cannot remove poll");
211 return HTTP_CLIENT_CALLBACK_ERROR;
212 }
213 } else {
214 proxy->ref++;
215 proxy->event.cookie = proxy;
216 proxy->event.fn = proxy_request_read_event;
217 proxy->event.finish = proxy_request_read_finished;
218 }
219 // Add write event
220 if(event_pollout(client->ev, proxy->sn->csd, &proxy->event)) {
221 proxy_unref(proxy);
222 log_ereport(LOG_FAILURE, "proxy_response_write: cannot add write poll");
223 }
224 return HTTP_CLIENT_CALLBACK_ERROR;
225 }
226 }
185 return ret; 227 return ret;
186 }
187
188 static void proxy_request_finished(HttpClient *client, void *userdata) {
189 ProxyRequest *proxy = userdata;
190 net_setnonblock(proxy->sn->csd, 0);
191 nsapi_saf_return(proxy->sn, proxy->rq, REQ_PROCEED);
192 } 228 }
193 229
194 int http_reverse_proxy_service(pblock *param, Session *sn, Request *rq) { 230 int http_reverse_proxy_service(pblock *param, Session *sn, Request *rq) {
195 EventHandler *ev = sn->ev; 231 EventHandler *ev = sn->ev;
196 const char *method = pblock_findkeyval(pb_key_method, rq->reqpb); 232 const char *method = pblock_findkeyval(pb_key_method, rq->reqpb);
394 client->request_body_read_userdata = proxy; 430 client->request_body_read_userdata = proxy;
395 client->response_start = proxy_response_start; 431 client->response_start = proxy_response_start;
396 client->response_start_userdata = proxy; 432 client->response_start_userdata = proxy;
397 client->response_body_write = proxy_response_write; 433 client->response_body_write = proxy_response_write;
398 client->response_body_write_userdata = proxy; 434 client->response_body_write_userdata = proxy;
399 client->response_finished = proxy_request_finished; 435 client->response_finished = proxy_response_finished;
400 client->response_finished_userdata = proxy; 436 client->response_finished_userdata = proxy;
401 437
402 net_setnonblock(sn->csd, 1); 438 net_setnonblock(sn->csd, 1);
403 if(http_client_start(client)) { 439 if(http_client_start(client)) {
404 net_setnonblock(sn->csd, 0); 440 net_setnonblock(sn->csd, 0);

mercurial