diff --git a/config.example.json b/config.example.json index 8f5b42aa..d753b1c7 100644 --- a/config.example.json +++ b/config.example.json @@ -193,6 +193,10 @@ //file with the extension ".gz" in the same path and send the compressed file to the client. //The default value of gzip_static is true. "gzip_static": true, + //br_static: If it is set to true, when the client requests a static file, drogon first finds the compressed + //file with the extension ".br" in the same path and send the compressed file to the client. + //The default value of br_static is true. + "br_static": true, //client_max_body_size: Set the maximum body size of HTTP requests received by drogon. The default value is "1M". //One can set it to "1024", "1k", "10M", "1G", etc. Setting it to "" means no limit. "client_max_body_size": "1M", diff --git a/drogon_ctl/templates/config.csp b/drogon_ctl/templates/config.csp index 924fb053..6536f085 100644 --- a/drogon_ctl/templates/config.csp +++ b/drogon_ctl/templates/config.csp @@ -193,6 +193,10 @@ //file with the extension ".gz" in the same path and send the compressed file to the client. //The default value of gzip_static is true. "gzip_static": true, + //br_static: If it is set to true, when the client requests a static file, drogon first finds the compressed + //file with the extension ".br" in the same path and send the compressed file to the client. + //The default value of br_static is true. + "br_static": true, //client_max_body_size: Set the maximum body size of HTTP requests received by drogon. The default value is "1M". //One can set it to "1024", "1k", "10M", "1G", etc. Setting it to "" means no limit. "client_max_body_size": "1M", diff --git a/lib/inc/drogon/HttpAppFramework.h b/lib/inc/drogon/HttpAppFramework.h index 5258f145..613ee949 100644 --- a/lib/inc/drogon/HttpAppFramework.h +++ b/lib/inc/drogon/HttpAppFramework.h @@ -923,6 +923,17 @@ class HttpAppFramework : public trantor::NonCopyable */ virtual HttpAppFramework &setGzipStatic(bool useGzipStatic) = 0; + /// Set the br_static option. + /** + * If it is set to true, when the client requests a static file, drogon + * first finds the compressed file with the extension ".br" in the same path + * and send the compressed file to the client. The default value is true. + * + * @note + * This operation can be performed by an option in the configuration file. + */ + virtual HttpAppFramework &setBrStatic(bool useGzipStatic) = 0; + /// Set the max body size of the requests received by drogon. /** * The default value is 1M. diff --git a/lib/src/ConfigLoader.cc b/lib/src/ConfigLoader.cc index 4d3a6b59..d5cf2e3e 100644 --- a/lib/src/ConfigLoader.cc +++ b/lib/src/ConfigLoader.cc @@ -369,6 +369,8 @@ static void loadApp(const Json::Value &app) drogon::app().setPipeliningRequestsNumber(pipeliningReqs); auto useGzipStatic = app.get("gzip_static", true).asBool(); drogon::app().setGzipStatic(useGzipStatic); + auto useBrStatic = app.get("br_static", true).asBool(); + drogon::app().setBrStatic(useBrStatic); auto maxBodySize = app.get("client_max_body_size", "1M").asString(); size_t size; if (bytesSize(maxBodySize, size)) diff --git a/lib/src/HttpAppFrameworkImpl.cc b/lib/src/HttpAppFrameworkImpl.cc index 883e33a4..cb4804bc 100644 --- a/lib/src/HttpAppFrameworkImpl.cc +++ b/lib/src/HttpAppFrameworkImpl.cc @@ -164,6 +164,11 @@ HttpAppFramework &HttpAppFrameworkImpl::setGzipStatic(bool useGzipStatic) staticFileRouterPtr_->setGzipStatic(useGzipStatic); return *this; } +HttpAppFramework &HttpAppFrameworkImpl::setBrStatic(bool useGzipStatic) +{ + staticFileRouterPtr_->setBrStatic(useGzipStatic); + return *this; +} #ifndef _WIN32 HttpAppFramework &HttpAppFrameworkImpl::enableDynamicViewsLoading( const std::vector &libPaths, diff --git a/lib/src/HttpAppFrameworkImpl.h b/lib/src/HttpAppFrameworkImpl.h index a959315f..8fbf70b9 100644 --- a/lib/src/HttpAppFrameworkImpl.h +++ b/lib/src/HttpAppFrameworkImpl.h @@ -274,6 +274,7 @@ class HttpAppFrameworkImpl : public HttpAppFramework return *this; } virtual HttpAppFramework &setGzipStatic(bool useGzipStatic) override; + virtual HttpAppFramework &setBrStatic(bool useGzipStatic) override; virtual HttpAppFramework &setClientMaxBodySize(size_t maxSize) override { clientMaxBodySize_ = maxSize; diff --git a/lib/src/StaticFileRouter.cc b/lib/src/StaticFileRouter.cc index d5830a7c..ef717aa9 100644 --- a/lib/src/StaticFileRouter.cc +++ b/lib/src/StaticFileRouter.cc @@ -248,7 +248,22 @@ void StaticFileRouter::sendStaticFileResponse( return; } HttpResponsePtr resp; - if (gzipStaticFlag_ && + if (brStaticFlag_ && + req->getHeaderBy("accept-encoding").find("br") != std::string::npos) + { + // Find compressed file first. + auto gzipFileName = filePath + ".br"; + std::ifstream infile(gzipFileName, std::ifstream::binary); + if (infile) + { + resp = + HttpResponse::newFileResponse(gzipFileName, + "", + drogon::getContentType(filePath)); + resp->addHeader("Content-Encoding", "br"); + } + } + if (!resp && gzipStaticFlag_ && req->getHeaderBy("accept-encoding").find("gzip") != std::string::npos) { // Find compressed file first. @@ -263,6 +278,7 @@ void StaticFileRouter::sendStaticFileResponse( resp->addHeader("Content-Encoding", "gzip"); } } + if (!resp) resp = HttpResponse::newFileResponse(filePath); if (resp->statusCode() != k404NotFound) diff --git a/lib/src/StaticFileRouter.h b/lib/src/StaticFileRouter.h index d55fecd1..0be94652 100644 --- a/lib/src/StaticFileRouter.h +++ b/lib/src/StaticFileRouter.h @@ -42,6 +42,10 @@ class StaticFileRouter { gzipStaticFlag_ = useGzipStatic; } + void setBrStatic(bool useBrStatic) + { + brStaticFlag_ = useBrStatic; + } void init(const std::vector &ioloops); void sendStaticFileResponse( @@ -95,6 +99,7 @@ class StaticFileRouter int staticFilesCacheTime_{5}; bool enableLastModify_{true}; bool gzipStaticFlag_{true}; + bool brStaticFlag_{true}; std::unique_ptr< IOThreadStorage>>> staticFilesCacheMap_;