Browse Source

[core] limit num ranges in Range requests

parse Range header prior to constructing ranged response
master
Glenn Strauss 8 months ago
parent
commit
55e9f082a9
  1. 32
      src/http-header-glue.c

32
src/http-header-glue.c

@ -331,7 +331,7 @@ handler_t http_response_reqbody_read_error (request_st * const r, int http_statu
static int http_response_parse_range(request_st * const r, buffer * const path, stat_cache_entry * const sce, const char * const range) {
int multipart = 0;
int n = 0;
int error;
off_t start, end;
const char *s, *minus;
@ -339,6 +339,7 @@ static int http_response_parse_range(request_st * const r, buffer * const path,
const buffer *content_type =
http_header_response_get(r, HTTP_HEADER_CONTENT_TYPE,
CONST_STR_LEN("Content-Type"));
off_t ranges[16];
start = 0;
end = sce->st.st_size - 1;
@ -383,7 +384,6 @@ static int http_response_parse_range(request_st * const r, buffer * const path,
end = sce->st.st_size - 1;
start = sce->st.st_size + le;
} else if (*err == ',') {
multipart = 1;
s = err + 1;
end = sce->st.st_size - 1;
@ -404,7 +404,6 @@ static int http_response_parse_range(request_st * const r, buffer * const path,
start = la;
} else if (*(err + 1) == ',') {
multipart = 1;
s = err + 2;
end = sce->st.st_size - 1;
@ -429,7 +428,6 @@ static int http_response_parse_range(request_st * const r, buffer * const path,
end = le;
start = la;
} else if (*err == ',') {
multipart = 1;
s = err + 1;
end = le;
@ -455,7 +453,25 @@ static int http_response_parse_range(request_st * const r, buffer * const path,
}
if (!error) {
if (multipart) {
if (n < (int)(sizeof(ranges)/sizeof(*ranges))) {
ranges[n] = start;
ranges[n+1] = end;
n += 2;
}
else { /* excessive num ranges in request */
error = 1;
r->http_status = 416;
}
}
}
/* something went wrong */
if (error) return -1;
for (int i = 0; i < n; i += 2) {
start = ranges[i];
end = ranges[i+1];
if (n > 2) {
/* write boundary-header */
buffer *b = r->tmp_buf;
buffer_copy_string_len(b, CONST_STR_LEN("\r\n--"));
@ -483,15 +499,11 @@ static int http_response_parse_range(request_st * const r, buffer * const path,
chunkqueue_append_file(&r->write_queue, path, start, end - start + 1);
r->content_length += end - start + 1;
}
}
/* something went wrong */
if (error) return -1;
buffer * const tb = r->tmp_buf;
if (multipart) {
if (n > 2) {
/* add boundary end */
buffer_copy_string_len(tb, "\r\n--", 4);
buffer_append_string_len(tb, boundary, sizeof(boundary)-1);

Loading…
Cancel
Save