Browse Source

[core] move addtl request-specific struct members

personal/stbuehler/ci-build
Glenn Strauss 2 years ago
parent
commit
1474be7859
  1. 21
      src/base.h
  2. 2
      src/chunk.h
  3. 8
      src/connections-glue.c
  4. 70
      src/connections.c
  5. 12
      src/gw_backend.c
  6. 38
      src/http-header-glue.c
  7. 4
      src/mod_accesslog.c
  8. 18
      src/mod_cgi.c
  9. 2
      src/mod_cml_lua.c
  10. 4
      src/mod_compress.c
  11. 15
      src/mod_deflate.c
  12. 2
      src/mod_dirlisting.c
  13. 2
      src/mod_evasive.c
  14. 10
      src/mod_fastcgi.c
  15. 2
      src/mod_flv_streaming.c
  16. 2
      src/mod_magnet.c
  17. 6
      src/mod_proxy.c
  18. 2
      src/mod_redirect.c
  19. 4
      src/mod_scgi.c
  20. 2
      src/mod_sockproxy.c
  21. 4
      src/mod_ssi.c
  22. 10
      src/mod_status.c
  23. 2
      src/mod_trigger_b4_dl.c
  24. 6
      src/mod_uploadprogress.c
  25. 28
      src/mod_webdav.c
  26. 16
      src/mod_wstunnel.c
  27. 8
      src/request.h
  28. 26
      src/response.c

21
src/base.h

