开源 企业版 高校版 私有云 模力方舟 AI 队友
代码拉取完成,页面将自动刷新
forked from libhv/libhv
加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
已有帐号? 立即登录
文件
master
分支 (6)
标签 (13)
master
dev
kcptun
tfb
check_unicode
annotate
v1.3.3
v1.3.2
v1.3.1
v1.3.0
v1.2.6
v1.2.5
v1.2.4
v1.2.3
v1.2.2
v1.2.1
v1.1.1
v1.1.0
v1.0.0
master
分支 (6)
标签 (13)
master
dev
kcptun
tfb
check_unicode
annotate
v1.3.3
v1.3.2
v1.3.1
v1.3.0
v1.2.6
v1.2.5
v1.2.4
v1.2.3
v1.2.2
v1.2.1
v1.1.1
v1.1.0
v1.0.0
克隆/下载
克隆/下载
提示
下载代码请复制以下命令到终端执行
为确保你提交的代码身份被 Gitee 正确识别,请执行以下命令完成配置
初次使用 SSH 协议进行代码克隆、推送等操作时,需按下述提示完成 SSH 配置
1 生成 RSA 密钥
2 获取 RSA 公钥内容,并配置到 SSH公钥
在 Gitee 上使用 SVN,请访问 使用指南
使用 HTTPS 协议时,命令行会出现如下账号密码验证步骤。基于安全考虑,Gitee 建议 配置并使用私人令牌 替代登录密码进行克隆、推送等操作
Username for 'https://gitee.com': userName
Password for 'https://userName@gitee.com': # 私人令牌
master
分支 (6)
标签 (13)
master
dev
kcptun
tfb
check_unicode
annotate
v1.3.3
v1.3.2
v1.3.1
v1.3.0
v1.2.6
v1.2.5
v1.2.4
v1.2.3
v1.2.2
v1.2.1
v1.1.1
v1.1.0
v1.0.0
libhv
/
http
/
server
/
FileCache.cpp
libhv
/
http
/
server
/
FileCache.cpp
FileCache.cpp 5.27 KB
一键复制 编辑 原始数据 按行查看 历史
ithewei 提交于 2024年06月26日 22:16 +08:00 . fix mingw compile error
#include "FileCache.h"
#include "herr.h"
#include "hscope.h"
#include "htime.h"
#include "hlog.h"
#include "httpdef.h" // import http_content_type_str_by_suffix
#include "http_page.h" // import make_index_of_page
#ifdef _MSC_VER
#include <codecvt>
#endif
#define ETAG_FMT "\"%zx-%zx\""
FileCache::FileCache() {
stat_interval = 10; // s
expired_time = 60; // s
}
static int hv_open(char const* filepath, int flags) {
#ifdef _MSC_VER
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv;
auto wfilepath = conv.from_bytes(filepath);
int fd = _wopen(wfilepath.c_str(), flags);
#else
int fd = open(filepath, flags);
#endif
return fd;
}
file_cache_ptr FileCache::Open(const char* filepath, OpenParam* param) {
std::lock_guard<std::mutex> locker(mutex_);
file_cache_ptr fc = Get(filepath);
bool modified = false;
if (fc) {
time_t now = time(NULL);
if (now - fc->stat_time > stat_interval) {
modified = fc->is_modified();
fc->stat_time = now;
fc->stat_cnt++;
}
if (param->need_read) {
if (!modified && fc->is_complete()) {
param->need_read = false;
}
}
}
if (fc == NULL || modified || param->need_read) {
int flags = O_RDONLY;
#ifdef O_BINARY
flags |= O_BINARY;
#endif
int fd = hv_open(filepath, flags);
if (fd < 0) {
#ifdef OS_WIN
// NOTE: open(dir) return -1 on windows
if (!hv_isdir(filepath)) {
param->error = ERR_OPEN_FILE;
return NULL;
}
#else
param->error = ERR_OPEN_FILE;
return NULL;
#endif
}
defer(if (fd > 0) { close(fd); })
if (fc == NULL) {
struct stat st;
if (fd > 0) {
fstat(fd, &st);
} else {
stat(filepath, &st);
}
if (S_ISREG(st.st_mode) ||
(S_ISDIR(st.st_mode) &&
filepath[strlen(filepath)-1] == '/')) {
fc = std::make_shared<file_cache_t>();
fc->filepath = filepath;
fc->st = st;
time(&fc->open_time);
fc->stat_time = fc->open_time;
fc->stat_cnt = 1;
cached_files[filepath] = fc;
}
else {
param->error = ERR_MISMATCH;
return NULL;
}
}
if (S_ISREG(fc->st.st_mode)) {
param->filesize = fc->st.st_size;
// FILE
if (param->need_read) {
if (fc->st.st_size > param->max_read) {
param->error = ERR_OVER_LIMIT;
return NULL;
}
fc->resize_buf(fc->st.st_size);
int nread = read(fd, fc->filebuf.base, fc->filebuf.len);
if (nread != fc->filebuf.len) {
hloge("Failed to read file: %s", filepath);
param->error = ERR_READ_FILE;
return NULL;
}
}
const char* suffix = strrchr(filepath, '.');
if (suffix) {
http_content_type content_type = http_content_type_enum_by_suffix(suffix+1);
if (content_type == TEXT_HTML) {
fc->content_type = "text/html; charset=utf-8";
} else if (content_type == TEXT_PLAIN) {
fc->content_type = "text/plain; charset=utf-8";
} else {
fc->content_type = http_content_type_str_by_suffix(suffix+1);
}
}
}
else if (S_ISDIR(fc->st.st_mode)) {
// DIR
std::string page;
make_index_of_page(filepath, page, param->path);
fc->resize_buf(page.size());
memcpy(fc->filebuf.base, page.c_str(), page.size());
fc->content_type = "text/html; charset=utf-8";
}
gmtime_fmt(fc->st.st_mtime, fc->last_modified);
snprintf(fc->etag, sizeof(fc->etag), ETAG_FMT, (size_t)fc->st.st_mtime, (size_t)fc->st.st_size);
}
return fc;
}
bool FileCache::Close(const char* filepath) {
std::lock_guard<std::mutex> locker(mutex_);
auto iter = cached_files.find(filepath);
if (iter != cached_files.end()) {
iter = cached_files.erase(iter);
return true;
}
return false;
}
bool FileCache::Close(const file_cache_ptr& fc) {
std::lock_guard<std::mutex> locker(mutex_);
auto iter = cached_files.begin();
while (iter != cached_files.end()) {
if (iter->second == fc) {
iter = cached_files.erase(iter);
return true;
} else {
++iter;
}
}
return false;
}
file_cache_ptr FileCache::Get(const char* filepath) {
auto iter = cached_files.find(filepath);
if (iter != cached_files.end()) {
return iter->second;
}
return NULL;
}
void FileCache::RemoveExpiredFileCache() {
std::lock_guard<std::mutex> locker(mutex_);
time_t now = time(NULL);
auto iter = cached_files.begin();
while (iter != cached_files.end()) {
if (now - iter->second->stat_time > expired_time) {
iter = cached_files.erase(iter);
} else {
++iter;
}
}
}
Loading...
举报
举报成功
我们将于2个工作日内通过站内信反馈结果给你!
请认真填写举报原因,尽可能描述详细。
请选择举报类型
取消
发送
误判申诉

此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。

如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。

取消
提交

简介

🔥 比libevent/libuv/asio更易用的国产网络库,用来开发 TCP/UDP/SSL/HTTP/WebSocket/MQTT 客户端/服务端
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
编辑仓库简介
简介内容
主页
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/cppprojects/libhv.git
git@gitee.com:cppprojects/libhv.git
cppprojects
libhv
libhv
master
点此查找更多帮助

搜索帮助

评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册

AltStyle によって変換されたページ (->オリジナル) /