http_response_backend_error()
consolidate repeated code in dynamic handlers which manipulates con->file_finished. Centralize calls to http_chunk_close(). (mod_cgi, mod_fastcgi, mod_scgi, mod_proxy)
This commit is contained in:
parent
923688d2da
commit
4ef4baa59d
|
@ -169,6 +169,7 @@ static void connection_handle_errdoc_init(server *srv, connection *con) {
|
|||
}
|
||||
}
|
||||
|
||||
con->response.transfer_encoding = 0;
|
||||
buffer_reset(con->physical.path);
|
||||
array_reset(con->response.headers);
|
||||
chunkqueue_reset(con->write_queue);
|
||||
|
@ -291,7 +292,6 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
|
|||
|
||||
http_chunk_append_buffer(srv, con, b);
|
||||
buffer_free(b);
|
||||
http_chunk_close(srv, con);
|
||||
|
||||
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
|
||||
}
|
||||
|
@ -1031,7 +1031,9 @@ int connection_state_machine(server *srv, connection *con) {
|
|||
|
||||
switch (r = http_response_prepare(srv, con)) {
|
||||
case HANDLER_WAIT_FOR_EVENT:
|
||||
if (!con->file_started || 0 == con->conf.stream_response_body) break; /* come back here */
|
||||
if (!con->file_finished && (!con->file_started || 0 == con->conf.stream_response_body)) {
|
||||
break; /* come back here */
|
||||
}
|
||||
/* response headers received from backend; fall through to start response */
|
||||
case HANDLER_FINISHED:
|
||||
if (con->error_handler_saved_status > 0) {
|
||||
|
|
|
@ -727,6 +727,17 @@ void http_response_xsendfile (server *srv, connection *con, buffer *path, const
|
|||
}
|
||||
}
|
||||
|
||||
void http_response_backend_error (server *srv, connection *con) {
|
||||
UNUSED(srv);
|
||||
if (con->file_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->keep_alive = 0; /*(no keep-alive; final chunked block not sent)*/
|
||||
con->file_finished = 1;
|
||||
} /*(else error status set later by http_response_backend_done())*/
|
||||
}
|
||||
|
||||
void http_response_backend_done (server *srv, connection *con) {
|
||||
/* (not CON_STATE_ERROR and not CON_STATE_RESPONSE_END,
|
||||
* i.e. not called from handle_connection_close or connection_reset
|
||||
|
|
|
@ -410,12 +410,6 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
|
|||
|
||||
if (n == 0) {
|
||||
/* read finished */
|
||||
|
||||
con->file_finished = 1;
|
||||
|
||||
/* send final chunk */
|
||||
http_chunk_close(srv, con);
|
||||
|
||||
return FDEVENT_HANDLED_FINISHED;
|
||||
}
|
||||
|
||||
|
@ -1589,7 +1583,7 @@ SUBREQUEST_FUNC(mod_cgi_handle_subrequest) {
|
|||
}
|
||||
|
||||
/* if not done, wait for CGI to close stdout, so we read EOF on pipe */
|
||||
return con->file_finished ? HANDLER_FINISHED : HANDLER_WAIT_FOR_EVENT;
|
||||
return HANDLER_WAIT_FOR_EVENT;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1863,7 +1863,6 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
|
|||
#define FCGI_ENV_ADD_CHECK(ret, con) \
|
||||
if (ret == -1) { \
|
||||
con->http_status = 400; \
|
||||
con->file_finished = 1; \
|
||||
return -1; \
|
||||
};
|
||||
static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
|
||||
|
@ -2677,15 +2676,6 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
|
|||
|
||||
break;
|
||||
case FCGI_END_REQUEST:
|
||||
con->file_finished = 1;
|
||||
|
||||
if (host->mode != FCGI_AUTHORIZER ||
|
||||
!(con->http_status == 0 ||
|
||||
con->http_status == 200)) {
|
||||
/* send chunk-end if necessary */
|
||||
http_chunk_close(srv, con);
|
||||
}
|
||||
|
||||
fin = 1;
|
||||
break;
|
||||
default:
|
||||
|
@ -3357,21 +3347,15 @@ static handler_t fcgi_recv_response(server *srv, handler_ctx *hctx) {
|
|||
"response not received, request sent:", hctx->wb->bytes_out,
|
||||
"on socket:", proc->connection_name,
|
||||
"for", con->uri.path, "?", con->uri.query, ", closing connection");
|
||||
|
||||
fcgi_connection_close(srv, hctx);
|
||||
} else {
|
||||
/* response might have been already started, kill the connection */
|
||||
log_error_write(srv, __FILE__, __LINE__, "ssbsBSBs",
|
||||
"response already sent out, but backend returned error",
|
||||
"on socket:", proc->connection_name,
|
||||
"for", con->uri.path, "?", con->uri.query, ", terminating connection");
|
||||
|
||||
con->keep_alive = 0;
|
||||
con->file_finished = 1;
|
||||
con->mode = DIRECT; /*(avoid sending final chunked block)*/
|
||||
fcgi_connection_close(srv, hctx);
|
||||
}
|
||||
|
||||
http_response_backend_error(srv, con);
|
||||
fcgi_connection_close(srv, hctx);
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
|
||||
|
@ -3432,11 +3416,7 @@ static handler_t fcgi_handle_fdevent(server *srv, void *ctx, int revents) {
|
|||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"fcgi: got a FDEVENT_ERR. Don't know why.");
|
||||
|
||||
if (con->file_started) {
|
||||
con->keep_alive = 0;
|
||||
con->file_finished = 1;
|
||||
con->mode = DIRECT; /*(avoid sending final chunked block)*/
|
||||
}
|
||||
http_response_backend_error(srv, con);
|
||||
fcgi_connection_close(srv, hctx);
|
||||
}
|
||||
|
||||
|
|
|
@ -240,7 +240,6 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
|
|||
chunkqueue_reset(con->write_queue);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
http_chunk_close(srv, con);
|
||||
|
||||
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv"));
|
||||
|
||||
|
|
|
@ -742,13 +742,8 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
|
|||
}
|
||||
buffer_reset(hctx->response);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* reading from upstream done */
|
||||
con->file_finished = 1;
|
||||
|
||||
http_chunk_close(srv, con);
|
||||
|
||||
fin = 1;
|
||||
}
|
||||
|
||||
|
@ -1003,26 +998,14 @@ static handler_t proxy_recv_response(server *srv, handler_ctx *hctx) {
|
|||
switch (proxy_demux_response(srv, hctx)) {
|
||||
case 0:
|
||||
break;
|
||||
case -1:
|
||||
http_response_backend_error(srv, hctx->remote_conn);
|
||||
/* fall through */
|
||||
case 1:
|
||||
/* we are done */
|
||||
proxy_connection_close(srv, hctx);
|
||||
|
||||
return HANDLER_FINISHED;
|
||||
case -1: {
|
||||
connection *con = hctx->remote_conn;
|
||||
if (con->file_started == 0) {
|
||||
/* reading response headers failed */
|
||||
} else {
|
||||
/* response might have been already started, kill the connection */
|
||||
con->keep_alive = 0;
|
||||
con->file_finished = 1;
|
||||
con->mode = DIRECT; /*(avoid sending final chunked block)*/
|
||||
}
|
||||
|
||||
proxy_connection_close(srv, hctx);
|
||||
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
}
|
||||
|
||||
return HANDLER_GO_ON;
|
||||
|
@ -1135,11 +1118,7 @@ static handler_t proxy_handle_fdevent(server *srv, void *ctx, int revents) {
|
|||
} else if (revents & FDEVENT_ERR) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sd", "proxy-FDEVENT_ERR, but no HUP", revents);
|
||||
|
||||
if (con->file_started) {
|
||||
con->keep_alive = 0;
|
||||
con->file_finished = 1;
|
||||
con->mode = DIRECT; /*(avoid sending final chunked block)*/
|
||||
}
|
||||
http_response_backend_error(srv, con);
|
||||
proxy_connection_close(srv, hctx);
|
||||
}
|
||||
|
||||
|
|
|
@ -1869,12 +1869,6 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
|
|||
|
||||
if (n == 0) {
|
||||
/* read finished */
|
||||
|
||||
con->file_finished = 1;
|
||||
|
||||
/* send final chunk */
|
||||
http_chunk_close(srv, con);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2678,21 +2672,15 @@ static handler_t scgi_recv_response(server *srv, handler_ctx *hctx) {
|
|||
"response not sent, request sent:", hctx->wb->bytes_out,
|
||||
"connection-fd:", con->fd,
|
||||
"fcgi-fd:", hctx->fd);
|
||||
|
||||
scgi_connection_close(srv, hctx);
|
||||
} else {
|
||||
/* response might have been already started, kill the connection */
|
||||
log_error_write(srv, __FILE__, __LINE__, "ssdsd",
|
||||
"response already sent out, termination connection",
|
||||
"connection-fd:", con->fd,
|
||||
"fcgi-fd:", hctx->fd);
|
||||
|
||||
con->keep_alive = 0;
|
||||
con->file_finished = 1;
|
||||
con->mode = DIRECT; /*(avoid sending final chunked block)*/
|
||||
scgi_connection_close(srv, hctx);
|
||||
}
|
||||
|
||||
http_response_backend_error(srv, con);
|
||||
scgi_connection_close(srv, hctx);
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
}
|
||||
|
@ -2758,11 +2746,7 @@ static handler_t scgi_handle_fdevent(server *srv, void *ctx, int revents) {
|
|||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"fcgi: got a FDEVENT_ERR. Don't know why.");
|
||||
|
||||
if (con->file_started) {
|
||||
con->keep_alive = 0;
|
||||
con->file_finished = 1;
|
||||
con->mode = DIRECT; /*(avoid sending final chunked block)*/
|
||||
}
|
||||
http_response_backend_error(srv, con);
|
||||
scgi_connection_close(srv, hctx);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ int http_response_handle_cachable(server *srv, connection *con, buffer * mtime);
|
|||
void http_response_send_file (server *srv, connection *con, buffer *path);
|
||||
void http_response_xsendfile (server *srv, connection *con, buffer *path, const array *xdocroot);
|
||||
void http_response_backend_done (server *srv, connection *con);
|
||||
void http_response_backend_error (server *srv, connection *con);
|
||||
|
||||
buffer * strftime_cache_get(server *srv, time_t last_mod);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue