| 85 int ref; |
85 int ref; |
| 86 } ProxyRequest; |
86 } ProxyRequest; |
| 87 |
87 |
| 88 static void proxy_unref(ProxyRequest *proxy) { |
88 static void proxy_unref(ProxyRequest *proxy) { |
| 89 if(--proxy->ref == 0) { |
89 if(--proxy->ref == 0) { |
| 90 log_ereport(LOG_INFORM, "proxy cleanup"); |
90 log_ereport(LOG_DEBUG, "proxy cleanup"); |
| 91 //const char *method = pblock_findkeyval(pb_key_method, proxy->rq->reqpb); |
91 //const char *method = pblock_findkeyval(pb_key_method, proxy->rq->reqpb); |
| 92 //const char *uri = pblock_findkeyval(pb_key_uri, proxy->rq->reqpb); |
92 //const char *uri = pblock_findkeyval(pb_key_uri, proxy->rq->reqpb); |
| 93 //log_ereport(LOG_INFORM, "reverse-proxy: %s %s finished", method, uri); |
93 //log_ereport(LOG_INFORM, "reverse-proxy: %s %s finished", method, uri); |
| 94 http_client_free(proxy->client); |
94 http_client_free(proxy->client); |
| 95 free(proxy->read_buf); |
95 free(proxy->read_buf); |
| 140 } |
140 } |
| 141 |
141 |
| 142 static void proxy_response_finished(HttpClient *client, void *userdata) { |
142 static void proxy_response_finished(HttpClient *client, void *userdata) { |
| 143 ProxyRequest *proxy = userdata; |
143 ProxyRequest *proxy = userdata; |
| 144 |
144 |
| 145 log_ereport(LOG_INFORM, "proxy_response_finished: %s", client->uri); |
145 log_ereport(LOG_DEBUG, "proxy_response_finished: %s", client->uri); |
| 146 |
146 |
| 147 int ret = proxy->client->error == 0 ? REQ_PROCEED : REQ_ABORTED; |
147 int ret = proxy->client->error == 0 ? REQ_PROCEED : REQ_ABORTED; |
| 148 if(!proxy->response_started) { |
148 if(!proxy->response_started) { |
| 149 protocol_status(proxy->sn, proxy->rq, 502, NULL); |
149 protocol_status(proxy->sn, proxy->rq, 502, NULL); |
| 150 ret = REQ_ABORTED; |
150 ret = REQ_ABORTED; |
| 171 if(http_client_process(proxy->client, event)) { |
171 if(http_client_process(proxy->client, event)) { |
| 172 if(proxy->client->error == 0) { |
172 if(proxy->client->error == 0) { |
| 173 return 1; |
173 return 1; |
| 174 } |
174 } |
| 175 } |
175 } |
| 176 log_ereport(LOG_INFORM, "proxy_event end: %p", event->finish); |
|
| 177 return 0; |
176 return 0; |
| 178 } |
177 } |
| 179 |
178 |
| 180 static int proxy_event_finished(EventHandler *eh, Event *event) { |
179 static int proxy_event_finished(EventHandler *eh, Event *event) { |
| 181 ProxyRequest *proxy = event->cookie; |
180 ProxyRequest *proxy = event->cookie; |
| 211 } |
210 } |
| 212 |
211 |
| 213 static ssize_t proxy_response_write(HttpClient *client, void *buf, size_t nbytes, void *userdata) { |
212 static ssize_t proxy_response_write(HttpClient *client, void *buf, size_t nbytes, void *userdata) { |
| 214 ProxyRequest *proxy = userdata; |
213 ProxyRequest *proxy = userdata; |
| 215 ssize_t ret = net_write(proxy->sn->csd, buf, nbytes); |
214 ssize_t ret = net_write(proxy->sn->csd, buf, nbytes); |
| 216 if(ret == 0) { |
215 |
| 217 log_ereport(LOG_FAILURE, "proxy_response_write ret 0 wtf"); |
216 if(ret <= 0) { |
| 218 } |
|
| 219 |
|
| 220 if(ret < 0) { |
|
| 221 IOStream *st = proxy->sn->csd; |
217 IOStream *st = proxy->sn->csd; |
| 222 if(st->io_errno == EWOULDBLOCK) { |
218 if(st->io_errno == EWOULDBLOCK) { |
| 223 log_ereport(LOG_INFORM, "proxy_response_write would block"); |
|
| 224 // Is there already an poll event for csd? |
219 // Is there already an poll event for csd? |
| 225 if(client->last_event == &proxy->event) { |
220 if(client->last_event == &proxy->event) { |
| 226 // Yes, there is already an event, and it even is the event that triggert this call. |
221 // Yes, there is already an event, and it even is the event that triggert this call. |
| 227 // Make sure it is a write event |
222 // Make sure it is a write event |
| 228 proxy->event.events = EVENT_POLLOUT; |
223 proxy->event.events = EVENT_POLLOUT; |
| 229 log_ereport(LOG_INFORM, "proxy_response_write pollout event already exists"); |
|
| 230 return HTTP_CLIENT_CALLBACK_WOULD_BLOCK; |
224 return HTTP_CLIENT_CALLBACK_WOULD_BLOCK; |
| 231 } else if(proxy->event.fn != NULL) { |
225 } else if(proxy->event.fn != NULL) { |
| 232 // There is an inactive event, probably a read event |
226 // There is an inactive event, probably a read event |
| 233 // Remove the old event before we add a write event |
227 // Remove the old event before we add a write event |
| 234 if(ev_remove_poll(client->ev, proxy->event.object)) { |
228 if(ev_remove_poll(client->ev, proxy->event.object)) { |
| 240 proxy->event.cookie = proxy; |
234 proxy->event.cookie = proxy; |
| 241 proxy->event.fn = proxy_event; |
235 proxy->event.fn = proxy_event; |
| 242 proxy->event.finish = proxy_event_finished; |
236 proxy->event.finish = proxy_event_finished; |
| 243 } |
237 } |
| 244 // Add write event |
238 // Add write event |
| 245 log_ereport(LOG_INFORM, "proxy_response_write pollout"); |
|
| 246 if(event_pollout(client->ev, proxy->sn->csd, &proxy->event)) { |
239 if(event_pollout(client->ev, proxy->sn->csd, &proxy->event)) { |
| 247 proxy_unref(proxy); |
240 proxy_unref(proxy); |
| 248 log_ereport(LOG_FAILURE, "proxy_response_write: cannot add write poll"); |
241 log_ereport(LOG_FAILURE, "proxy_response_write: cannot add write poll"); |
| 249 } |
242 } |
| 250 return HTTP_CLIENT_CALLBACK_WOULD_BLOCK; |
243 return HTTP_CLIENT_CALLBACK_WOULD_BLOCK; |