diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce 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 '')
| -rw-r--r-- | source/html.c | 20 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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"); } /* |
