| 192 int http_client_enable_chunked_transfer_encoding(HttpClient *client) { |
192 int http_client_enable_chunked_transfer_encoding(HttpClient *client) { |
| 193 client->req_content_length = -1; |
193 client->req_content_length = -1; |
| 194 return http_client_add_request_header(client, cx_mutstr("transfer-encoding"), cx_mutstr("chunked")); |
194 return http_client_add_request_header(client, cx_mutstr("transfer-encoding"), cx_mutstr("chunked")); |
| 195 } |
195 } |
| 196 |
196 |
| 197 static int client_start_poll(HttpClient *client, int in) { |
197 static int client_start_poll(HttpClient *client) { |
| 198 client->event.fn = client_connected; |
198 client->event.fn = client_connected; |
| 199 client->event.finish = client_finished; |
199 client->event.finish = client_finished; |
| 200 if(in) { |
200 return ev_poll(client->ev, client->socketfd, &client->event); |
| 201 return ev_pollin(client->ev, client->socketfd, &client->event); |
|
| 202 } else { |
|
| 203 return ev_pollout(client->ev, client->socketfd, &client->event); |
|
| 204 } |
|
| 205 } |
201 } |
| 206 |
202 |
| 207 int http_client_start(HttpClient *client) { |
203 int http_client_start(HttpClient *client) { |
| |
204 client->event.events = EVENT_POLLOUT; |
| 208 client->event.cookie = client; |
205 client->event.cookie = client; |
| 209 if(client->socketfd != -1) { |
206 if(client->socketfd != -1) { |
| 210 int ret = client_connected(client->ev, &client->event); |
207 int ret = client_connected(client->ev, &client->event); |
| 211 if(ret != 0) { |
208 if(ret != 0) { |
| 212 return client_start_poll(client, 1); // TODO: check event type |
209 return client_start_poll(client); |
| 213 } |
210 } |
| 214 return 0; |
211 return 0; |
| 215 } |
212 } |
| 216 |
213 |
| 217 int socketfd = socket(client->domain, SOCK_STREAM, 0); |
214 int socketfd = socket(client->domain, SOCK_STREAM, 0); |
| 220 } |
217 } |
| 221 if(util_socket_setnonblock(socketfd, 1)) { |
218 if(util_socket_setnonblock(socketfd, 1)) { |
| 222 return 1; |
219 return 1; |
| 223 } |
220 } |
| 224 client->socketfd = socketfd; |
221 client->socketfd = socketfd; |
| 225 |
222 |
| 226 int ret = 1; |
223 int ret = 1; |
| 227 if(connect(socketfd, client->addr, client->addrlen)) { |
224 if(connect(socketfd, client->addr, client->addrlen)) { |
| 228 int err = errno; |
225 int err = errno; |
| 229 if(err == EINPROGRESS) { |
226 if(err == EINPROGRESS) { |
| 230 ret = client_start_poll(client, 1); |
227 ret = client_start_poll(client); |
| 231 } else { |
228 } else { |
| 232 log_ereport(LOG_FAILURE, "http-client-start: connect failed: %s", strerror(err)); |
229 log_ereport(LOG_FAILURE, "http-client-start: connect failed: %s", strerror(err)); |
| 233 } |
230 } |
| 234 } else { |
231 } else { |
| 235 ret = 0; // TODO |
232 ret = 0; // TODO |
| 324 |
321 |
| 325 // writing complete, switch to read events |
322 // writing complete, switch to read events |
| 326 event->events = EVENT_POLLIN; |
323 event->events = EVENT_POLLIN; |
| 327 client->stage = 1; |
324 client->stage = 1; |
| 328 |
325 |
| 329 if(client_read_response_header(client)) { |
326 if(client_read_response_header(client)) { |
| 330 return client->error == 0; |
327 return client->error == 0; |
| 331 } |
328 } |
| 332 int ret = 0; |
329 int ret = 0; |
| 333 if(client->stage == 2) { |
330 if(client->stage == 2) { |
| 334 // websocket: write message buffer |
331 // websocket: write message buffer |
| 470 return 0; |
467 return 0; |
| 471 } |
468 } |
| 472 |
469 |
| 473 unsigned char *buffer = client->buffer.inbuf + client->buffer.cursize; |
470 unsigned char *buffer = client->buffer.inbuf + client->buffer.cursize; |
| 474 size_t nbytes = client->buffer.maxsize - client->buffer.cursize; |
471 size_t nbytes = client->buffer.maxsize - client->buffer.cursize; |
| 475 |
472 |
| 476 ssize_t r; |
473 ssize_t r; |
| 477 while((r = read(client->socketfd, buffer, nbytes)) > 0) { |
474 while((r = read(client->socketfd, client->buffer.inbuf + client->buffer.cursize, client->buffer.maxsize - client->buffer.cursize)) > 0) { |
| 478 client->buffer.cursize += r; |
475 client->buffer.cursize += r; |
| 479 if(!client->response_header_complete) { |
476 if(!client->response_header_complete) { |
| 480 switch(http_parser_process(client->parser)) { |
477 switch(http_parser_process(client->parser)) { |
| 481 case 0: { // finish |
478 case 0: { // finish |
| 482 if(!http_parser_validate(client->parser)) { |
479 if(!http_parser_validate(client->parser)) { |