src/server/proxy/httpclient.c

changeset 679
4885cd4c3754
parent 676
d43f1dd8b18e
child 680
02935baa186b
equal deleted inserted replaced
678:9908159eff0e 679:4885cd4c3754
250 event->fn = client_io; 250 event->fn = client_io;
251 251
252 return client_io(ev, event); 252 return client_io(ev, event);
253 } 253 }
254 254
255 static int client_send_request_body(HttpClient *client) {
256 size_t rbody_readsize = client->req_buffer_alloc;
257 size_t rbody_buf_offset = 0;
258 if(client->req_content_length == -1) {
259 // chunked transfer encoding:
260 // don't fill req_buffer completely, reserve some space for
261 // a chunk header, that will be inserted at the beginning
262 rbody_readsize -= 16;
263 rbody_buf_offset = 16;
264 }
265 while(!client->request_body_complete) {
266 ssize_t r = client->request_body_read(client, client->req_buffer + rbody_buf_offset, rbody_readsize, client->request_body_read_userdata);
267 if(r <= 0) {
268 if(r == HTTP_CLIENT_CALLBACK_WOULD_BLOCK) {
269 return 1;
270 } else if(r == 0) {
271 // EOF
272 client->request_body_complete = 1;
273 break;
274 } else {
275 // error
276 client->error = 1;
277 return 1;
278 }
279 }
280
281 size_t startpos = 0;
282 if(client->req_content_length == -1) {
283 char chunkheader[16];
284 int chunkheaderlen = snprintf(chunkheader, 16, "%zx\r\n", (size_t)r);
285 startpos = 16 - chunkheaderlen;
286 memcpy(client->req_buffer + startpos, chunkheader, chunkheaderlen);
287 }
288
289 client->req_contentlength_pos += r;
290 client->req_buffer_pos = startpos;
291 client->req_buffer_len = r;
292 if(client_send_request(client)) {
293 return 1;
294 }
295 }
296
297 if(client->req_content_length > 0 && client->req_content_length != client->req_contentlength_pos) {
298 // incomplete request body
299 client->error = 1;
300 return 1;
301 }
302
303 return 0;
304 }
305
255 static int client_io(EventHandler *ev, Event *event) { 306 static int client_io(EventHandler *ev, Event *event) {
256 HttpClient *client = event->cookie; 307 HttpClient *client = event->cookie;
257 if(client->req_buffer_pos < client->req_buffer_len) { 308 if(client->req_buffer_pos < client->req_buffer_len) {
258 if(client_send_request(client)) { 309 if(client_send_request(client)) {
259 return client->error == 0; 310 return client->error == 0;
260 } 311 }
261 } 312 }
262 313
263 // do we need to send a request body? 314 // do we need to send a request body?
264 if(client->req_content_length != 0) { 315 if(client->req_content_length != 0) {
265 while(!client->request_body_complete) { 316 if(client_send_request_body(client)) {
266 ssize_t r = client->request_body_read(client, client->req_buffer, client->req_buffer_alloc, client->request_body_read_userdata); 317 return client->error == 0;
267 if(r <= 0) { 318 }
268 if(r == HTTP_CLIENT_CALLBACK_WOULD_BLOCK) { 319 }
269 return 1;
270 } else if(r == 0) {
271 // EOF
272 client->request_body_complete = 1;
273 break;
274 } else {
275 // error
276 client->error = 1;
277 return 0;
278 }
279 }
280 client->req_contentlength_pos += r;
281 client->req_buffer_pos = 0;
282 client->req_buffer_len = r;
283 if(client_send_request(client)) {
284 return client->error == 0;
285 }
286 }
287
288 if(client->req_content_length > 0 && client->req_content_length != client->req_contentlength_pos) {
289 // incomplete request body
290 client->error = 1;
291 return 0;
292 }
293 }
294
295
296 320
297 // writing complete, switch to read events 321 // writing complete, switch to read events
298 event->events = EVENT_POLLIN; 322 event->events = EVENT_POLLIN;
299 323
300 324

mercurial