int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) { chunkqueue *cq; if (!con) return -1; cq = con->write_queue; if (len == 0) { if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { chunkqueue_append_mem(cq, "0\r\n\r\n", 5 + 1); } else { chunkqueue_append_mem(cq, "", 1); } return 0; } if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { http_chunk_append_len(srv, con, len - 1); } chunkqueue_append_mem(cq, mem, len); if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { chunkqueue_append_mem(cq, "\r\n", 2 + 1); } return 0; }
int http_chunk_append_file(server * srv, connection * con, buffer * fn, off_t offset, off_t len) { chunkqueue *cq; if (!con) return -1; cq = con->write_queue; if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { http_chunk_append_len(srv, con, len); } chunkqueue_append_file(cq, fn, offset, len); if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) { chunkqueue_append_mem(cq, "\r\n", 2 + 1); } return 0; }
static void http_chunk_append_file_fd_range(server *srv, connection *con, buffer *fn, int fd, off_t offset, off_t len) { chunkqueue *cq = con->write_queue; if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { http_chunk_append_len(srv, con, (uintmax_t)len); } chunkqueue_append_file_fd(cq, fn, fd, offset, len); if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { chunkqueue_append_mem(cq, CONST_STR_LEN("\r\n")); } }
liHandlerResult li_filter_chunked_encode(liVRequest *vr, liChunkQueue *out, liChunkQueue *in) { UNUSED(vr); if (in->length > 0) { http_chunk_append_len(out, in->length); li_chunkqueue_steal_all(out, in); li_chunkqueue_append_mem(out, CONST_STR_LEN("\r\n")); } if (in->is_closed) { if (!out->is_closed) { li_chunkqueue_append_mem(out, CONST_STR_LEN("0\r\n\r\n")); out->is_closed = TRUE; } return LI_HANDLER_GO_ON; } return LI_HANDLER_GO_ON; }
int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) { chunkqueue *cq; if (!con) return -1; cq = con->write_queue; if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { http_chunk_append_len(srv, con, mem->used - 1); } chunkqueue_append_buffer(cq, mem); if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) { chunkqueue_append_mem(cq, "\r\n", 2 + 1); } return 0; }
int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) { chunkqueue *cq; if (!con) return -1; Cdbg(DBE, "enter http_chunk_append_file..with fd=[%d], fn=[%s], offset=[%d], len=[%d]", con->fd, fn->ptr, offset, len); cq = con->write_queue; if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { http_chunk_append_len(srv, con, len); } chunkqueue_append_file(cq, fn, offset, len); if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) { chunkqueue_append_mem(cq, "\r\n", 2 + 1); } Cdbg(DBE, "leave"); return 0; }
static int http_chunk_append_data(server *srv, connection *con, buffer *b, const char * mem, size_t len) { chunkqueue * const cq = con->write_queue; chunk *c = cq->last; if (0 == len) return 0; /* current usage does not append_mem or append_buffer after appending * file, so not checking if users of this interface have appended large * (references to) files to chunkqueue, which would not be in memory */ /*(allow slightly larger mem use if FDEVENT_STREAM_RESPONSE_BUFMIN * to reduce creation of temp files when backend producer will be * blocked until more data is sent to network to client)*/ if ((c && c->type == FILE_CHUNK && c->file.is_temp) || cq->bytes_in - cq->bytes_out + len > 1024 * ((con->conf.stream_response_body & FDEVENT_STREAM_RESPONSE_BUFMIN) ? 128 : 64)) { return http_chunk_append_to_tempfile(srv, con, b ? b->ptr : mem, len); } /* not appending to prior mem chunk just in case using openssl * and need to resubmit same args as prior call to openssl (required?)*/ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { http_chunk_append_len(srv, con, len); } /*(chunkqueue_append_buffer() might steal buffer contents)*/ b ? chunkqueue_append_buffer(cq, b) : chunkqueue_append_mem(cq, mem, len); if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { chunkqueue_append_mem(cq, CONST_STR_LEN("\r\n")); } return 0; }