@ -25,7 +25,10 @@ typedef struct {
off_t content_length;
unsigned int htags; /* bitfield of flagged headers present in response */
array headers;
int send_chunked;
char send_chunked;
char resp_body_started;
char resp_body_finished;
uint32_t resp_header_len;
} response;
typedef struct {
@ -75,13 +78,8 @@ struct connection {
time_t write_request_ts;
time_t connection_start;
uint32_t request_count; /* number of requests handled in this connection */
uint32_t loops_per_request; /* to catch endless loops in a single request
*
* used by mod_rewrite, mod_fastcgi, ... and others
* this is self-protection
*/
int keep_alive_idle; /* remember max_keep_alive_idle from config */
fdnode *fdn; /* fdevent (fdnode *) object */
int fd; /* the FD for this connection */
@ -92,28 +90,20 @@ struct connection {
int is_writable;
int is_ssl_sock;
int keep_alive_idle; /* remember max_keep_alive_idle from config */
int file_started;
int file_finished;
chunkqueue *write_queue; /* a large queue for low-level write ( HTTP response ) [ file, mem ] */
chunkqueue *read_queue; /* a small queue for low-level read ( HTTP request ) [ mem ] */
chunkqueue *request_content_queue; /* takes request-content into tempfile if necessary [ tempfile, mem ]*/
int traffic_limit_reached;
off_t bytes_written; /* used by mod_accesslog, mod_rrd */
off_t bytes_written_cur_second; /* used by mod_accesslog, mod_rrd */
off_t bytes_read; /* used by mod_accesslog, mod_rrd */
off_t bytes_header;
sock_addr dst_addr;
buffer *dst_addr_buf;
/* request */
int http_status;
uint32_t header_len;
request_st request;
request_uri uri;
@ -123,7 +113,6 @@ struct connection {
array environment; /* used to pass lighttpd internal stuff to the FastCGI/CGI apps, setenv does that */
int mode; /* DIRECT (0) or plugin id */
int async_callback;
server *srv;

2
src/chunk.h

@ -38,7 +38,7 @@ typedef struct chunk {
} file;
} chunk;
typedef struct {
typedef struct chunkqueue {
chunk *first;
chunk *last;

8
src/connections-glue.c

@ -113,7 +113,7 @@ handler_t connection_handle_read_post_error(connection *con, int http_status) {
con->request.keep_alive = 0;
/*(do not change status if response headers already set and possibly sent)*/
if (0 != con->bytes_header) return HANDLER_ERROR;
if (0 != con->response.resp_header_len) return HANDLER_ERROR;
http_response_body_clear(con, 0);
con->http_status = http_status;
@ -414,7 +414,7 @@ static int connection_write_100_continue(connection *con) {
handler_t connection_handle_read_post_state(connection *con) {
chunkqueue *cq = con->read_queue;
chunkqueue *dst_cq = con->request_content_queue;
chunkqueue *dst_cq = con->request.reqbody_queue;
int is_closed = 0;
@ -491,8 +491,8 @@ void connection_response_reset(connection *con) {
con->mode = DIRECT;
con->http_status = 0;
con->is_writable = 1;
con->file_finished = 0;
con->file_started = 0;
con->response.resp_body_finished = 0;
con->response.resp_body_started = 0;
if (con->physical.path) { /*(skip for mod_fastcgi authorizer)*/
buffer_clear(con->physical.doc_root);
buffer_reset(con->physical.path);

70
src/connections.c

@ -229,7 +229,7 @@ static void connection_handle_response_end_state(connection *con) {
if (con->state != CON_STATE_ERROR) ++con->srv->con_written;
if (con->request.reqbody_length != con->request_content_queue->bytes_in
if (con->request.reqbody_length != con->request.reqbody_queue->bytes_in
|| con->state == CON_STATE_ERROR) {
/* request body is present and has not been read completely */
con->request.keep_alive = 0;
@ -276,7 +276,7 @@ static void connection_handle_errdoc(connection *con) {
return;
connection_handle_errdoc_init(con);
con->file_finished = 1;
con->response.resp_body_finished = 1;
/* try to send static errorfile */
if (!buffer_string_is_empty(con->conf.errorfile_prefix)) {
@ -343,7 +343,7 @@ static int connection_handle_write_prepare(connection *con) {
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->http_status = 200;
con->file_finished = 1;
con->response.resp_body_finished = 1;
}
break;
@ -365,7 +365,7 @@ static int connection_handle_write_prepare(connection *con) {
case 304:
/* disable chunked encoding again as we have no body */
http_response_body_clear(con, 1);
con->file_finished = 1;
con->response.resp_body_finished = 1;
break;
default: /* class: header + body */
/* only custom body for 4xx and 5xx */
@ -384,7 +384,7 @@ static int connection_handle_write_prepare(connection *con) {
return -1;
}
if (con->file_finished) {
if (con->response.resp_body_finished) {
/* we have all the content and chunked encoding is not used, set a content-length */
if (!(con->response.htags & (HTTP_HEADER_CONTENT_LENGTH|HTTP_HEADER_TRANSFER_ENCODING))) {
@ -452,7 +452,7 @@ static int connection_handle_write_prepare(connection *con) {
* without the content
*/
http_response_body_clear(con, 1);
con->file_finished = 1;
con->response.resp_body_finished = 1;
}
http_response_write_header(con);
@ -463,7 +463,7 @@ static int connection_handle_write_prepare(connection *con) {
static void connection_handle_write(connection *con) {
switch(connection_write_chunkqueue(con, con->write_queue, MAX_WRITE_LIMIT)) {
case 0:
if (con->file_finished) {
if (con->response.resp_body_finished) {
connection_set_state(con, CON_STATE_RESPONSE_END);
}
break;
@ -492,12 +492,12 @@ static void connection_handle_write_state(connection *con) {
connection_handle_write(con);
if (con->state != CON_STATE_WRITE) break;
}
} else if (con->file_finished) {
} else if (con->response.resp_body_finished) {
connection_set_state(con, CON_STATE_RESPONSE_END);
break;
}
if (con->mode != DIRECT && !con->file_finished) {
if (con->mode != DIRECT && !con->response.resp_body_finished) {
int rc = plugins_call_handle_subrequest(con);
switch(rc) {
case HANDLER_WAIT_FOR_EVENT:
@ -521,7 +521,7 @@ static void connection_handle_write_state(connection *con) {
} while (con->state == CON_STATE_WRITE
&& (!chunkqueue_is_empty(con->write_queue)
? con->is_writable
: con->file_finished));
: con->response.resp_body_finished));
}
@ -536,8 +536,8 @@ static connection *connection_init(server *srv) {
con->ndx = -1;
con->bytes_written = 0;
con->bytes_read = 0;
con->bytes_header = 0;
con->loops_per_request = 0;
con->response.resp_header_len = 0;
con->request.loops_per_request = 0;
con->request.conf = &con->conf;
con->request.con = con;
@ -567,7 +567,7 @@ static connection *connection_init(server *srv) {
#undef CLEAN
con->write_queue = chunkqueue_init();
con->read_queue = chunkqueue_init();
con->request_content_queue = chunkqueue_init();
con->request.reqbody_queue = chunkqueue_init();
con->srv = srv;
con->plugin_slots = srv->plugin_slots;
@ -600,7 +600,7 @@ void connections_free(server *srv) {
chunkqueue_free(con->write_queue);
chunkqueue_free(con->read_queue);
chunkqueue_free(con->request_content_queue);
chunkqueue_free(con->request.reqbody_queue);
array_free_data(&con->request.headers);
array_free_data(&con->response.headers);
array_free_data(&con->environment);
@ -649,8 +649,8 @@ static int connection_reset(connection *con) {
con->bytes_written = 0;
con->bytes_written_cur_second = 0;
con->bytes_read = 0;
con->bytes_header = 0;
con->loops_per_request = 0;
con->response.resp_header_len = 0;
con->request.loops_per_request = 0;
con->request.http_method = HTTP_METHOD_UNSET;
con->request.http_version = HTTP_VERSION_UNSET;
@ -678,20 +678,20 @@ static int connection_reset(connection *con) {
con->request.te_chunked = 0;
con->request.htags = 0;
if (con->header_len <= BUFFER_MAX_REUSE_SIZE)
if (con->request.rqst_header_len <= BUFFER_MAX_REUSE_SIZE)
con->request.headers.used = 0;
else
array_reset_data_strings(&con->request.headers);
con->header_len = 0;
con->request.rqst_header_len = 0;
if (0 != con->environment.used)
array_reset_data_strings(&con->environment);
chunkqueue_reset(con->request_content_queue);
chunkqueue_reset(con->request.reqbody_queue);
/* The cond_cache gets reset in response.c */
/* config_cond_cache_reset(con); */
con->async_callback = 0;
con->request.async_callback = 0;
con->error_handler_saved_status = 0;
/*con->error_handler_saved_method = HTTP_METHOD_UNSET;*/
/*(error_handler_saved_method value is not valid unless error_handler_saved_status is set)*/
@ -773,6 +773,7 @@ static int connection_handle_read_state(connection * const con) {
chunkqueue * const cq = con->read_queue;
chunk *c = cq->first;
uint32_t clen = 0;
uint32_t header_len = 0;
unsigned short hoff[8192]; /* max num header lines + 3; 16k on stack */
do {
@ -786,14 +787,14 @@ static int connection_handle_read_state(connection * const con) {
hoff[1] = (unsigned short)c->offset; /* base offset for all lines */
/*hoff[2] = ...;*/ /* offset from base for 2nd line */
con->header_len =
header_len =
connection_read_header_hoff(c->mem->ptr + c->offset, clen, hoff);
/* casting to (unsigned short) might truncate, and the hoff[]
* addition might overflow, but max_request_field_size is USHRT_MAX,
* so failure will be detected below */
const uint32_t max_request_field_size=con->conf.max_request_field_size;
if ((con->header_len ? con->header_len : clen) > max_request_field_size
if ((header_len ? header_len : clen) > max_request_field_size
|| hoff[0] >= sizeof(hoff)/sizeof(hoff[0])-1) {
log_error(con->conf.errh, __FILE__, __LINE__, "%s",
"oversized request-header -> sending Status 431");
@ -802,7 +803,7 @@ static int connection_handle_read_state(connection * const con) {
return 1;
}
if (0 != con->header_len) break;
if (0 != header_len) break;
} while ((c = connection_read_header_more(con, cq, c, clen)));
if (keepalive_request_start) {
@ -841,8 +842,8 @@ static int connection_handle_read_state(connection * const con) {
if (con->conf.log_request_header) {
log_error(con->conf.errh, __FILE__, __LINE__,
"fd: %d request-len: %d\n%.*s", con->fd, (int)con->header_len,
(int)con->header_len, hdrs);
"fd: %d request-len: %d\n%.*s", con->fd, (int)header_len,
(int)header_len, hdrs);
}
con->http_status =
@ -855,11 +856,12 @@ static int connection_handle_read_state(connection * const con) {
/*(http_request_parse() modifies hdrs only to
* undo line-wrapping in-place using spaces)*/
log_error(con->conf.errh, __FILE__, __LINE__, "request-header:\n%.*s",
(int)con->header_len, hdrs);
(int)header_len, hdrs);
}
}
chunkqueue_mark_written(cq, con->header_len);
con->request.rqst_header_len = header_len;
chunkqueue_mark_written(cq, header_len);
connection_set_state(con, CON_STATE_REQUEST_END);
return 1;
}
@ -918,7 +920,7 @@ static handler_t connection_handle_fdevent(void *context, int revents) {
con->is_readable = 1; /*(can read 0 for end-of-stream)*/
if (chunkqueue_is_empty(con->read_queue)) con->request.keep_alive = 0;
if (con->request.reqbody_length < -1) { /*(transparent proxy mode; no more data to read)*/
con->request.reqbody_length = con->request_content_queue->bytes_in;
con->request.reqbody_length = con->request.reqbody_queue->bytes_in;
}
if (sock_addr_get_family(&con->dst_addr) == AF_UNIX) {
/* future: will getpeername() on AF_UNIX properly check if still connected? */
@ -1136,7 +1138,7 @@ static int connection_handle_request(connection *con) {
int rc = http_response_prepare(con);
switch (rc) {
case HANDLER_WAIT_FOR_EVENT:
if (!con->file_finished && (!con->file_started || 0 == con->conf.stream_response_body)) {
if (!con->response.resp_body_finished && (!con->response.resp_body_started || 0 == con->conf.stream_response_body)) {
break; /* come back here */
}
/* response headers received from backend; fall through to start response */
@ -1186,16 +1188,16 @@ static int connection_handle_request(connection *con) {
plugins_call_connection_reset(con);
if (con->request.reqbody_length) {
if (con->request.reqbody_length != con->request_content_queue->bytes_in) {
if (con->request.reqbody_length != con->request.reqbody_queue->bytes_in) {
con->request.keep_alive = 0;
}
con->request.reqbody_length = 0;
chunkqueue_reset(con->request_content_queue);
chunkqueue_reset(con->request.reqbody_queue);
}
con->is_writable = 1;
con->file_finished = 0;
con->file_started = 0;
con->response.resp_body_finished = 0;
con->response.resp_body_started = 0;
con->error_handler_saved_status = con->http_status;
con->error_handler_saved_method = con->request.http_method;
@ -1263,7 +1265,7 @@ int connection_state_machine(connection *con) {
log_clock_gettime_realtime(&con->request.start_hp);
con->request_count++;
con->loops_per_request = 0;
con->request.loops_per_request = 0;
connection_set_state(con, CON_STATE_READ);
/* fall through */

12
src/gw_backend.c

@ -2012,7 +2012,7 @@ handler_t gw_handle_subrequest(connection *con, void *p_d) {
if (con->mode != p->id) return HANDLER_GO_ON; /* not my job */
if ((con->conf.stream_response_body & FDEVENT_STREAM_RESPONSE_BUFMIN)
&& con->file_started) {
&& con->response.resp_body_started) {
if (chunkqueue_length(con->write_queue) > 65536 - 4096) {
fdevent_fdnode_event_clr(hctx->ev, hctx->fdn, FDEVENT_IN);
}
@ -2033,7 +2033,7 @@ handler_t gw_handle_subrequest(connection *con, void *p_d) {
&& (0 == hctx->wb->bytes_in
? (con->state == CON_STATE_READ_POST || -1 == hctx->wb_reqlen)
: (hctx->wb->bytes_in < hctx->wb_reqlen || hctx->wb_reqlen < 0))) {
/* leave excess data in con->request_content_queue, which is
/* leave excess data in con->request.reqbody_queue, which is
* buffered to disk if too large and backend can not keep up */
/*(64k - 4k to attempt to avoid temporary files
* in conjunction with FDEVENT_STREAM_REQUEST_BUFMIN)*/
@ -2045,7 +2045,7 @@ handler_t gw_handle_subrequest(connection *con, void *p_d) {
}
else {
handler_t rc = connection_handle_read_post_state(con);
chunkqueue *req_cq = con->request_content_queue;
chunkqueue *req_cq = con->request.reqbody_queue;
#if 0 /*(not reached since we send 411 Length Required below)*/
if (hctx->wb_reqlen < -1 && con->request.reqbody_length >= 0) {
/* (completed receiving Transfer-Encoding: chunked) */
@ -2140,7 +2140,7 @@ static handler_t gw_recv_response(gw_handler_ctx *hctx, connection *con) {
handler_ctx_clear(hctx);
/* don't do more than 6 loops here; normally shouldn't happen */
if (++con->loops_per_request > 5) {
if (++con->request.loops_per_request > 5) {
log_error(con->conf.errh, __FILE__, __LINE__,
"too many loops while processing request: %s",
con->request.orig_uri->ptr);
@ -2191,7 +2191,7 @@ static handler_t gw_recv_response(gw_handler_ctx *hctx, connection *con) {
}
}
if (con->file_started == 0) {
if (con->response.resp_body_started == 0) {
/* nothing has been sent out yet, try to use another child */
if (hctx->wb->bytes_out == 0 &&
@ -2255,7 +2255,7 @@ static handler_t gw_handle_fdevent(void *ctx, int revents) {
*
*/
gw_send_request(hctx, con);
} else if (con->file_started) {
} else if (con->response.resp_body_started) {
/* drain any remaining data from kernel pipe buffers
* even if (con->conf.stream_response_body
* & FDEVENT_STREAM_RESPONSE_BUFMIN)

38
src/http-header-glue.c

@ -108,7 +108,7 @@ int http_response_redirect_to_directory(connection *con, int status) {
if (status >= 300) {
http_header_response_set(con, HTTP_HEADER_LOCATION, CONST_STR_LEN("Location"), CONST_BUF_LEN(o));
con->http_status = status;
con->file_finished = 1;
con->response.resp_body_finished = 1;
}
else {
http_header_response_set(con, HTTP_HEADER_CONTENT_LOCATION, CONST_STR_LEN("Content-Location"), CONST_BUF_LEN(o));
@ -543,7 +543,7 @@ void http_response_send_file (connection *con, buffer *path) {
if (fd < 0) { /* 0-length file */
con->http_status = 200;
con->file_finished = 1;
con->response.resp_body_finished = 1;
return;
}
@ -585,7 +585,7 @@ void http_response_send_file (connection *con, buffer *path) {
&& 0 == strncmp(range->ptr, "bytes=", 6)) {
/* support only "bytes" byte-unit */
/* content prepared, I'm done */
con->file_finished = 1;
con->response.resp_body_finished = 1;
if (0 == http_response_parse_range(con, path, sce, range->ptr+6)) {
con->http_status = 206;
@ -603,7 +603,7 @@ void http_response_send_file (connection *con, buffer *path) {
if (0 == http_chunk_append_file_fd(con, path, fd, sce->st.st_size)) {
con->http_status = 200;
con->file_finished = 1;
con->response.resp_body_finished = 1;
}
else {
con->http_status = 500;
@ -813,12 +813,12 @@ range_success: ;
void http_response_backend_error (connection *con) {
if (con->file_started) {
if (con->response.resp_body_started) {
/*(response might have been already started, kill the connection)*/
/*(mode == DIRECT to avoid later call to http_response_backend_done())*/
con->mode = DIRECT; /*(avoid sending final chunked block)*/
con->request.keep_alive = 0;
con->file_finished = 1;
con->response.resp_body_finished = 1;
} /*(else error status set later by http_response_backend_done())*/
}
@ -829,16 +829,16 @@ void http_response_backend_done (connection *con) {
switch (con->state) {
case CON_STATE_HANDLE_REQUEST:
case CON_STATE_READ_POST:
if (!con->file_started) {
if (!con->response.resp_body_started) {
/* Send an error if we haven't sent any data yet */
con->http_status = 500;
con->mode = DIRECT;
break;
} /* else fall through */
case CON_STATE_WRITE:
if (!con->file_finished) {
if (!con->response.resp_body_finished) {
http_chunk_close(con);
con->file_finished = 1;
con->response.resp_body_finished = 1;
}
default:
break;
@ -896,7 +896,7 @@ static handler_t http_response_process_local_redir(connection *con, size_t blen)
&& 0 == blen
&& !(con->response.htags & HTTP_HEADER_STATUS) /*no "Status" or NPH response*/
&& 1 == con->response.headers.used) {
if (++con->loops_per_request > 5) {
if (++con->request.loops_per_request > 5) {
log_error(con->conf.errh, __FILE__, __LINE__,
"too many internal loops while processing request: %s",
con->request.orig_uri->ptr);
@ -909,11 +909,11 @@ static handler_t http_response_process_local_redir(connection *con, size_t blen)
if (con->request.reqbody_length) {
if (con->request.reqbody_length
!= con->request_content_queue->bytes_in) {
!= con->request.reqbody_queue->bytes_in) {
con->request.keep_alive = 0;
}
con->request.reqbody_length = 0;
chunkqueue_reset(con->request_content_queue);
chunkqueue_reset(con->request.reqbody_queue);
}
if (con->http_status != 307 && con->http_status != 308) {
@ -1122,7 +1122,7 @@ handler_t http_response_parse_headers(connection *con, http_response_opts *opts,
return HANDLER_ERROR;
}
con->http_status = 200; /* OK */
con->file_started = 1;
con->response.resp_body_started = 1;
return HANDLER_GO_ON;
} else {
/* invalid response headers */
@ -1166,7 +1166,7 @@ handler_t http_response_parse_headers(connection *con, http_response_opts *opts,
return HANDLER_ERROR;
}
con->file_started = 1;
con->response.resp_body_started = 1;
if (opts->authorizer
&& (con->http_status == 0 || con->http_status == 200)) {
@ -1180,7 +1180,7 @@ handler_t http_response_parse_headers(connection *con, http_response_opts *opts,
if (opts->local_redir && con->http_status >= 300 && con->http_status < 400){
/*(con->response.htags & HTTP_HEADER_LOCATION)*/
handler_t rc = http_response_process_local_redir(con, blen);
if (con->mode == DIRECT) con->file_started = 0;
if (con->mode == DIRECT) con->response.resp_body_started = 0;
if (rc != HANDLER_GO_ON) return rc;
}
@ -1192,7 +1192,7 @@ handler_t http_response_parse_headers(connection *con, http_response_opts *opts,
http_response_xsendfile2(con, vb, opts->xsendfile_docroot);
/* http_header_response_unset() shortcut for HTTP_HEADER_OTHER */
buffer_clear(vb); /*(do not send to client)*/
if (con->mode == DIRECT) con->file_started = 0;
if (con->mode == DIRECT) con->response.resp_body_started = 0;
return HANDLER_FINISHED;
} else if (NULL != (vb = http_header_response_get(con, HTTP_HEADER_OTHER, CONST_STR_LEN("X-Sendfile")))
|| (opts->backend == BACKEND_FASTCGI /* X-LIGHTTPD-send-file is deprecated; historical for fastcgi */
@ -1200,7 +1200,7 @@ handler_t http_response_parse_headers(connection *con, http_response_opts *opts,
http_response_xsendfile(con, vb, opts->xsendfile_docroot);
/* http_header_response_unset() shortcut for HTTP_HEADER_OTHER */
buffer_clear(vb); /*(do not send to client)*/
if (con->mode == DIRECT) con->file_started = 0;
if (con->mode == DIRECT) con->response.resp_body_started = 0;
return HANDLER_FINISHED;
}
}
@ -1308,12 +1308,12 @@ handler_t http_response_read(connection *con, http_response_opts *opts, buffer *
* (backend should read all data desired prior to closing socket,
* though might send app-level close data frame, if applicable) */
return HANDLER_FINISHED; /* read finished */
} else if (0 == con->file_started) {
} else if (0 == con->response.resp_body_started) {
/* split header from body */
handler_t rc = http_response_parse_headers(con, opts, b);
if (rc != HANDLER_GO_ON) return rc;
/* accumulate response in b until headers completed (or error) */
if (con->file_started) buffer_clear(b);
if (con->response.resp_body_started) buffer_clear(b);
} else {
if (0 != http_chunk_append_buffer(con, b)) {
/* error writing to tempfile;

4
src/mod_accesslog.c

@ -958,8 +958,8 @@ static int log_access_record (const connection * const con, buffer * const b, fo
case FORMAT_BYTES_OUT_NO_HEADER:
if (con->bytes_written > 0) {
buffer_append_int(b,
con->bytes_written - con->bytes_header <= 0 ? 0 : con->bytes_written - con->bytes_header);
off_t bytes = con->bytes_written - (off_t)con->response.resp_header_len;
buffer_append_int(b, bytes > 0 ? bytes : 0);
} else {
buffer_append_string_len(b, CONST_STR_LEN("-"));
}

18
src/mod_cgi.c

@ -333,7 +333,7 @@ static void cgi_connection_close(connection *con, handler_ctx *hctx) {
cgi_handler_ctx_free(hctx);
/* finish response (if not already con->file_started, con->file_finished) */
/* finish response (if not already con->response.resp_body_started, con->response.resp_body_finished) */
if (con->mode == p->id) {
http_response_backend_done(con);
}
@ -369,7 +369,7 @@ static handler_t cgi_handle_fdevent_send (void *ctx, int revents) {
if (revents & FDEVENT_HUP) {
/* skip sending remaining data to CGI */
if (con->request.reqbody_length) {
chunkqueue *cq = con->request_content_queue;
chunkqueue *cq = con->request.reqbody_queue;
chunkqueue_mark_written(cq, chunkqueue_length(cq));
if (cq->bytes_in != (off_t)con->request.reqbody_length) {
con->request.keep_alive = 0;
@ -412,7 +412,7 @@ static handler_t cgi_response_headers(connection *con, struct http_response_opts
}
if (hctx->conf.upgrade && !(con->response.htags & HTTP_HEADER_UPGRADE)) {
chunkqueue *cq = con->request_content_queue;
chunkqueue *cq = con->request.reqbody_queue;
hctx->conf.upgrade = 0;
if (cq->bytes_out == (off_t)con->request.reqbody_length) {
cgi_connection_close_fdtocgi(con, hctx); /*(closes hctx->fdtocgi)*/
@ -458,7 +458,7 @@ static handler_t cgi_handle_fdevent(void *ctx, int revents) {
/* perhaps this issue is already handled */
if (revents & (FDEVENT_HUP|FDEVENT_RDHUP)) {
if (con->file_started) {
if (con->response.resp_body_started) {
/* drain any remaining data from kernel pipe buffers
* even if (con->conf.stream_response_body
* & FDEVENT_STREAM_RESPONSE_BUFMIN)
@ -475,7 +475,7 @@ static handler_t cgi_handle_fdevent(void *ctx, int revents) {
return rc; /* HANDLER_FINISHED or HANDLER_COMEBACK or HANDLER_ERROR */
} else if (!buffer_string_is_empty(hctx->response)) {
/* unfinished header package which is a body in reality */
con->file_started = 1;
con->response.resp_body_started = 1;
if (0 != http_chunk_append_buffer(con, hctx->response)) {
cgi_connection_close(con, hctx);
return HANDLER_ERROR;
@ -639,7 +639,7 @@ static ssize_t cgi_write_file_chunk_mmap(connection *con, int fd, chunkqueue *cq
static int cgi_write_request(handler_ctx *hctx, int fd) {
connection *con = hctx->remote_conn;
chunkqueue *cq = con->request_content_queue;
chunkqueue *cq = con->request.reqbody_queue;
chunk *c;
/* old comment: windows doesn't support select() on pipes - wouldn't be easy to fix for all platforms.
@ -934,7 +934,7 @@ SUBREQUEST_FUNC(mod_cgi_handle_subrequest) {
if (NULL == hctx) return HANDLER_GO_ON;
if ((con->conf.stream_response_body & FDEVENT_STREAM_RESPONSE_BUFMIN)
&& con->file_started) {
&& con->response.resp_body_started) {
if (chunkqueue_length(con->write_queue) > 65536 - 4096) {
fdevent_fdnode_event_clr(con->srv->ev,hctx->fdn,FDEVENT_IN);
} else if (!(fdevent_fdnode_interest(hctx->fdn) & FDEVENT_IN)) {
@ -945,7 +945,7 @@ SUBREQUEST_FUNC(mod_cgi_handle_subrequest) {
}
}
chunkqueue * const cq = con->request_content_queue;
chunkqueue * const cq = con->request.reqbody_queue;
if (cq->bytes_in != (off_t)con->request.reqbody_length) {
/*(64k - 4k to attempt to avoid temporary files
@ -980,7 +980,7 @@ SUBREQUEST_FUNC(mod_cgi_handle_subrequest) {
return HANDLER_FINISHED;
}
} else if (!chunkqueue_is_empty(con->request_content_queue)) {
} else if (!chunkqueue_is_empty(cq)) {
if (0 != cgi_write_request(hctx, hctx->fdtocgi)) {
cgi_connection_close(con, hctx);
return HANDLER_ERROR;

2
src/mod_cml_lua.c

@ -286,7 +286,7 @@ int cache_parse_lua(connection *con, plugin_data *p, const buffer *fn) {
force_assert(NULL != vb);
}
con->file_finished = 1;
con->response.resp_body_finished = 1;
if (HANDLER_FINISHED == http_response_handle_cachable(con, vb)) {
/* ok, the client already has our content,

4
src/mod_compress.c

@ -750,8 +750,8 @@ static int deflate_file_to_buffer(connection *con, plugin_data *p, int ifd, buff
buffer_reset(con->physical.path);
con->file_finished = 1;
con->file_started = 1;
con->response.resp_body_finished = 1;
con->response.resp_body_started = 1;
return 0;
}

15
src/mod_deflate.c

@ -15,7 +15,8 @@
*
* Patch further modified in this incarnation.
*
* Note: this patch only handles completed responses (con->file_finished);
* Note: this patch only handles completed responses
* (con->response.resp_body_finished)
* this patch does not currently handle streaming dynamic responses,
* and therefore also does not worry about Transfer-Encoding: chunked
* (or having separate con->output_queue for chunked-encoded output)
@ -59,7 +60,8 @@
* block, e.g. $HTTP["url"] =~ "....." { deflate.mimetypes = ( ) }
* - deflate.sync-flush removed; controlled by con->conf.stream_response_body
* (though streaming compression not currently implemented in mod_deflate)
* - inactive directives in this patch (since con->file_finished required)
* - inactive directives in this patch
* (since con->response.resp_body_finished required)
* deflate.work-block-size
* deflate.output-buffer-size
* - remove weak file size check; SIGBUS is trapped, file that shrink will error
@ -958,7 +960,8 @@ static handler_t deflate_compress_response(connection *con, handler_ctx *hctx) {
/*(currently should always be true)*/
/*(current implementation requires response be complete)*/
close_stream = (con->file_finished && chunkqueue_is_empty(hctx->in_queue));
close_stream = (con->response.resp_body_finished
&& chunkqueue_is_empty(hctx->in_queue));
if (mod_deflate_stream_flush(con, hctx, close_stream) < 0) {
log_error(con->conf.errh, __FILE__, __LINE__, "flush error");
return HANDLER_ERROR;
@ -1071,7 +1074,7 @@ CONNECTION_FUNC(mod_deflate_handle_response_start) {
handler_t rc;
/*(current implementation requires response be complete)*/
if (!con->file_finished) return HANDLER_GO_ON;
if (!con->response.resp_body_finished) return HANDLER_GO_ON;
if (con->request.http_method == HTTP_METHOD_HEAD) return HANDLER_GO_ON;
if (con->response.htags & HTTP_HEADER_TRANSFER_ENCODING) return HANDLER_GO_ON;
@ -1094,7 +1097,7 @@ CONNECTION_FUNC(mod_deflate_handle_response_start) {
if (NULL == p->conf.mimetypes) return HANDLER_GO_ON;
/* check if size of response is below min-compress-size or exceeds max*/
/* (con->file_finished checked at top of routine) */
/* (con->response.resp_body_finished checked at top of routine) */
len = chunkqueue_length(con->write_queue);
if (len <= (off_t)p->conf.min_compress_size) return HANDLER_GO_ON;
if (p->conf.max_compress_size /*(max_compress_size in KB)*/
@ -1166,7 +1169,7 @@ CONNECTION_FUNC(mod_deflate_handle_response_start) {
/* clear content length even if 304 since compressed length unknown */
http_response_body_clear(con, 0);
con->file_finished = 1;
con->response.resp_body_finished = 1;
con->mode = DIRECT;
return HANDLER_GO_ON;
}

2
src/mod_dirlisting.c

@ -1015,7 +1015,7 @@ static int http_list_directory(connection *con, plugin_data *p, buffer *dir) {
}
chunkqueue_append_buffer_commit(con->write_queue);
con->file_finished = 1;
con->response.resp_body_finished = 1;
return 0;
}

2
src/mod_evasive.c

@ -132,7 +132,7 @@ URIHANDLER_FUNC(mod_evasive_uri_handler) {
if (!buffer_is_empty(p->conf.location)) {
http_header_response_set(con, HTTP_HEADER_LOCATION, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.location));
con->http_status = 302;
con->file_finished = 1;
con->response.resp_body_finished = 1;
} else {
con->http_status = 403;
}

10
src/mod_fastcgi.c

@ -220,7 +220,7 @@ static void fcgi_header(FCGI_Header * header, unsigned char type, int request_id
static handler_t fcgi_stdin_append(handler_ctx *hctx) {
FCGI_Header header;
connection *con = hctx->remote_conn;
chunkqueue *req_cq = con->request_content_queue;
chunkqueue *req_cq = con->request.reqbody_queue;
off_t offset, weWant;
const off_t req_cqlen = req_cq->bytes_in - req_cq->bytes_out;
int request_id = hctx->request_id;
@ -274,7 +274,7 @@ static handler_t fcgi_create_env(handler_ctx *hctx) {
};
size_t rsz = (size_t)(con->read_queue->bytes_out - hctx->wb->bytes_in);
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->wb, rsz < 65536 ? rsz : con->header_len);
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->wb, rsz < 65536 ? rsz : con->request.rqst_header_len);
/* send FCGI_BEGIN_REQUEST */
@ -317,7 +317,7 @@ static handler_t fcgi_create_env(handler_ctx *hctx) {
}
if (con->request.reqbody_length) {
/*chunkqueue_append_chunkqueue(hctx->wb, con->request_content_queue);*/
/*chunkqueue_append_chunkqueue(hctx->wb, con->request.reqbody_queue);*/
if (con->request.reqbody_length > 0)
hctx->wb_reqlen += con->request.reqbody_length;/* (eventual) (minimal) total request size, not necessarily including all fcgi_headers around content length yet */
else /* as-yet-unknown total request size (Transfer-Encoding: chunked)*/
@ -432,7 +432,7 @@ static handler_t fcgi_recv_parse(connection *con, struct http_response_opts_t *o
if (packet.len == 0) break;
/* is the header already finished */
if (0 == con->file_started) {
if (0 == con->response.resp_body_started) {
/* split header from body */
buffer *hdrs = hctx->response;
if (NULL == hdrs) {
@ -445,7 +445,7 @@ static handler_t fcgi_recv_parse(connection *con, struct http_response_opts_t *o
fin = 1;
break;
}
if (0 == con->file_started) {
if (0 == con->response.resp_body_started) {
if (!hctx->response) {
hctx->response = chunk_buffer_acquire();
buffer_copy_buffer(hctx->response, hdrs);

2
src/mod_flv_streaming.c

@ -127,7 +127,7 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
}
http_header_response_set(con, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv"));
con->file_finished = 1;
con->response.resp_body_finished = 1;
return HANDLER_FINISHED;
}

2
src/mod_magnet.c

@ -940,7 +940,7 @@ static handler_t magnet_attract(connection *con, plugin_data *p, buffer *name) {
if (lua_return_value > 99) {
con->http_status = lua_return_value;
con->file_finished = 1;
con->response.resp_body_finished = 1;
/* try { ...*/
if (0 == setjmp(exceptionjmp)) {

6
src/mod_proxy.c

@ -821,7 +821,7 @@ static handler_t proxy_create_env(gw_handler_ctx *gwhctx) {
const int upgrade = hctx->conf.header.upgrade
&& (NULL != http_header_request_get(con, HTTP_HEADER_UPGRADE, CONST_STR_LEN("Upgrade")));
size_t rsz = (size_t)(con->read_queue->bytes_out - hctx->gw.wb->bytes_in);
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->gw.wb, rsz < 65536 ? rsz : con->header_len);
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->gw.wb, rsz < 65536 ? rsz : con->request.rqst_header_len);
/* build header */
@ -949,7 +949,7 @@ static handler_t proxy_create_env(gw_handler_ctx *gwhctx) {
chunkqueue_prepend_buffer_commit(hctx->gw.wb);
if (con->request.reqbody_length) {
chunkqueue_append_chunkqueue(hctx->gw.wb, con->request_content_queue);
chunkqueue_append_chunkqueue(hctx->gw.wb, con->request.reqbody_queue);
if (con->request.reqbody_length > 0)
hctx->gw.wb_reqlen += con->request.reqbody_length; /* total req size */
else /* as-yet-unknown total request size (Transfer-Encoding: chunked)*/
@ -965,7 +965,7 @@ static handler_t proxy_create_env_connect(gw_handler_ctx *gwhctx) {
handler_ctx *hctx = (handler_ctx *)gwhctx;
connection *con = hctx->gw.remote_conn;
con->http_status = 200; /* OK */
con->file_started = 1;
con->response.resp_body_started = 1;
gw_set_transparent(&hctx->gw);
http_response_upgrade_read_body_unknown(con);

2
src/mod_redirect.c

@ -180,7 +180,7 @@ URIHANDLER_FUNC(mod_redirect_uri_handler) {
CONST_BUF_LEN(tb));
con->http_status = p->conf.redirect_code;
con->mode = DIRECT;
con->file_finished = 1;
con->response.resp_body_finished = 1;
}
else if (HANDLER_ERROR == rc) {
log_error(con->conf.errh, __FILE__, __LINE__,

4
src/mod_scgi.c

@ -216,7 +216,7 @@ static handler_t scgi_create_env(handler_ctx *hctx) {
: scgi_env_add_uwsgi;
size_t offset;
size_t rsz = (size_t)(con->read_queue->bytes_out - hctx->wb->bytes_in);
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->wb, rsz < 65536 ? rsz : con->header_len);
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->wb, rsz < 65536 ? rsz : con->request.rqst_header_len);
/* save space for 9 digits (plus ':'), though incoming HTTP request
* currently limited to 64k (65535, so 5 chars) */
@ -267,7 +267,7 @@ static handler_t scgi_create_env(handler_ctx *hctx) {
#endif
if (con->request.reqbody_length) {
chunkqueue_append_chunkqueue(hctx->wb, con->request_content_queue);
chunkqueue_append_chunkqueue(hctx->wb, con->request.reqbody_queue);
if (con->request.reqbody_length > 0)
hctx->wb_reqlen += con->request.reqbody_length; /* total req size */
else /* as-yet-unknown total request size (Transfer-Encoding: chunked)*/

2
src/mod_sockproxy.c

@ -126,7 +126,7 @@ SETDEFAULTS_FUNC(mod_sockproxy_set_defaults) {
static handler_t sockproxy_create_env_connect(handler_ctx *hctx) {
connection *con = hctx->remote_conn;
con->file_started = 1;
con->response.resp_body_started = 1;
gw_set_transparent(hctx);
http_response_upgrade_read_body_unknown(con);

4
src/mod_ssi.c

@ -1203,8 +1203,8 @@ static int mod_ssi_handle_request(connection *con, handler_ctx *p) {
if (mod_ssi_process_file(con, p, &st)) return -1;
con->file_started = 1;
con->file_finished = 1;
con->response.resp_body_started = 1;
con->response.resp_body_finished = 1;
if (buffer_string_is_empty(p->conf.content_type)) {
http_header_response_set(con, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));

10
src/mod_status.c

@ -494,7 +494,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">"));
if (c->request.reqbody_length) {
buffer_append_int(b, c->request_content_queue->bytes_in);
buffer_append_int(b, c->request.reqbody_queue->bytes_in);
buffer_append_string_len(b, CONST_STR_LEN("/"));
buffer_append_int(b, c->request.reqbody_length);
} else {
@ -715,7 +715,7 @@ static handler_t mod_status_handle_server_statistics(connection *con) {
if (0 == st->used) {
/* we have nothing to send */
con->http_status = 204;
con->file_finished = 1;
con->response.resp_body_finished = 1;
return HANDLER_FINISHED;
}
@ -732,7 +732,7 @@ static handler_t mod_status_handle_server_statistics(connection *con) {
http_header_response_set(con, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain"));
con->http_status = 200;
con->file_finished = 1;
con->response.resp_body_finished = 1;
return HANDLER_FINISHED;
}
@ -750,7 +750,7 @@ static handler_t mod_status_handle_server_status(connection *con, plugin_data *p
}
con->http_status = 200;
con->file_finished = 1;
con->response.resp_body_finished = 1;
return HANDLER_FINISHED;
}
@ -810,7 +810,7 @@ static handler_t mod_status_handle_server_config(connection *con) {
http_header_response_set(con, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
con->http_status = 200;
con->file_finished = 1;
con->response.resp_body_finished = 1;
return HANDLER_FINISHED;
}

2
src/mod_trigger_b4_dl.c

@ -345,7 +345,7 @@ static handler_t mod_trigger_b4_dl_deny(connection * const con, const plugin_dat
"trigger-before-download.deny-url not configured");
con->http_status = 500;
}
con->file_finished = 1;
con->response.resp_body_finished = 1;
return HANDLER_FINISHED;
}

6
src/mod_uploadprogress.c

@ -260,8 +260,8 @@ URIHANDLER_FUNC(mod_uploadprogress_uri_handler) {
case HTTP_METHOD_GET:
buffer_reset(con->physical.path);
con->file_started = 1;
con->file_finished = 1;
con->response.resp_body_started = 1;
con->response.resp_body_finished = 1;
con->http_status = 200;
con->mode = DIRECT;
@ -292,7 +292,7 @@ URIHANDLER_FUNC(mod_uploadprogress_uri_handler) {
buffer_append_string_len(b, CONST_STR_LEN(
"</size>"
"<received>"));
buffer_append_int(b, post_con->request_content_queue->bytes_in);
buffer_append_int(b, post_con->request.reqbody_queue->bytes_in);
buffer_append_string_len(b, CONST_STR_LEN(
"</received>"
"</upload>"));

28
src/mod_webdav.c

@ -211,8 +211,8 @@
#include "plugin.h"
#define http_status_get(con) ((con)->http_status)
#define http_status_set_fin(con, code) ((con)->file_finished = 1, \
(con)->mode = DIRECT, \
#define http_status_set_fin(con, code) ((con)->response.resp_body_finished = 1,\
(con)->mode = DIRECT, \
(con)->http_status = (code))
#define http_status_set(con, code) ((con)->http_status = (code))
#define http_status_unset(con) ((con)->http_status = 0)
@ -945,7 +945,7 @@ static void
webdav_xml_doc_error_propfind_finite_depth (connection * const con)
{
http_status_set(con, 403); /* Forbidden */
con->file_finished = 1;
con->response.resp_body_finished = 1;
buffer * const b =
chunkqueue_append_buffer_open_sz(con->write_queue, 256);
@ -962,7 +962,7 @@ static void
webdav_xml_doc_error_lock_token_matches_request_uri (connection * const con)
{
http_status_set(con, 409); /* Conflict */
con->file_finished = 1;
con->response.resp_body_finished = 1;
buffer * const b =
chunkqueue_append_buffer_open_sz(con->write_queue, 256);
@ -981,7 +981,7 @@ webdav_xml_doc_423_locked (connection * const con, buffer * const hrefs,
const char * const errtag, const uint32_t errtaglen)
{
http_status_set(con, 423); /* Locked */
con->file_finished = 1;
con->response.resp_body_finished = 1;
buffer * const b = /*(optimization; buf extended as needed)*/
chunkqueue_append_buffer_open_sz(con->write_queue, 256 + hrefs->used);
@ -3380,7 +3380,7 @@ webdav_parse_chunkqueue (connection * const con,
xmlCtxtUseOptions(ctxt, XML_PARSE_NOERROR | XML_PARSE_NOWARNING
| XML_PARSE_PEDANTIC| XML_PARSE_NONET);
char *xmlstr;
chunkqueue * const cq = con->request_content_queue;
chunkqueue * const cq = con->request.reqbody_queue;
size_t weWant = cq->bytes_in - cq->bytes_out;
int err = XML_ERR_OK;
@ -4278,7 +4278,7 @@ mod_webdav_put_prep (connection * const con, const plugin_config * const pconf)
* (still, loop on partial writes)
* (Note: copying might take some time, temporarily pausing server)
* (error status is set if error occurs) */
chunkqueue * const cq = con->request_content_queue;
chunkqueue * const cq = con->request.reqbody_queue;
off_t cqlen = chunkqueue_length(cq);
if (!mod_webdav_write_cq(con, cq, fd)) {
close(fd);
@ -4310,7 +4310,7 @@ static int
mod_webdav_put_linkat_rename (connection * const con,
const char * const pathtemp)
{
chunkqueue * const cq = con->request_content_queue;
chunkqueue * const cq = con->request.reqbody_queue;
chunk *c = cq->first;
char pathproc[32] = "/proc/self/fd/";
@ -4394,7 +4394,7 @@ mod_webdav_put_deprecated_unsafe_partial_put_compat (connection * const con,
* check that reqbody is contained in single tempfile and open fd (expected)
* (Note: copying might take some time, temporarily pausing server)
*/
chunkqueue * const cq = con->request_content_queue;
chunkqueue * const cq = con->request.reqbody_queue;
chunk *c = cq->first;
off_t cqlen = chunkqueue_length(cq);
if (c->type == FILE_CHUNK && NULL == c->next && c->file.fd >= 0) {
@ -4418,7 +4418,7 @@ mod_webdav_put_deprecated_unsafe_partial_put_compat (connection * const con,
* (still, loop on partial writes)
* (Note: copying might take some time, temporarily pausing server)
* (error status is set if error occurs) */
mod_webdav_write_cq(con, con->request_content_queue, fd);
mod_webdav_write_cq(con, con->request.reqbody_queue, fd);
}
struct stat st;
@ -4444,7 +4444,7 @@ static handler_t
mod_webdav_put (connection * const con, const plugin_config * const pconf)
{
if (con->state == CON_STATE_READ_POST) {
int first_read = chunkqueue_is_empty(con->request_content_queue);
int first_read = chunkqueue_is_empty(con->request.reqbody_queue);
handler_t rc = connection_handle_read_post_state(con);
if (rc != HANDLER_GO_ON) {
if (first_read && rc == HANDLER_WAIT_FOR_EVENT
@ -4478,7 +4478,7 @@ mod_webdav_put (connection * const con, const plugin_config * const pconf)
* so add pid and fd to avoid conflict with an unlikely parallel
* PUT request being handled by same server pid (presumably by
* same client using same lock token)) */
chunkqueue * const cq = con->request_content_queue;
chunkqueue * const cq = con->request.reqbody_queue;
chunk *c = cq->first;
/* future: might support client specifying getcontenttype property
@ -5663,8 +5663,8 @@ CONNECTION_FUNC(mod_webdav_handle_reset) {
if (*dptr) {
free(*dptr);
*dptr = NULL;
chunkqueue_set_tempdirs(con->request_content_queue, /* reset sz */
con->request_content_queue->tempdirs, 0);
chunkqueue_set_tempdirs(con->request.reqbody_queue, /* reset sz */
con->request.reqbody_queue->tempdirs, 0);
}
return HANDLER_GO_ON;
}

16
src/mod_wstunnel.c

@ -353,14 +353,14 @@ static handler_t wstunnel_create_env(gw_handler_ctx *gwhctx) {
handler_t rc;
if (0 == con->request.reqbody_length) {
http_response_upgrade_read_body_unknown(con);
chunkqueue_append_chunkqueue(con->request_content_queue,
chunkqueue_append_chunkqueue(con->request.reqbody_queue,
con->read_queue);
}
rc = mod_wstunnel_handshake_create_response(hctx);
if (rc != HANDLER_GO_ON) return rc;
con->http_status = 101; /* Switching Protocols */
con->file_started = 1;
con->response.resp_body_started = 1;
hctx->ping_ts = log_epoch_secs;
gw_set_transparent(&hctx->gw);
@ -370,8 +370,8 @@ static handler_t wstunnel_create_env(gw_handler_ctx *gwhctx) {
static handler_t wstunnel_stdin_append(gw_handler_ctx *gwhctx) {
/* prepare websocket frames to backend */
/* (caller should verify con->request_content_queue) */
/*assert(!chunkqueue_is_empty(con->request_content_queue));*/
/* (caller should verify con->request.reqbody_queue) */
/*assert(!chunkqueue_is_empty(con->request.reqbody_queue));*/
handler_ctx *hctx = (handler_ctx *)gwhctx;
if (0 == mod_wstunnel_frame_recv(hctx))
return HANDLER_GO_ON;
@ -656,7 +656,7 @@ int mod_wstunnel_plugin_init(plugin *p) {
static int get_key3(connection *con, char *buf) {
/* 8 bytes should have been sent with request
* for draft-ietf-hybi-thewebsocketprotocol-00 */
chunkqueue *cq = con->request_content_queue;
chunkqueue *cq = con->request.reqbody_queue;
size_t bytes = 8;
/*(caller should ensure bytes available prior to calling this routine)*/
/*assert(chunkqueue_length(cq) >= 8);*/
@ -858,7 +858,7 @@ handler_t mod_wstunnel_handshake_create_response(handler_ctx *hctx) {
#ifdef _MOD_WEBSOCKET_SPEC_IETF_00_
/* 8 bytes should have been sent with request
* for draft-ietf-hybi-thewebsocketprotocol-00 */
chunkqueue *cq = con->request_content_queue;
chunkqueue *cq = con->request.reqbody_queue;
if (chunkqueue_length(cq) < 8)
return HANDLER_WAIT_FOR_EVENT;
#endif /* _MOD_WEBSOCKET_SPEC_IETF_00_ */