src/server/util/io.c

changeset 685
349d62bfae29
parent 684
48da20bde908
child 687
4bded456b4a7
equal deleted inserted replaced
684:48da20bde908 685:349d62bfae29
554 554
555 #define BUF_UNNEEDED_DIFF 64 555 #define BUF_UNNEEDED_DIFF 64
556 /* 556 /*
557 * read from st->readbuf first, read from st->fd if perform_io is true 557 * read from st->readbuf first, read from st->fd if perform_io is true
558 */ 558 */
559 static ssize_t http_read_buffered(HttpStream *st, char *buf, size_t nbytes, WSBool read_data, WSBool *perform_io) { 559 static ssize_t http_read_buffered(HttpStream *httpstr, char *buf, size_t nbytes, WSBool read_data, WSBool *perform_io) {
560 ssize_t r = 0; 560 ssize_t r = 0;
561 561
562 //memset(buf, 'x', nbytes); 562 //memset(buf, 'x', nbytes);
563 //char *orig_buf = buf; 563 //char *orig_buf = buf;
564 564
565 // copy available data from st->readbuf to buf 565 // copy available data from st->readbuf to buf
566 int pos = *st->bufpos; 566 int pos = *httpstr->bufpos;
567 size_t buf_available = *st->buflen - pos; 567 int buflen = *httpstr->buflen;
568 if(buf_available) { 568 int buf_available = buflen > 0 ? buflen - pos : 0;
569 if(buf_available > 0) {
569 size_t cplen = buf_available > nbytes ? nbytes : buf_available; 570 size_t cplen = buf_available > nbytes ? nbytes : buf_available;
570 if(read_data) { 571 if(read_data) {
571 // if we read data (and not a chunk header), we limit the 572 // if we read data (and not a chunk header), we limit the
572 // amount of bytes we copy 573 // amount of bytes we copy
573 size_t chunk_available = st->max_read - st->read; 574 size_t chunk_available = httpstr->max_read - httpstr->read;
574 cplen = cplen > chunk_available ? chunk_available : cplen; 575 cplen = cplen > chunk_available ? chunk_available : cplen;
575 st->read += cplen; 576 httpstr->read += cplen;
576 } 577 }
577 memcpy(buf, st->readbuf + pos, cplen); 578 memcpy(buf, httpstr->readbuf + pos, cplen);
578 *st->bufpos += cplen; 579 *httpstr->bufpos += cplen;
579 r += cplen; 580 r += cplen;
580 buf += cplen; 581 buf += cplen;
581 nbytes -= cplen; 582 nbytes -= cplen;
582 } 583 }
583 584
586 // when a chunk is completed 587 // when a chunk is completed
587 // 588 //
588 // if we read a chunk header (read_data == false) it is very important 589 // if we read a chunk header (read_data == false) it is very important
589 // to not perform IO, if we have previously copied data from readbuf 590 // to not perform IO, if we have previously copied data from readbuf
590 // this ensures we never override non-chunk-header data 591 // this ensures we never override non-chunk-header data
591 if(*perform_io && ((read_data && nbytes > 0 && st->max_read - st->read) || (!read_data && r == 0))) { 592 if(*perform_io && ((read_data && nbytes > 0 && httpstr->max_read - httpstr->read) || (!read_data && r == 0))) {
592 if(*st->buflen - *st->bufpos > 0) { 593 if(*httpstr->buflen - *httpstr->bufpos > 0) {
593 printf("todo: fix, should not happen, remove later\n"); 594 printf("todo: fix, should not happen, remove later\n");
594 } 595 }
595 // fill buffer again 596 // fill buffer again
596 ssize_t rlen = st->fd->read(st->fd, st->readbuf, st->bufsize); 597 ssize_t rlen = httpstr->fd->read(httpstr->fd, httpstr->readbuf, httpstr->bufsize);
597 *st->buflen = rlen; 598 *httpstr->buflen = rlen;
598 *st->bufpos = 0; 599 *httpstr->bufpos = 0;
599 *perform_io = WS_FALSE; 600 *perform_io = WS_FALSE;
600 if(rlen < 0) { 601 if(rlen < 0) {
601 st->st.io_errno = st->fd->io_errno; 602 httpstr->st.io_errno = httpstr->fd->io_errno;
602 } 603 }
603 604
604 if(rlen > 0) { 605 if(rlen > 0) {
605 // call func again to get data from buffer (no IO will be performed) 606 // call func again to get data from buffer (no IO will be performed)
606 r += http_read_buffered(st, buf, nbytes, read_data, perform_io); 607 r += http_read_buffered(httpstr, buf, nbytes, read_data, perform_io);
608 } else if(r == 0) {
609 r = rlen;
607 } 610 }
608 } 611 }
609 612
610 return r; 613 return r;
611 } 614 }

mercurial