Commit ba213346 by ziyue

http文件服务器mmap方案采用共享方式

parent 72caa43c
......@@ -104,32 +104,32 @@ private:
/**
* 文件类型的content
*/
class HttpFileBody : public HttpBody{
class HttpFileBody : public HttpBody {
public:
typedef std::shared_ptr<HttpFileBody> Ptr;
/**
* 构造函数
* @param fp 文件句柄,文件的偏移量必须为0
* @param offset 相对文件头的偏移量
* @param max_size 最大读取字节数,未判断是否大于文件真实大小
* @param file_path 文件路径
* @param use_mmap 是否使用mmap方式访问文件
*/
HttpFileBody(const std::shared_ptr<FILE> &fp, size_t offset, size_t max_size, bool use_mmap = true);
HttpFileBody(const std::string &file_path, bool use_mmap = true);
~HttpFileBody() override = default;
ssize_t remainSize() override ;
/**
* 设置读取范围
* @param offset 相对文件头的偏移量
* @param max_size 最大读取字节数
*/
void setRange(uint64_t offset, uint64_t max_size);
ssize_t remainSize() override;
toolkit::Buffer::Ptr readData(size_t size) override;
int sendFile(int fd) override;
private:
void init(const std::shared_ptr<FILE> &fp,size_t offset,size_t max_size, bool use_mmap);
private:
size_t _max_size;
size_t _offset = 0;
size_t _file_offset = 0;
int64_t _read_to = 0;
uint64_t _file_offset = 0;
std::shared_ptr<FILE> _fp;
std::shared_ptr<char> _map_addr;
toolkit::ResourcePool<toolkit::BufferRaw> _pool;
......
......@@ -582,13 +582,8 @@ void HttpResponseInvokerImp::responseFile(const StrCaseMap &requestHeader,
const string &filePath,
bool use_mmap) const {
StrCaseMap &httpHeader = const_cast<StrCaseMap &>(responseHeader);
std::shared_ptr<FILE> fp(fopen(filePath.data(), "rb"), [](FILE *fp) {
if (fp) {
fclose(fp);
}
});
if (!fp) {
auto fileBody = std::make_shared<HttpFileBody>(filePath, use_mmap);
if (fileBody->remainSize() < 0) {
//打开文件失败
GET_CONFIG(string, notFound, Http::kNotFound);
GET_CONFIG(string, charSet, Http::kCharSet);
......@@ -600,29 +595,23 @@ void HttpResponseInvokerImp::responseFile(const StrCaseMap &requestHeader,
}
auto &strRange = const_cast<StrCaseMap &>(requestHeader)["Range"];
size_t iRangeStart = 0;
size_t iRangeEnd = 0;
size_t fileSize = File::fileSize(fp.get());
int code;
if (strRange.size() == 0) {
//全部下载
code = 200;
iRangeEnd = fileSize - 1;
} else {
int code = 200;
if (!strRange.empty()) {
//分节下载
code = 206;
iRangeStart = atoll(FindField(strRange.data(), "bytes=", "-").data());
iRangeEnd = atoll(FindField(strRange.data(), "-", nullptr).data());
auto iRangeStart = atoll(FindField(strRange.data(), "bytes=", "-").data());
auto iRangeEnd = atoll(FindField(strRange.data(), "-", nullptr).data());
auto fileSize = fileBody->remainSize();
if (iRangeEnd == 0) {
iRangeEnd = fileSize - 1;
}
//设置文件范围
fileBody->setRange(iRangeStart, iRangeEnd - iRangeStart + 1);
//分节下载返回Content-Range头
httpHeader.emplace("Content-Range", StrPrinter << "bytes " << iRangeStart << "-" << iRangeEnd << "/" << fileSize << endl);
}
//回复文件
HttpBody::Ptr fileBody = std::make_shared<HttpFileBody>(fp, iRangeStart, iRangeEnd - iRangeStart + 1, use_mmap);
(*this)(code, httpHeader, fileBody);
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论