确保32位系统支持超过4GB文件下载

This commit is contained in:
ziyue 2022-02-10 21:06:51 +08:00
parent ba213346bc
commit dc672b14e3
3 changed files with 30 additions and 32 deletions

View File

@ -40,7 +40,7 @@ HttpStringBody::HttpStringBody(string str) {
_str = std::move(str); _str = std::move(str);
} }
ssize_t HttpStringBody::remainSize() { int64_t HttpStringBody::remainSize() {
return _str.size() - _offset; return _str.size() - _offset;
} }
@ -150,7 +150,7 @@ private:
std::shared_ptr<char> _map_addr; std::shared_ptr<char> _map_addr;
}; };
ssize_t HttpFileBody::remainSize() { int64_t HttpFileBody::remainSize() {
return _read_to - _file_offset; return _read_to - _file_offset;
} }
@ -205,7 +205,7 @@ HttpMultiFormBody::HttpMultiFormBody(const HttpArgs &args, const string &filePat
_totalSize = _bodyPrefix.size() + _bodySuffix.size() + _fileBody->remainSize(); _totalSize = _bodyPrefix.size() + _bodySuffix.size() + _fileBody->remainSize();
} }
ssize_t HttpMultiFormBody::remainSize() { int64_t HttpMultiFormBody::remainSize() {
return _totalSize - _offset; return _totalSize - _offset;
} }
@ -270,7 +270,7 @@ HttpBufferBody::HttpBufferBody(Buffer::Ptr buffer) {
_buffer = std::move(buffer); _buffer = std::move(buffer);
} }
ssize_t HttpBufferBody::remainSize() { int64_t HttpBufferBody::remainSize() {
return _buffer ? _buffer->size() : 0; return _buffer ? _buffer->size() : 0;
} }

View File

@ -37,7 +37,7 @@ public:
/** /**
* -1, content-length * -1, content-length
*/ */
virtual ssize_t remainSize() { return 0;}; virtual int64_t remainSize() { return 0;};
/** /**
* size * size
@ -77,7 +77,7 @@ public:
HttpStringBody(std::string str); HttpStringBody(std::string str);
~HttpStringBody() override = default; ~HttpStringBody() override = default;
ssize_t remainSize() override; int64_t remainSize() override;
toolkit::Buffer::Ptr readData(size_t size) override ; toolkit::Buffer::Ptr readData(size_t size) override ;
private: private:
@ -94,7 +94,7 @@ public:
HttpBufferBody(toolkit::Buffer::Ptr buffer); HttpBufferBody(toolkit::Buffer::Ptr buffer);
~HttpBufferBody() override = default; ~HttpBufferBody() override = default;
ssize_t remainSize() override; int64_t remainSize() override;
toolkit::Buffer::Ptr readData(size_t size) override; toolkit::Buffer::Ptr readData(size_t size) override;
private: private:
@ -123,7 +123,7 @@ public:
*/ */
void setRange(uint64_t offset, uint64_t max_size); void setRange(uint64_t offset, uint64_t max_size);
ssize_t remainSize() override; int64_t remainSize() override;
toolkit::Buffer::Ptr readData(size_t size) override; toolkit::Buffer::Ptr readData(size_t size) override;
int sendFile(int fd) override; int sendFile(int fd) override;
@ -152,7 +152,7 @@ public:
*/ */
HttpMultiFormBody(const HttpArgs &args,const std::string &filePath,const std::string &boundary = "0xKhTmLbOuNdArY"); HttpMultiFormBody(const HttpArgs &args,const std::string &filePath,const std::string &boundary = "0xKhTmLbOuNdArY");
virtual ~HttpMultiFormBody(){} virtual ~HttpMultiFormBody(){}
ssize_t remainSize() override ; int64_t remainSize() override ;
toolkit::Buffer::Ptr readData(size_t size) override; toolkit::Buffer::Ptr readData(size_t size) override;
public: public:
@ -161,8 +161,8 @@ public:
static std::string multiFormContentType(const std::string &boundary); static std::string multiFormContentType(const std::string &boundary);
private: private:
size_t _offset = 0; uint64_t _offset = 0;
size_t _totalSize; int64_t _totalSize;
std::string _bodyPrefix; std::string _bodyPrefix;
std::string _bodySuffix; std::string _bodySuffix;
HttpFileBody::Ptr _fileBody; HttpFileBody::Ptr _fileBody;

View File

