From 193f358a192419466a04766a993921703e965df7 Mon Sep 17 00:00:00 2001 From: op Date: Thu, 11 Aug 2022 14:25:22 +0000 Subject: [PATCH] correctly handle an abnormal fastcgi termination. httpd handles the disconnection from the fastcgi application via server_file_error which assumes that the reply was completey done. However, if the fastcgi reply wasn't complete (e.g. because slowcgi hit the timeout) the HTTP client are left "hanging" and waiting for a reply until they give up. This adds a server_fcgi_error callback to handle the "no headers" and "incomplete data" cases and properly close the reply before falling back to server_file_error. OK claudio@ --- usr.sbin/httpd/server_fcgi.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/usr.sbin/httpd/server_fcgi.c b/usr.sbin/httpd/server_fcgi.c index 381fade2924..c0f6ed505c9 100644 --- a/usr.sbin/httpd/server_fcgi.c +++ b/usr.sbin/httpd/server_fcgi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_fcgi.c,v 1.90 2022/03/02 11:10:43 florian Exp $ */ +/* $OpenBSD: server_fcgi.c,v 1.91 2022/08/11 14:25:22 op Exp $ */ /* * Copyright (c) 2014 Florian Obser @@ -77,6 +77,7 @@ struct server_fcgi_param { }; int server_fcgi_header(struct client *, unsigned int); +void server_fcgi_error(struct bufferevent *, short, void *); void server_fcgi_read(struct bufferevent *, void *); int server_fcgi_writeheader(struct client *, struct kv *, void *); int server_fcgi_writechunk(struct client *); @@ -133,7 +134,7 @@ server_fcgi(struct httpd *env, struct client *clt) clt->clt_srvbev_throttled = 0; clt->clt_srvbev = bufferevent_new(fd, server_fcgi_read, - NULL, server_file_error, clt); + NULL, server_fcgi_error, clt); if (clt->clt_srvbev == NULL) { errstr = "failed to allocate fcgi buffer event"; goto fail; @@ -481,6 +482,23 @@ fcgi_add_param(struct server_fcgi_param *p, const char *key, return (0); } +void +server_fcgi_error(struct bufferevent *bev, short error, void *arg) +{ + struct client *clt = arg; + + if ((error & EVBUFFER_EOF) && !clt->clt_fcgi.headersdone) { + server_abort_http(clt, 500, "malformed or no headers"); + return; + } + + /* send the end marker if not already */ + if (clt->clt_fcgi.chunked && !clt->clt_fcgi.end++) + server_bufferevent_print(clt, "0\r\n\r\n"); + + server_file_error(bev, error, arg); +} + void server_fcgi_read(struct bufferevent *bev, void *arg) { -- 2.20.1