-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
range_error function always return true! #1946
Comments
@bobhyun thanks for the report. Could you show me your code calling |
It is not called directly. This call is made by nginx.
flowchart LR
browser-->|GET /storage/x/0/0/0/0/721.mp4|nginx-->|GET /api/auth|myapp
nginx-->|static resources|/storage/x/0/0/0/0/721.mp4
http {
server {
listen 80;
location / {
root "/var/wwwroot";
index index.html;
add_header 'Access-Control-Allow-Origin' '*';
}
location ~* ^/api(.*$) {
proxy_set_header X-Original-URI $request_uri;
proxy_pass http://127.0.0.1:65530;
proxy_set_header X-Remote $remote_addr;
proxy_set_header X-Host $http_host;
proxy_set_header Authorization $http_authorization;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; # this makes Range header
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
# Preflighted requests
if ($request_method = OPTIONS) {
return 204;
}
}
}
# static resources
location /storage {
# authentication is required before accessing the resources
# this makes call my app using cpp-httplib
auth_request /api/auth;
proxy_set_header X-Remote $remote_addr;
proxy_set_header X-Host $http_host;
proxy_set_header Authorization $http_authorization;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
# Preflighted requests
if ($request_method = OPTIONS) {
return 204;
}
location ~ (\/storage\/)(.*)\.(mp4|mov)$ {
alias /videos$2;
}
}
}
inline bool range_error(Request &req, Response &res) {
if (!req.ranges.empty() && 200 <= res.status && res.status < 300) {
ssize_t contant_len = static_cast<ssize_t>(
res.content_length_ ? res.content_length_ : res.body.size());
ssize_t prev_first_pos = -1;
ssize_t prev_last_pos = -1;
size_t overwrapping_count = 0;
// NOTE: The following Range check is based on '14.2. Range' in RFC 9110
// 'HTTP Semantics' to avoid potential denial-of-service attacks.
// https://www.rfc-editor.org/rfc/rfc9110#section-14.2
// Too many ranges
if (req.ranges.size() > CPPHTTPLIB_RANGE_MAX_COUNT) { return true; }
for (auto &r : req.ranges) {
auto &first_pos = r.first;
auto &last_pos = r.second;
if (first_pos == -1 && last_pos == -1) {
first_pos = 0;
last_pos = contant_len;
}
if (first_pos == -1) {
first_pos = contant_len - last_pos;
last_pos = contant_len - 1;
}
if (last_pos == -1) { last_pos = contant_len - 1; }
// Range must be within content length
if (!(0 <= first_pos && first_pos <= last_pos &&
last_pos <= contant_len - 1)) {
return true;
}
// Ranges must be in ascending order
if (prev_first_pos != -1 && // Fixed: checking initial value
first_pos <= prev_first_pos) { return true; }
// Request must not have more than two overlapping ranges
if (prev_last_pos != -1 && // Fixed: checking initial value
first_pos <= prev_last_pos) {
overwrapping_count++;
if (overwrapping_count > 2) { return true; }
}
// Fixed: checking initial values
prev_first_pos = (prev_first_pos == -1) ? first_pos : (std::max)(prev_first_pos, first_pos);
prev_last_pos = (prev_last_pos == -1) ? last_pos : (std::max)(prev_last_pos, last_pos);
}
}
return false;
} Please check. |
@bobhyun thanks for the details.
If you already have a fix for this issue, could you send a pull request? Thanks! |
Ok , I sent PR, pls confirm. |
@bobhyun could you explain why your They should be Also I added a unit test for this issue, and the current httplib.h has no problem on Windows, Mac and Ubuntu. Lines 3703 to 3711 in 10d68cf
|
If there's Range in the Request header, it always failed with 416 status.
In my case, using Visual Studio 2022 C++, the value -1 is the same as SIZE_MAX
in
range_error
function,ssize_t prev_first_pos = -1;
ssize_t prev_last_pos = -1;
The comparision with these values always be the same or less.
The text was updated successfully, but these errors were encountered: