276 } |
276 } |
277 } |
277 } |
278 } |
278 } |
279 |
279 |
280 int http_start_response(Session *sn, Request *rq) { |
280 int http_start_response(Session *sn, Request *rq) { |
281 int fd = ((SystemIOStream*)sn->csd)->fd; |
281 int fd = ((NetIOStream*)sn->csd)->fd; |
282 |
282 |
283 if(rq->status_num == -1) { |
283 if(rq->status_num == -1) { |
284 protocol_status(sn, rq, 200, "OK"); |
284 protocol_status(sn, rq, 200, "OK"); |
285 } |
285 } |
286 |
286 |
287 /* set socket blocking */ |
287 // set socket blocking |
288 int flags; |
288 int flags; |
289 flags = fcntl(fd, F_GETFL, 0); |
289 flags = fcntl(fd, F_GETFL, 0); |
290 fcntl(fd, F_SETFL, flags ^ O_NONBLOCK); |
290 fcntl(fd, F_SETFL, flags ^ O_NONBLOCK); |
291 |
291 |
292 /* output buffer */ |
292 // output buffer |
293 sbuf_t *out = sbuf_new(512); |
293 sbuf_t *out = sbuf_new(512); |
294 |
294 |
295 /* add the http status line to the output buffer */ |
295 // add the http status line to the output buffer |
296 add_http_status_line(out, sn->pool, rq); |
296 add_http_status_line(out, sn->pool, rq); |
297 |
297 |
298 /* add server header */ |
298 // add server header |
299 sbuf_write(out, "Server: webserver\r\n", 19); |
299 sbuf_write(out, "Server: webserver\r\n", 19); |
300 |
300 |
301 /* add header from rq->srvhdrs */ |
301 // check content length ans transfer encoding |
|
302 char *ctlen = pblock_findkeyval(pb_key_content_length, rq->srvhdrs); |
|
303 char *enc = pblock_findkeyval(pb_key_transfer_encoding, rq->srvhdrs); |
|
304 if(ctlen && enc) { |
|
305 pblock_removekey(pb_key_transfer_encoding, rq->srvhdrs); |
|
306 } |
|
307 if(!ctlen) { |
|
308 // set transfer-encoding header |
|
309 if(!enc) { |
|
310 pblock_kvinsert( |
|
311 pb_key_transfer_encoding, |
|
312 "chunked", |
|
313 7, |
|
314 rq->srvhdrs); |
|
315 } else if(strcmp(enc, "chunked")) { |
|
316 pblock_removekey(pb_key_transfer_encoding, rq->srvhdrs); |
|
317 pblock_kvinsert( |
|
318 pb_key_transfer_encoding, |
|
319 "chunked", |
|
320 7, |
|
321 rq->srvhdrs); |
|
322 } |
|
323 |
|
324 // set stream property |
|
325 NetIOStream *stream = (NetIOStream*)sn->csd; |
|
326 stream->chunkedenc = 1; |
|
327 } |
|
328 |
|
329 // add header from rq->srvhdrs |
302 add_http_response_header(out, rq); |
330 add_http_response_header(out, rq); |
303 |
331 |
304 /* add connection header */ |
332 // add connection header |
305 sbuf_write(out, "Connection: close\r\n", 19); |
333 sbuf_write(out, "Connection: close\r\n", 19); |
306 |
334 |
307 /* response header end */ |
335 // response header end |
308 sbuf_write(out, "\r\n", 2); |
336 sbuf_write(out, "\r\n", 2); |
309 |
337 |
310 /* flush buffer to the socket */ |
338 // flush buffer to the socket |
311 write(fd, out->ptr, out->length); |
339 write(fd, out->ptr, out->length); |
312 sbuf_free(out); |
340 sbuf_free(out); |
313 |
341 |
314 rq->senthdrs = 1; |
342 rq->senthdrs = 1; |
315 |
343 |