diff --git a/src/Http/HttpBody.cpp b/src/Http/HttpBody.cpp index 4d9046a3..0c1996d1 100644 --- a/src/Http/HttpBody.cpp +++ b/src/Http/HttpBody.cpp @@ -65,9 +65,23 @@ HttpFileBody::HttpFileBody(const std::shared_ptr &fp, size_t offset, size_ init(fp, offset, max_size, use_mmap); } +#if defined(__linux__) || defined(__linux) +#include +#endif + +int HttpFileBody::sendFile(int fd) { +#if defined(__linux__) || defined(__linux) + off_t off = _file_offset; + return sendfile(fd, fileno(_fp.get()), &off, _max_size); +#else + return -1; +#endif +} + void HttpFileBody::init(const std::shared_ptr &fp, size_t offset, size_t max_size, bool use_mmap) { _fp = fp; _max_size = max_size; + _file_offset = offset; #ifdef ENABLE_MMAP if (use_mmap) { do { diff --git a/src/Http/HttpBody.h b/src/Http/HttpBody.h index eb854030..319bc1bb 100644 --- a/src/Http/HttpBody.h +++ b/src/Http/HttpBody.h @@ -57,6 +57,15 @@ public: //(其实并没有读,拷贝文件数据时在内核态完成文件读) cb(readData(size)); } + + /** + * 使用sendfile优化文件发送 + * @param fd socket fd + * @return 0成功,其他为错误代码 + */ + virtual int sendFile(int fd) { + return -1; + } }; /** @@ -112,6 +121,7 @@ public: ssize_t remainSize() override ; toolkit::Buffer::Ptr readData(size_t size) override; + int sendFile(int fd) override; private: void init(const std::shared_ptr &fp,size_t offset,size_t max_size, bool use_mmap); @@ -119,6 +129,7 @@ private: private: size_t _max_size; size_t _offset = 0; + size_t _file_offset = 0; std::shared_ptr _fp; std::shared_ptr _map_addr; toolkit::ResourcePool _pool; diff --git a/src/Http/HttpSession.cpp b/src/Http/HttpSession.cpp index c1b9655a..0d3c6760 100644 --- a/src/Http/HttpSession.cpp +++ b/src/Http/HttpSession.cpp @@ -594,6 +594,11 @@ void HttpSession::sendResponse(int code, return; } + if (!body->sendFile(getSock()->rawFD())) { + //支持sendfile优化 + return; + } + GET_CONFIG(uint32_t, sendBufSize, Http::kSendBufSize); if(body->remainSize() > sendBufSize){ //文件下载提升发送性能