1、修复大文件LONG长度不够的问题;2、修复大文件导致未发送缓冲区超出的问题
This commit is contained in:
@@ -32,7 +32,7 @@ namespace ylib
|
||||
ylib::json sjson;
|
||||
private:
|
||||
bool filecache(const uint64& last_modify_time);
|
||||
bool fileoffset(long filesize, long& start, long& len);
|
||||
bool fileoffset(long long filesize, long long& start, long long& len);
|
||||
private:
|
||||
std::map<std::string, std::string> m_headers;
|
||||
bool m_response = false;
|
||||
|
||||
@@ -136,20 +136,25 @@ bool ylib::network::http::response::send(const ylib::json& json, ushort stateNum
|
||||
|
||||
bool ylib::network::http::response::send_file(const std::string& filepath, int32 downbaud, ushort stateNum, const std::string& stateDesc)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
std::string filepath2;
|
||||
filepath2.append(filepath);
|
||||
if(m_response == true)
|
||||
return false;
|
||||
|
||||
long filesize = 0;
|
||||
long long filesize = 0;
|
||||
time_t last_modify_time = 0;
|
||||
|
||||
//ylib::log->info(filepath2,"response");
|
||||
//取文件信息
|
||||
{
|
||||
struct stat statbuf;
|
||||
if (stat(filepath2.c_str(), &statbuf) != 0)
|
||||
struct _stat64 statbuf;
|
||||
if (_stat64(filepath2.c_str(), &statbuf) != 0)
|
||||
return false;
|
||||
|
||||
filesize = statbuf.st_size;
|
||||
last_modify_time = statbuf.st_mtime;
|
||||
}
|
||||
@@ -192,13 +197,13 @@ bool ylib::network::http::response::send_file(const std::string& filepath, int32
|
||||
ylib::buffer send_data;
|
||||
|
||||
//计算断点续传
|
||||
long start = 0, len = 0;
|
||||
long long start = 0, len = 0;
|
||||
if(direct_send == false){
|
||||
if (fileoffset(filesize, start, len))
|
||||
stateNum = 206;
|
||||
if (m_headers.find("Transfer-Encoding") == m_headers.end())
|
||||
{
|
||||
HEADER_SET("Content-Length", std::to_string((uint64)len));
|
||||
HEADER_SET("Content-Length", std::to_string(len));
|
||||
}
|
||||
|
||||
}else{
|
||||
@@ -247,7 +252,7 @@ bool ylib::network::http::response::send_file(const std::string& filepath, int32
|
||||
|
||||
/***************计算发送文件**************/
|
||||
//读取块大小
|
||||
long blocksize = 0;
|
||||
long long blocksize = 0;
|
||||
|
||||
if (downbaud == -1)
|
||||
blocksize = 4096;
|
||||
@@ -260,44 +265,84 @@ bool ylib::network::http::response::send_file(const std::string& filepath, int32
|
||||
}
|
||||
if (blocksize > len)
|
||||
blocksize = len;
|
||||
// ==== 修复后版本,支持大文件 / 中文路径 / 跨平台 ====
|
||||
FILE* pFile = nullptr;
|
||||
|
||||
#ifdef _WIN32
|
||||
fopen_s(&pFile, filepath2.c_str(), "rb");
|
||||
// Windows: 使用宽字符接口,支持中文路径
|
||||
std::wstring wpath(filepath2.begin(), filepath2.end());
|
||||
_wfopen_s(&pFile, wpath.c_str(), L"rb");
|
||||
#else
|
||||
// Linux/macOS: 直接使用 fopen
|
||||
pFile = fopen(filepath2.c_str(), "rb");
|
||||
#endif
|
||||
if (pFile == NULL)
|
||||
|
||||
if (pFile == nullptr)
|
||||
return false;
|
||||
fseek(pFile, start, SEEK_SET);
|
||||
#ifdef _WIN32
|
||||
if (_fseeki64(pFile, start, SEEK_SET) != 0)
|
||||
#else
|
||||
if (fseeko(pFile, start, SEEK_SET) != 0)
|
||||
#endif
|
||||
{
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char* read_buffer = new char[blocksize];
|
||||
size_t readlen = 0;
|
||||
timestamp begin_sec = time::now_sec();
|
||||
long read_size = 0;
|
||||
|
||||
long long read_size = 0;
|
||||
int ipending_count = 0;
|
||||
int ipending_detect_loop = 0;
|
||||
while ((readlen = fread(read_buffer, 1, blocksize, pFile)) > 0)
|
||||
{
|
||||
read_size += blocksize;
|
||||
if (HPSERVER->Send((CONNID)m_reqpack->connid(), (const BYTE*)read_buffer, (int)readlen, 0) == false)
|
||||
read_size += readlen;
|
||||
|
||||
if (!HPSERVER->Send((CONNID)m_reqpack->connid(),
|
||||
(const BYTE*)read_buffer,
|
||||
(int)readlen, 0))
|
||||
{
|
||||
fclose(pFile);
|
||||
delete[] read_buffer;
|
||||
return false;
|
||||
}
|
||||
//判断是否读够了
|
||||
if (read_size == len)
|
||||
|
||||
// 判断是否读够了
|
||||
if (read_size >= len)
|
||||
break;
|
||||
|
||||
if (len - read_size < blocksize)
|
||||
{
|
||||
blocksize = len - read_size;
|
||||
}
|
||||
//等待,压缩带宽
|
||||
blocksize = (long)(len - read_size);
|
||||
|
||||
// 可选带宽限制
|
||||
if (downbaud != -1) {
|
||||
while ((time::now_sec()-begin_sec)*downbaud < read_size) {
|
||||
while ((time::now_sec() - begin_sec) * downbaud < read_size) {
|
||||
system::sleep_msec(100);
|
||||
}
|
||||
}
|
||||
if (ipending_detect_loop > 1024)
|
||||
{
|
||||
while (HPSERVER->GetPendingDataLength(m_reqpack->connid(), ipending_count))
|
||||
{
|
||||
if (ipending_count > 1024 * 1024 * 10)
|
||||
{
|
||||
system::sleep_msec(100);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
ipending_detect_loop = 0;
|
||||
}
|
||||
else
|
||||
ipending_detect_loop++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
delete[] read_buffer;
|
||||
|
||||
@@ -347,7 +392,7 @@ bool ylib::network::http::response::filecache(const uint64& last_modify_time)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ylib::network::http::response::fileoffset(long filesize, long& start, long& len)
|
||||
bool ylib::network::http::response::fileoffset(long long filesize, long long& start, long long& len)
|
||||
{
|
||||
start = 0, len = filesize;
|
||||
|
||||
@@ -362,8 +407,8 @@ bool ylib::network::http::response::fileoffset(long filesize, long& start, long&
|
||||
auto __arr = strutils::split(hValue,"-");
|
||||
if (__arr.size() == 2)
|
||||
{
|
||||
start = atol(__arr[0].c_str());
|
||||
len = atol(__arr[1].c_str());
|
||||
start = atoll(__arr[0].c_str());
|
||||
len = atoll(__arr[1].c_str());
|
||||
if (len == 0)
|
||||
len = filesize - start;
|
||||
}
|
||||
@@ -372,7 +417,7 @@ bool ylib::network::http::response::fileoffset(long filesize, long& start, long&
|
||||
if (hValue[0] == '-')
|
||||
{
|
||||
//下载最后x字节
|
||||
len = atol(std::string(hValue.substr(1, hValue.length() - 2)).c_str());
|
||||
len = atoll(std::string(hValue.substr(1, hValue.length() - 2)).c_str());
|
||||
if (len > filesize)
|
||||
return false;
|
||||
start = filesize - len;
|
||||
@@ -380,7 +425,7 @@ bool ylib::network::http::response::fileoffset(long filesize, long& start, long&
|
||||
else if (hValue[hValue.length() - 1] == '-')
|
||||
{
|
||||
//从x字节开始下载
|
||||
start = atol(std::string(hValue.substr(0, hValue.length() - 2)).c_str());
|
||||
start = atoll(std::string(hValue.substr(0, hValue.length() - 2)).c_str());
|
||||
if (start > filesize)
|
||||
return false;
|
||||
len = filesize - start;
|
||||
|
||||
Reference in New Issue
Block a user