[core] code reuse with http_response_body_clear()
code reuse with http_response_body_clear() rename con->response.transfer_encoding to con->response.send_chunkedpersonal/stbuehler/fix-fdevent
parent
3dd3cde902
commit
9725299587
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue