summaryrefslogtreecommitdiff
path: root/core/static.c
diff options
context:
space:
mode:
authorSokolov Yura aka funny_falcon <funny.falcon@gmail.com>2016-04-06 21:11:10 +0300
committerSokolov Yura aka funny_falcon <funny.falcon@gmail.com>2016-04-06 21:11:10 +0300
commit6d1535f910d188c07289ab7ddee5df9d4b85d462 (patch)
tree9a940df187799066474f594fc122a3a369c4f5ed /core/static.c
parent122be0e224fcc04f3d2d51398eebcd1f3094ae8b (diff)
downloaduwsgi-6d1535f910d188c07289ab7ddee5df9d4b85d462.tar.gz
improve handling http byte range requests
refactor to make range fixing algorithm reusable. add flag field for parsed/not parsed/valid/invalid state of range header. properly handle suffix-range request. send 416 when range is not satisfable.
Diffstat (limited to 'core/static.c')
-rw-r--r--core/static.c41
1 files changed, 19 insertions, 22 deletions
diff --git a/core/static.c b/core/static.c
index 1ba0f2f3..fb426f07 100644
--- a/core/static.c
+++ b/core/static.c
@@ -439,6 +439,11 @@ static int uwsgi_static_stat(struct wsgi_request *wsgi_req, char *filename, size
return -1;
}
+void uwsgi_request_fix_range_for_size(struct wsgi_request *wsgi_req, int64_t size) {
+ uwsgi_fix_range_for_size(&wsgi_req->range_parsed,
+ &wsgi_req->range_from, &wsgi_req->range_to, size);
+}
+
int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, size_t real_filename_len, struct stat *st) {
size_t mime_type_size = 0;
@@ -465,28 +470,20 @@ int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, si
// static file - don't update avg_rt after request
wsgi_req->do_not_account_avg_rt = 1;
- size_t fsize = st->st_size;
- // security check
- if (wsgi_req->range_from > fsize) {
- wsgi_req->range_from = 0;
- wsgi_req->range_to = 0;
- }
- else {
- fsize -= wsgi_req->range_from;
- }
-
- if (wsgi_req->range_to) {
- fsize = (wsgi_req->range_to - wsgi_req->range_from)+1;
- if (fsize + wsgi_req->range_from > (size_t) (st->st_size)) {
- fsize = st->st_size - wsgi_req->range_from;
- }
- }
-
- // HTTP status
- if (fsize > 0 && (wsgi_req->range_from || wsgi_req->range_to)) {
+ int64_t fsize = (int64_t)st->st_size;
+ uwsgi_request_fix_range_for_size(wsgi_req, fsize);
+ switch (wsgi_req->range_parsed) {
+ case UWSGI_RANGE_INVALID:
+ if (uwsgi_response_prepare_headers(wsgi_req,
+ "416 Requested Range Not Satisfiable", 35))
+ return -1;
+ if (uwsgi_response_add_content_range(wsgi_req, -1, -1, st->st_size)) return -1;
+ return 0;
+ case UWSGI_RANGE_VALID:
+ fsize = wsgi_req->range_to - wsgi_req->range_from + 1;
if (uwsgi_response_prepare_headers(wsgi_req, "206 Partial Content", 19)) return -1;
- }
- else {
+ break;
+ default: /* UWSGI_RANGE_NOT_PARSED */
if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) return -1;
}
@@ -528,7 +525,7 @@ int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, si
else {
// set Content-Length (to fsize NOT st->st_size)
if (uwsgi_response_add_content_length(wsgi_req, fsize)) return -1;
- if (fsize > 0 && (wsgi_req->range_from || wsgi_req->range_to)) {
+ if (wsgi_req->range_parsed == UWSGI_RANGE_VALID) {
// here use the original size !!!
if (uwsgi_response_add_content_range(wsgi_req, wsgi_req->range_from, wsgi_req->range_to, st->st_size)) return -1;
}