@ -519,16 +519,16 @@ void HttpSession::sendResponse(int code,
GET_CONFIG(uint32_t,keepAliveSec,Http::kKeepAliveSecond); GET_CONFIG(uint32_t,keepAliveSec,Http::kKeepAliveSecond);
//body默认为空 //body默认为空
ssize_t size = 0; int64_t size = 0;
if (body && body->remainSize()) { if (body && body->remainSize()) {
//有body获取body大小 //有body获取body大小
size = body->remainSize(); size = body->remainSize();
} }
if(no_content_length){ if (no_content_length) {
//http-flv直播是Keep-Alive类型 // http-flv直播是Keep-Alive类型
bClose = false; bClose = false;
}else if((size_t) size >= SIZE_MAX || size < 0 ){ } else if ((size_t)size >= SIZE_MAX || size < 0) {
//不固定长度的body那么发送完body后应该关闭socket以便浏览器做下载完毕的判断 //不固定长度的body那么发送完body后应该关闭socket以便浏览器做下载完毕的判断
bClose = true; bClose = true;
} }
@ -537,47 +537,47 @@ void HttpSession::sendResponse(int code,
headerOut.emplace(kDate, dateStr()); headerOut.emplace(kDate, dateStr());
headerOut.emplace(kServer, kServerName); headerOut.emplace(kServer, kServerName);
headerOut.emplace(kConnection, bClose ? "close" : "keep-alive"); headerOut.emplace(kConnection, bClose ? "close" : "keep-alive");
if(!bClose){ if (!bClose) {
string keepAliveString = "timeout="; string keepAliveString = "timeout=";
keepAliveString += to_string(keepAliveSec); keepAliveString += to_string(keepAliveSec);
keepAliveString += ", max=100"; keepAliveString += ", max=100";
headerOut.emplace(kKeepAlive,std::move(keepAliveString)); headerOut.emplace(kKeepAlive, std::move(keepAliveString));
} }
if(!_origin.empty()){ if (!_origin.empty()) {
//设置跨域 //设置跨域
headerOut.emplace(kAccessControlAllowOrigin,_origin); headerOut.emplace(kAccessControlAllowOrigin, _origin);
headerOut.emplace(kAccessControlAllowCredentials, "true"); headerOut.emplace(kAccessControlAllowCredentials, "true");
} }
if(!no_content_length && size >= 0 && (size_t)size < SIZE_MAX){ if (!no_content_length && size >= 0 && (size_t)size < SIZE_MAX) {
//文件长度为固定值,且不是http-flv强制设置Content-Length //文件长度为固定值,且不是http-flv强制设置Content-Length
headerOut[kContentLength] = to_string(size); headerOut[kContentLength] = to_string(size);
} }
if(size && !pcContentType){ if (size && !pcContentType) {
//有body时设置缺省类型 //有body时设置缺省类型
pcContentType = "text/plain"; pcContentType = "text/plain";
} }
if((size || no_content_length) && pcContentType){ if ((size || no_content_length) && pcContentType) {
//有body时设置文件类型 //有body时设置文件类型
string strContentType = pcContentType; string strContentType = pcContentType;
strContentType += "; charset="; strContentType += "; charset=";
strContentType += charSet; strContentType += charSet;
headerOut.emplace(kContentType,std::move(strContentType)); headerOut.emplace(kContentType, std::move(strContentType));
} }
//发送http头 //发送http头
string str; string str;
str.reserve(256); str.reserve(256);
str += "HTTP/1.1 " ; str += "HTTP/1.1 ";
str += to_string(code); str += to_string(code);
str += ' '; str += ' ';
str += getHttpStatusMessage(code) ; str += getHttpStatusMessage(code);
str += "\r\n"; str += "\r\n";
for (auto &pr : header) { for (auto &pr : header) {
str += pr.first ; str += pr.first;
str += ": "; str += ": ";
str += pr.second; str += pr.second;
str += "\r\n"; str += "\r\n";
@ -586,16 +586,16 @@ void HttpSession::sendResponse(int code,
SockSender::send(std::move(str)); SockSender::send(std::move(str));
_ticker.resetTime(); _ticker.resetTime();
if(!size){ if (!size) {
//没有body //没有body
if(bClose){ if (bClose) {
shutdown(SockException(Err_shutdown,StrPrinter << "close connection after send http header completed with status code:" << code)); shutdown(SockException(Err_shutdown,StrPrinter << "close connection after send http header completed with status code:" << code));
} }
return; return;
} }
if (typeid(*this) == typeid(HttpSession) && !body->sendFile(getSock()->rawFD())) { if (typeid(*this) == typeid(HttpSession) && !body->sendFile(getSock()->rawFD())) {
//http支持sendfile优化 // http支持sendfile优化
return; return;
} }
@ -607,9 +607,7 @@ void HttpSession::sendResponse(int code,
//发送http body //发送http body
AsyncSenderData::Ptr data = std::make_shared<AsyncSenderData>(shared_from_this(), body, bClose); AsyncSenderData::Ptr data = std::make_shared<AsyncSenderData>(shared_from_this(), body, bClose);
getSock()->setOnFlush([data]() { getSock()->setOnFlush([data]() { return AsyncSender::onSocketFlushed(data); });
return AsyncSender::onSocketFlushed(data);
});
AsyncSender::onSocketFlushed(data); AsyncSender::onSocketFlushed(data);
} }