| 304 http->chunk_buf_pos = 0; |
304 http->chunk_buf_pos = 0; |
| 305 http->read_eof = WS_FALSE; |
305 http->read_eof = WS_FALSE; |
| 306 return 0; |
306 return 0; |
| 307 } |
307 } |
| 308 |
308 |
| |
309 int httpstream_enable_buffered_read(IOStream *st, char *buffer, size_t bufsize, int *cursize, int *pos) { |
| |
310 if(st->read != (io_read_f)net_http_read) { |
| |
311 log_ereport(LOG_FAILURE, "%s", "httpstream_enable_chunked_read: IOStream is not an HttpStream"); |
| |
312 return 1; |
| |
313 } |
| |
314 st->read = (io_read_f)net_http_read_buffered; |
| |
315 HttpStream *http = (HttpStream*)st; |
| |
316 http->readbuf = buffer; |
| |
317 http->bufsize = bufsize; |
| |
318 http->buflen = cursize; |
| |
319 http->bufpos = pos; |
| |
320 return 0; |
| |
321 } |
| |
322 |
| 309 int httpstream_enable_chunked_write(IOStream *st) { |
323 int httpstream_enable_chunked_write(IOStream *st) { |
| 310 if(st->type != IO_STREAM_TYPE_HTTP) { |
324 if(st->type != IO_STREAM_TYPE_HTTP) { |
| 311 log_ereport(LOG_FAILURE, "%s", "httpstream_enable_chunked_write: IOStream is not an HttpStream"); |
325 log_ereport(LOG_FAILURE, "%s", "httpstream_enable_chunked_write: IOStream is not an HttpStream"); |
| 312 return 1; |
326 return 1; |
| 313 } |
327 } |
| 523 return r; |
537 return r; |
| 524 } |
538 } |
| 525 |
539 |
| 526 #define BUF_UNNEEDED_DIFF 64 |
540 #define BUF_UNNEEDED_DIFF 64 |
| 527 /* |
541 /* |
| 528 * read from st->chunk_buf first, read from st->fd if perform_io is true |
542 * read from st->readbuf first, read from st->fd if perform_io is true |
| 529 */ |
543 */ |
| 530 static ssize_t net_http_read_buffered(HttpStream *st, char *buf, size_t nbytes, WSBool read_data, WSBool *perform_io) { |
544 static ssize_t http_read_buffered(HttpStream *st, char *buf, size_t nbytes, WSBool read_data, WSBool *perform_io) { |
| 531 ssize_t r = 0; |
545 ssize_t r = 0; |
| 532 |
546 |
| 533 //memset(buf, 'x', nbytes); |
547 //memset(buf, 'x', nbytes); |
| 534 //char *orig_buf = buf; |
548 //char *orig_buf = buf; |
| 535 |
549 |
| 572 st->st.io_errno = st->fd->io_errno; |
586 st->st.io_errno = st->fd->io_errno; |
| 573 } |
587 } |
| 574 |
588 |
| 575 if(rlen > 0) { |
589 if(rlen > 0) { |
| 576 // call func again to get data from buffer (no IO will be performed) |
590 // call func again to get data from buffer (no IO will be performed) |
| 577 r += net_http_read_buffered(st, buf, nbytes, read_data, perform_io); |
591 r += http_read_buffered(st, buf, nbytes, read_data, perform_io); |
| 578 } |
592 } |
| 579 } |
593 } |
| 580 |
594 |
| 581 return r; |
595 return r; |
| |
596 } |
| |
597 |
| |
598 ssize_t net_http_read_buffered(HttpStream *st, void *buf, size_t nbytes) { |
| |
599 WSBool perform_io = TRUE; |
| |
600 return http_read_buffered(st, buf, nbytes, TRUE, &perform_io); |
| 582 } |
601 } |
| 583 |
602 |
| 584 |
603 |
| 585 /* |
604 /* |
| 586 * parses a chunk header |
605 * parses a chunk header |
| 685 WSBool perform_io = WS_TRUE; // we do only 1 read before we abort |
704 WSBool perform_io = WS_TRUE; // we do only 1 read before we abort |
| 686 while(rd < nbytes && (perform_io || (st->max_read - st->read) > 0)) { |
705 while(rd < nbytes && (perform_io || (st->max_read - st->read) > 0)) { |
| 687 // how many bytes are available in the current chunk |
706 // how many bytes are available in the current chunk |
| 688 size_t chunk_available = st->max_read - st->read; |
707 size_t chunk_available = st->max_read - st->read; |
| 689 if(chunk_available > 0) { |
708 if(chunk_available > 0) { |
| 690 ssize_t r = net_http_read_buffered(st, rbuf, rbuflen, TRUE, &perform_io); |
709 ssize_t r = http_read_buffered(st, rbuf, rbuflen, TRUE, &perform_io); |
| 691 if(r == 0) { |
710 if(r == 0) { |
| 692 break; |
711 break; |
| 693 } |
712 } |
| 694 rd += r; |
713 rd += r; |
| 695 st->read_total += r; |
714 st->read_total += r; |
| 703 // this indicates that something has gone wrong (or this is an attack) |
722 // this indicates that something has gone wrong (or this is an attack) |
| 704 st->read_eof = WS_TRUE; |
723 st->read_eof = WS_TRUE; |
| 705 return -1; |
724 return -1; |
| 706 } |
725 } |
| 707 // fill st->chunk_buf |
726 // fill st->chunk_buf |
| 708 ssize_t r = net_http_read_buffered(st, &st->chunk_buf[st->chunk_buf_pos], chunkbuf_avail, FALSE, &perform_io); |
727 ssize_t r = http_read_buffered(st, &st->chunk_buf[st->chunk_buf_pos], chunkbuf_avail, FALSE, &perform_io); |
| 709 if(r == 0) { |
728 if(r == 0) { |
| 710 break; |
729 break; |
| 711 } |
730 } |
| 712 int chunkbuf_len = st->chunk_buf_pos + r; |
731 int chunkbuf_len = st->chunk_buf_pos + r; |
| 713 int64_t chunklen; |
732 int64_t chunklen; |