quark

quark web server
git clone git://git.suckless.org/quark
Log | Files | Refs | LICENSE

commit eda2c150e43c6c44f42b118dca835af65d1540ba
parent 9b8e2bdeb6abe8b42818ad2c9e4e118b09474261
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Tue,  4 Jul 2017 21:27:20 +0200

improve byte-range support

this fixes the lower and upper offset and adds a 416 (range not satisfiable
status). It returns the filesize if it cannot be satisfied as the standard
suggests so the client can do something.

Diffstat:
quark.c | 26++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/quark.c b/quark.c @@ -73,6 +73,7 @@ enum status { S_NOT_FOUND = 404, S_METHOD_NOT_ALLOWED = 405, S_REQUEST_TIMEOUT = 408, + S_RANGE_NOT_SATISFIABLE = 416, S_REQUEST_TOO_LARGE = 431, S_INTERNAL_SERVER_ERROR = 500, S_VERSION_NOT_SUPPORTED = 505, @@ -88,6 +89,7 @@ static char *status_str[] = { [S_NOT_FOUND] = "Not Found", [S_METHOD_NOT_ALLOWED] = "Method Not Allowed", [S_REQUEST_TIMEOUT] = "Request Time-out", + [S_RANGE_NOT_SATISFIABLE] = "Range Not Satisfiable", [S_REQUEST_TOO_LARGE] = "Request Header Fields Too Large", [S_INTERNAL_SERVER_ERROR] = "Internal Server Error", [S_VERSION_NOT_SUPPORTED] = "HTTP Version not supported", @@ -441,13 +443,13 @@ sendfile(int fd, char *name, struct request *r, struct stat *st, char *mime, "Content-Type: %s\r\n" "Content-Length: %zu\r\n", s, status_str[s], timestamp(0, t1), - timestamp(st->st_mtim.tv_sec, t2), mime, upper - lower) < 0) { + timestamp(st->st_mtim.tv_sec, t2), mime, upper - lower + 1) < 0) { s = S_REQUEST_TIMEOUT; goto cleanup; } if (range) { if (dprintf(fd, "Content-Range: bytes %zu-%zu/%zu\r\n", - lower, upper - 1, st->st_size) < 0) { + lower, upper, st->st_size) < 0) { s = S_REQUEST_TIMEOUT; goto cleanup; } @@ -666,10 +668,22 @@ sendresponse(int fd, struct request *r) upper = atoi(q); } - /* sanitize range */ - upper = MIN(st.st_size, upper); - if (lower < 0 || upper < 0 || lower > upper) { - return sendstatus(fd, S_BAD_REQUEST); + /* check range */ + if (lower < 0 || upper < 0 || lower > upper || + upper >= st.st_size) { + if (dprintf(fd, + "HTTP/1.1 %d %s\r\n" + "Date: %s\r\n" + "Content-Range: bytes */%zu\r\n" + "Connection: close\r\n" + "\r\n", + S_RANGE_NOT_SATISFIABLE, + status_str[S_RANGE_NOT_SATISFIABLE], + timestamp(0, t), + st.st_size) < 0) { + return S_REQUEST_TIMEOUT; + } + return S_RANGE_NOT_SATISFIABLE; } }