diff options
author | Sokolov Yura aka funny_falcon <funny.falcon@gmail.com> | 2016-04-06 21:11:10 +0300 |
---|---|---|
committer | Sokolov Yura aka funny_falcon <funny.falcon@gmail.com> | 2016-04-06 21:11:10 +0300 |
commit | 6d1535f910d188c07289ab7ddee5df9d4b85d462 (patch) | |
tree | 9a940df187799066474f594fc122a3a369c4f5ed /core/static.c | |
parent | 122be0e224fcc04f3d2d51398eebcd1f3094ae8b (diff) | |
download | uwsgi-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.c | 41 |
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; } |