@@ -46919,61 +46919,85 @@ FIO_SFUNC void fio___http_controller_http1_write_body(
4691946919 return;
4692046920
4692146921stream_chunk:
46922- if (args.len) { /* print chunk header */
46923- if (c->state.http.buf.len) {
46924- fio_io_write2(c->io,
46925- .buf = (void *)c->state.http.buf.buf,
46926- .len = c->state.http.buf.len,
46927- .dealloc = FIO_STRING_FREE);
46928- fio_string_write2(&c->state.http.buf,
46929- FIO_STRING_REALLOC,
46930- FIO_STRING_WRITE_HEX(args.len),
46931- FIO_STRING_WRITE_STR2("\r\n", 2));
46922+ if (args.len && args.buf) { /* String */
46923+ if (args.copy || args.len < (1 << 16)) {
46924+ fio_string_write2(
46925+ &c->state.http.buf,
46926+ FIO_STRING_REALLOC,
46927+ FIO_STRING_WRITE_HEX(args.len), /* chunk header - length */
46928+ FIO_STRING_WRITE_STR2("\r\n", 2), /* chunk header - EOL */
46929+ FIO_STRING_WRITE_STR2((char *)args.buf, args.buf ? args.len : 0),
46930+ FIO_STRING_WRITE_STR2("\r\n", 2)); /* chunk trailer - EOL */
4693246931 fio_io_write2(c->io,
4693346932 .buf = (void *)c->state.http.buf.buf,
4693446933 .len = c->state.http.buf.len,
4693546934 .dealloc = FIO_STRING_FREE);
4693646935 c->state.http.buf = FIO_STR_INFO0;
46937- } else {
46938- char buf[24];
46939- fio_str_info_s i = FIO_STR_INFO3(buf, 0, 24);
46940- fio_string_write_hex(&i, NULL, args.len);
46941- fio_string_write(&i, NULL, "\r\n", 2);
46942- fio_io_write2(c->io, .buf = (void *)i.buf, .len = i.len, .copy = 1);
46943- }
46944- } else {
46945- if (c->state.http.buf.len) {
46946- fio_io_write2(c->io,
46947- .buf = (void *)c->state.http.buf.buf,
46948- .len = c->state.http.buf.len,
46949- .dealloc = FIO_STRING_FREE);
46936+ if (args.dealloc)
46937+ args.dealloc((void *)args.buf);
46938+ return;
46939+ } else { /* avoid copying the incoming data if possible */
46940+ FIO_STR_INFO_TMP_VAR(buf, 32);
46941+ if (c->state.http.buf.buf)
46942+ buf = c->state.http.buf;
4695046943 c->state.http.buf = FIO_STR_INFO0;
46944+ fio_string_write2(
46945+ &buf,
46946+ NULL,
46947+ FIO_STRING_WRITE_HEX(args.len), /* chunk header - length */
46948+ FIO_STRING_WRITE_STR2("\r\n", 2)); /* chunk header - EOL */
46949+ fio_io_write2(c->io,
46950+ .buf = buf.buf,
46951+ .len = buf.len,
46952+ .copy = !FIO_STR_INFO_TMP_IS_REALLOCATED(buf),
46953+ .dealloc = FIO_STR_INFO_TMP_IS_REALLOCATED(buf)
46954+ ? FIO_STRING_FREE
46955+ : NULL);
46956+ fio_io_write2(c->io,
46957+ .buf = (void *)args.buf,
46958+ .len = args.len,
46959+ .dealloc = args.dealloc);
46960+ /* chunk trailer - EOL */
46961+ fio_io_write2(c->io, .buf = (void *)"\r\n", .len = 2);
46962+ return;
4695146963 }
46952- if (args.buf || (uint32_t)(args.fd + 1) > 0U)
46953- FIO_LOG_ERROR("HTTP1 streaming requires a correctly pre-determined "
46954- "length per chunk.");
46955- else
46956- goto no_write_err;
46957- }
46958- fio_io_write2(c->io,
46959- .buf = (void *)args.buf,
46960- .fd = args.fd,
46961- .len = args.len,
46962- .offset = args.offset,
46963- .dealloc = args.dealloc,
46964- .copy = (uint8_t)args.copy);
46965- /* print chunk trailer */
46966- {
46967- fio_buf_info_s trailer = FIO_BUF_INFO2((char *)"\r\n", 2);
46968- fio_io_write2(c->io, .buf = trailer.buf, .len = trailer.len, .copy = 1);
46964+ } else if ((uint32_t)(args.fd + 1) > 1U) { /* File? */
46965+ if (!args.len) { /* TODO: collect remaining file length */
46966+ goto no_length_err;
46967+ }
46968+ FIO_STR_INFO_TMP_VAR(buf, 32);
46969+ if (c->state.http.buf.buf)
46970+ buf = c->state.http.buf;
46971+ c->state.http.buf = FIO_STR_INFO0;
46972+ fio_string_write2(
46973+ &buf,
46974+ NULL,
46975+ FIO_STRING_WRITE_HEX(args.len), /* chunk header - length */
46976+ FIO_STRING_WRITE_STR2("\r\n", 2)); /* chunk header - EOL */
46977+ fio_io_write2(c->io,
46978+ .buf = buf.buf,
46979+ .len = buf.len,
46980+ .copy = !FIO_STR_INFO_TMP_IS_REALLOCATED(buf),
46981+ .dealloc = FIO_STR_INFO_TMP_IS_REALLOCATED(buf)
46982+ ? FIO_STRING_FREE
46983+ : NULL);
46984+ fio_io_write2(c->io,
46985+ .fd = args.fd,
46986+ .len = args.len,
46987+ .copy = (bool)args.copy,
46988+ .dealloc = args.dealloc);
46989+ /* chunk trailer - EOL */
46990+ fio_io_write2(c->io, .buf = (void *)"\r\n", .len = 2);
4696946991 }
4697046992 return;
46971-
46993+ no_length_err:
46994+ FIO_LOG_ERROR("HTTP1 streaming requires a correctly pre-determined "
46995+ "length per chunk.");
4697246996no_write_err:
4697346997 if (args.buf) {
4697446998 if (args.dealloc)
4697546999 args.dealloc((void *)args.buf);
46976- } else if (args.fd != -1 ) {
47000+ } else if ((uint32_t)( args.fd + 1) > 1U ) {
4697747001 close(args.fd);
4697847002 }
4697947003}
0 commit comments