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.
This commit is contained in:
parent
9b8e2bdeb6
commit
eda2c150e4
1 changed files with 20 additions and 6 deletions
26
quark.c
26
quark.c
|
@ -73,6 +73,7 @@ enum status {
|
||||||
S_NOT_FOUND = 404,
|
S_NOT_FOUND = 404,
|
||||||
S_METHOD_NOT_ALLOWED = 405,
|
S_METHOD_NOT_ALLOWED = 405,
|
||||||
S_REQUEST_TIMEOUT = 408,
|
S_REQUEST_TIMEOUT = 408,
|
||||||
|
S_RANGE_NOT_SATISFIABLE = 416,
|
||||||
S_REQUEST_TOO_LARGE = 431,
|
S_REQUEST_TOO_LARGE = 431,
|
||||||
S_INTERNAL_SERVER_ERROR = 500,
|
S_INTERNAL_SERVER_ERROR = 500,
|
||||||
S_VERSION_NOT_SUPPORTED = 505,
|
S_VERSION_NOT_SUPPORTED = 505,
|
||||||
|
@ -88,6 +89,7 @@ static char *status_str[] = {
|
||||||
[S_NOT_FOUND] = "Not Found",
|
[S_NOT_FOUND] = "Not Found",
|
||||||
[S_METHOD_NOT_ALLOWED] = "Method Not Allowed",
|
[S_METHOD_NOT_ALLOWED] = "Method Not Allowed",
|
||||||
[S_REQUEST_TIMEOUT] = "Request Time-out",
|
[S_REQUEST_TIMEOUT] = "Request Time-out",
|
||||||
|
[S_RANGE_NOT_SATISFIABLE] = "Range Not Satisfiable",
|
||||||
[S_REQUEST_TOO_LARGE] = "Request Header Fields Too Large",
|
[S_REQUEST_TOO_LARGE] = "Request Header Fields Too Large",
|
||||||
[S_INTERNAL_SERVER_ERROR] = "Internal Server Error",
|
[S_INTERNAL_SERVER_ERROR] = "Internal Server Error",
|
||||||
[S_VERSION_NOT_SUPPORTED] = "HTTP Version not supported",
|
[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-Type: %s\r\n"
|
||||||
"Content-Length: %zu\r\n",
|
"Content-Length: %zu\r\n",
|
||||||
s, status_str[s], timestamp(0, t1),
|
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;
|
s = S_REQUEST_TIMEOUT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (range) {
|
if (range) {
|
||||||
if (dprintf(fd, "Content-Range: bytes %zu-%zu/%zu\r\n",
|
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;
|
s = S_REQUEST_TIMEOUT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -666,10 +668,22 @@ sendresponse(int fd, struct request *r)
|
||||||
upper = atoi(q);
|
upper = atoi(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sanitize range */
|
/* check range */
|
||||||
upper = MIN(st.st_size, upper);
|
if (lower < 0 || upper < 0 || lower > upper ||
|
||||||
if (lower < 0 || upper < 0 || lower > upper) {
|
upper >= st.st_size) {
|
||||||
return sendstatus(fd, S_BAD_REQUEST);
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue