diff options
context:
space:
mode:
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
End a request quietly when the client has gone
A write that failed with EPIPE on an uncached page died into an error page, which died again at exit when the page could not be sent either, and git logged a recursion warning on every dropped connection. A filter that exits early fails a write the same way, so the quiet exit is kept for writes that reach the client itself.
Diffstat (limited to 'source/html.c')
-rw-r--r--source/html.c20
1 file changed, 18 insertions, 2 deletions
diff --git a/source/html.c b/source/html.c
index 96b1b52..caa5a29 100644
--- a/source/html.c
+++ b/source/html.c
@@ -10,6 +10,7 @@
#include "cgit.h"
#include "cache.h"
+#include "filter.h"
#include "html.h"
#define HTML_WRITE_BUFSIZE (64 * 1024)
@@ -57,6 +58,8 @@ static struct strbuf *capture;
static void write_out(const char *data, size_t size)
{
+ int err;
+
// A blob or snapshot is well past what one write can move onto a
// pipe, so short writes are resumed rather than reported.
while (size) {
@@ -69,12 +72,25 @@ static void write_out(const char *data, size_t size)
}
if (!size)
return;
+ err = errno;
// While a cache slot is being filled stdout is a file, and a full disk
// must not cost the visitor the page. Abandoning the fill puts stdout
// back on the client along with what the file already holds, so only
// the rest is written again.
- if (!cache_abandon_fill() || write_in_full(STDOUT_FILENO, data, size) < 0)
- die_errno("Unable to write the page");
+ if (cache_abandon_fill()) {
+ if (write_in_full(STDOUT_FILENO, data, size) < 0)
+ die_errno("Unable to write the page");
+ return;
+ }
+ // A client that has gone away fails the write with EPIPE and leaves
+ // nobody to read an error page, so the request ends quietly. A filter
+ // that exited early fails it the same way, and that page has a reader.
+ if (err == EPIPE && !cgit_filter_holds_stdout()) {
+ html_discard();
+ exit(0);
+ }
+ errno = err;
+ die_errno("Unable to write the page");
}
/*