[core] code reuse with http_response_body_clear()

code reuse with http_response_body_clear()
rename con->response.transfer_encoding to con->response.send_chunked
personal/stbuehler/fix-fdevent
Glenn Strauss 2018-09-15 22:48:29 -04:00
parent 3dd3cde902
commit 9725299587
8 changed files with 40 additions and 52 deletions

View File

@ -54,10 +54,7 @@ typedef struct {
unsigned int htags; /* bitfield of flagged headers present in response */
array *headers;
enum {
HTTP_TRANSFER_ENCODING_IDENTITY, HTTP_TRANSFER_ENCODING_CHUNKED
} transfer_encoding;
int send_chunked;
} response;
typedef struct {

View File

@ -6,6 +6,7 @@
#include "fdevent.h"
#include "http_header.h"
#include "log.h"
#include "response.h"
#include <errno.h>
#include <string.h>
@ -111,9 +112,9 @@ handler_t connection_handle_read_post_error(server *srv, connection *con, int ht
/*(do not change status if response headers already set and possibly sent)*/
if (0 != con->bytes_header) return HANDLER_ERROR;
http_response_body_clear(con, 0);
con->http_status = http_status;
con->mode = DIRECT;
chunkqueue_reset(con->write_queue);
return HANDLER_FINISHED;
}
@ -491,10 +492,7 @@ void connection_response_reset(server *srv, connection *con) {
con->is_writable = 1;
con->file_finished = 0;
con->file_started = 0;
con->response.htags = 0;
con->response.keep_alive = 0;
con->response.content_length = -1;
con->response.transfer_encoding = 0;
if (con->physical.path) { /*(skip for mod_fastcgi authorizer)*/
buffer_reset(con->physical.doc_root);
buffer_reset(con->physical.path);
@ -502,6 +500,7 @@ void connection_response_reset(server *srv, connection *con) {
buffer_reset(con->physical.rel_path);
buffer_reset(con->physical.etag);
}
con->response.htags = 0;
array_reset(con->response.headers);
chunkqueue_reset(con->write_queue);
http_response_body_clear(con, 0);
}

View File

@ -243,10 +243,10 @@ static void connection_handle_errdoc_init(connection *con) {
if (NULL != vb) www_auth = buffer_init_buffer(vb);
}
con->response.transfer_encoding = 0;
buffer_reset(con->physical.path);
con->response.htags = 0;
array_reset(con->response.headers);
chunkqueue_reset(con->write_queue);
http_response_body_clear(con, 0);
if (NULL != www_auth) {
http_header_response_set(con, HTTP_HEADER_OTHER, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(www_auth));
@ -270,17 +270,11 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
* */
if ((!con->http_status || con->http_status == 200) && !buffer_string_is_empty(con->uri.path) &&
con->uri.path->ptr[0] != '*') {
http_response_body_clear(con, 0);
http_header_response_append(con, HTTP_HEADER_OTHER, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
if (con->response.htags & HTTP_HEADER_CONTENT_LENGTH) {
http_header_response_set(con, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length"), CONST_STR_LEN(""));
}
con->http_status = 200;
con->file_finished = 1;
chunkqueue_reset(con->write_queue);
}
break;
default:
@ -300,12 +294,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
case 205:
case 304:
/* disable chunked encoding again as we have no body */
con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
if (con->response.htags & HTTP_HEADER_CONTENT_LENGTH) {
http_header_response_set(con, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length"), CONST_STR_LEN(""));
}
chunkqueue_reset(con->write_queue);
http_response_body_clear(con, 1);
con->file_finished = 1;
break;
default: /* class: header + body */
@ -431,7 +420,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
/*(no transfer-encoding if successful CONNECT)*/
} else if (con->request.http_version == HTTP_VERSION_1_1) {
off_t qlen = chunkqueue_length(con->write_queue);
con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
con->response.send_chunked = 1;
if (qlen) {
/* create initial Transfer-Encoding: chunked segment */
buffer *b = srv->tmp_chunk_len;
@ -469,13 +458,8 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
* a HEAD request has the same as a GET
* without the content
*/
http_response_body_clear(con, 1);
con->file_finished = 1;
chunkqueue_reset(con->write_queue);
con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
if (con->response.htags & HTTP_HEADER_TRANSFER_ENCODING) {
http_header_response_set(con, HTTP_HEADER_TRANSFER_ENCODING, CONST_STR_LEN("Transfer-Encoding"), CONST_STR_LEN(""));
}
}
http_response_write_header(srv, con);
@ -1240,10 +1224,7 @@ int connection_state_machine(server *srv, connection *con) {
con->is_writable = 1;
con->file_finished = 0;
con->file_started = 0;
con->response.htags = 0;
con->response.keep_alive = 0;
con->response.content_length = -1;
con->response.transfer_encoding = 0;
con->error_handler_saved_status = con->http_status;
con->error_handler_saved_method = con->request.http_method;

View File

@ -186,6 +186,21 @@ int http_response_handle_cachable(server *srv, connection *con, buffer *mtime) {
}
void http_response_body_clear (connection *con, int preserve_length) {
con->response.send_chunked = 0;
if (con->response.htags & HTTP_HEADER_TRANSFER_ENCODING) {
http_header_response_set(con, HTTP_HEADER_TRANSFER_ENCODING, CONST_STR_LEN("Transfer-Encoding"), CONST_STR_LEN(""));
}
if (!preserve_length) { /* preserve for HEAD responses and no-content responses (204, 205, 304) */
con->response.content_length = -1;
if (con->response.htags & HTTP_HEADER_CONTENT_LENGTH) {
http_header_response_set(con, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length"), CONST_STR_LEN(""));
}
}
chunkqueue_reset(con->write_queue);
}
static int http_response_parse_range(server *srv, connection *con, buffer *path, stat_cache_entry *sce, const char *range) {
int multipart = 0;
int error;

View File

@ -49,13 +49,13 @@ static int http_chunk_append_file_open_fstat(server *srv, connection *con, buffe
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) {
if (con->response.send_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) {
if (con->response.send_chunked) {
chunkqueue_append_mem(cq, CONST_STR_LEN("\r\n"));
}
}
@ -96,7 +96,7 @@ int http_chunk_append_file(server *srv, connection *con, buffer *fn) {
static int http_chunk_append_to_tempfile(server *srv, connection *con, const char * mem, size_t len) {
chunkqueue * const cq = con->write_queue;
if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
if (con->response.send_chunked) {
/*http_chunk_append_len(srv, con, len);*/
buffer *b = srv->tmp_chunk_len;
@ -113,7 +113,7 @@ static int http_chunk_append_to_tempfile(server *srv, connection *con, const cha
return -1;
}
if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
if (con->response.send_chunked) {
if (0 != chunkqueue_append_mem_to_tempfile(srv, cq, CONST_STR_LEN("\r\n"))) {
return -1;
}
@ -145,14 +145,14 @@ static int http_chunk_append_data(server *srv, connection *con, buffer *b, const
/* 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) {
if (con->response.send_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) {
if (con->response.send_chunked) {
chunkqueue_append_mem(cq, CONST_STR_LEN("\r\n"));
}
@ -176,7 +176,7 @@ void http_chunk_close(server *srv, connection *con) {
UNUSED(srv);
force_assert(NULL != con);
if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
if (con->response.send_chunked) {
chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("0\r\n\r\n"));
}
}

View File

@ -116,6 +116,7 @@
#include "etag.h"
#include "http_chunk.h"
#include "http_header.h"
#include "response.h"
#include "plugin.h"
@ -1157,13 +1158,10 @@ CONNECTION_FUNC(mod_deflate_handle_response_start) {
* In the future, might extract the error doc code so that it
* might be run again if response_start hooks return with
* changed http_status and con->mode = DIRECT */
con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
if (con->response.htags & HTTP_HEADER_CONTENT_LENGTH) {
http_header_response_set(con, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length"), CONST_STR_LEN(""));
}
chunkqueue_reset(con->write_queue);
con->file_finished = 1;
/* clear content length even if 304 since compressed length unknown */
http_response_body_clear(con, 0);
con->file_finished = 1;
con->mode = DIRECT;
return HANDLER_GO_ON;
}
@ -1190,10 +1188,7 @@ CONNECTION_FUNC(mod_deflate_handle_response_start) {
* request if ETag not modified and Content-Encoding not added) */
if (HTTP_METHOD_HEAD == con->request.http_method) {
/* ensure that uncompressed Content-Length is not sent in HEAD response */
chunkqueue_reset(con->write_queue);
if (con->response.htags & HTTP_HEADER_CONTENT_LENGTH) {
http_header_response_set(con, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length"), CONST_STR_LEN(""));
}
http_response_body_clear(con, 0);
return HANDLER_GO_ON;
}

View File

@ -266,7 +266,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
(con->http_status != 0 && con->http_status != 200)) {
/* remove a packets in the queue */
if (con->file_finished == 0) {
chunkqueue_reset(con->write_queue);
http_response_body_clear(con, 0);
}
return HANDLER_FINISHED;

View File

@ -46,6 +46,7 @@ handler_t http_response_read(server *srv, connection *con, http_response_opts *o
handler_t http_response_prepare(server *srv, connection *con);
int http_response_redirect_to_directory(server *srv, connection *con);
int http_response_handle_cachable(server *srv, connection *con, buffer * mtime);
void http_response_body_clear(connection *con, int preserve_length);
void http_response_send_file (server *srv, connection *con, buffer *path);
void http_response_backend_done (server *srv, connection *con);
void http_response_backend_error (server *srv, connection *con);