in net/http/server.cpp [194:251]
int handle_request(Request &req, Response &resp, std::string_view prefix) override {
LOG_DEBUG("enter fs handler");
DEFER(LOG_DEBUG("leave fs handler"));
auto target = req.target();
auto pos = target.find("?");
estring_view query;
if (pos != std::string_view::npos) {
query = target.substr(pos + 1);
target = target.substr(0, pos);
}
estring_view filename(target);
if (!prefix.empty())
filename = filename.substr(prefix.size() - 1);
LOG_DEBUG(VALUE(filename));
auto file = m_fs->open(filename.extract_c_str(), O_RDONLY);
if (!file) {
failed_resp(resp);
LOG_ERROR_RETURN(0, 0, "open file ` failed", target);
}
DEFER(delete file);
if (!query.empty())
file->ioctl(fs::HTTP_URL_PARAM, (const char*) query.extract_c_str());
struct stat buf;
if (file->fstat(&buf) < 0) {
failed_resp(resp);
LOG_ERROR_RETURN(0, 0, "stat file ` failed", target);
}
auto file_end_pos = buf.st_size - 1;
auto range = req.headers.range();
if (range.first < 0) {
range.first = file_end_pos - range.second;
range.second = file_end_pos;
}
if (range.second < 0 || range.second > file_end_pos) {
range.second = file_end_pos;
}
if (buf.st_size > 0 &&
(range.second < range.first || range.first > file_end_pos)) {
failed_resp(resp, 416);
LOG_ERROR_RETURN(0, 0, "invalid request range ", target);
}
auto req_size = range.second - range.first + 1;
if (req_size == buf.st_size)
resp.set_result(200);
else {
resp.set_result(206);
resp.headers.content_range(range.first, range.second, buf.st_size);
}
resp.headers.content_length(req_size);
if (req.verb() == Verb::HEAD)
return 0;
file->lseek(range.first, SEEK_SET);
return resp.write_stream(&*file, req_size);
}