diff --git a/include/ulib/utility/uhttp.h b/include/ulib/utility/uhttp.h index a384e826..b9050366 100644 --- a/include/ulib/utility/uhttp.h +++ b/include/ulib/utility/uhttp.h @@ -184,7 +184,7 @@ public: static char response_buffer[64]; static int mime_index, cgi_timeout; // the time-out value in seconds for output cgi process static bool enable_caching_by_proxy_servers, skip_check_cookie_ip_address; - static uint32_t limit_request_body, request_read_timeout, range_start, range_size; + static uint32_t limit_request_body, request_read_timeout, range_start, range_size, brotli_level_for_dynamic_content; static bool readRequest(); static bool handlerCache(); @@ -1340,8 +1340,33 @@ private: #endif #if defined(USE_LIBZ) || defined(USE_LIBBROTLI) + static bool checkForCompression(uint32_t size) + { + U_TRACE(0, "UHTTP::checkForCompression(%u)", size) + + U_INTERNAL_ASSERT_MAJOR(size, 0) + + U_INTERNAL_DUMP("U_http_is_accept_gzip = %b U_http_is_accept_brotli = %b", U_http_is_accept_gzip, U_http_is_accept_brotli) + + if (size > U_MIN_SIZE_FOR_DEFLATE) + { +# ifdef USE_LIBBROTLI + if (U_http_is_accept_brotli) U_RETURN(true); +# endif +# ifdef USE_LIBZ + if (U_http_is_accept_gzip) U_RETURN(true); +# endif + } + + U_RETURN(false); + } + +# ifdef USE_LIBBROTLI + static void checkArrayCompressData(UFileCacheData* ptr) U_NO_EXPORT; +# endif + static inline void setAcceptEncoding(const char* ptr, uint32_t len) U_NO_EXPORT; -#endif +#endif #ifdef U_STATIC_ONLY static void loadStaticLinkedServlet(const char* name, uint32_t len, vPFi runDynamicPage) U_NO_EXPORT; diff --git a/src/ulib/net/server/plugin/mod_ssi.cpp b/src/ulib/net/server/plugin/mod_ssi.cpp index 6b4d0a05..a496500f 100644 --- a/src/ulib/net/server/plugin/mod_ssi.cpp +++ b/src/ulib/net/server/plugin/mod_ssi.cpp @@ -1055,7 +1055,9 @@ int USSIPlugIn::handlerRequest() U_INTERNAL_ASSERT_POINTER(UHTTP::file_data->array) U_INTERNAL_ASSERT_EQUALS( UHTTP::file_data->array->size(), 2) - (void) header->append(UHTTP::getHeaderFromCache()); // NB: after now 'file_data' can change... + U_INTERNAL_DUMP("U_http_version = %C", U_http_version) + + (void) header->append(UHTTP::getDataFromCache(UHTTP::file_data->array, 1)); // NB: after now 'file_data' can change... *body = (UHTTP::isGETorHEAD() && *UClientImage_Base::body @@ -1069,27 +1071,27 @@ int USSIPlugIn::handlerRequest() U_INTERNAL_DUMP("alternative_response = %d output(%u) = %V", alternative_response, output.size(), output.rep) + U_http_info.nResponseCode = HTTP_OK; + if (alternative_response == 0) { uint32_t size = output.size(); - U_INTERNAL_ASSERT_MAJOR(size,0) - -# ifdef USE_LIBZ - U_INTERNAL_DUMP("U_http_is_accept_gzip = %b", U_http_is_accept_gzip) - - if (U_http_is_accept_gzip && - size > U_MIN_SIZE_FOR_DEFLATE) +# if !defined(USE_LIBZ) && !defined(USE_LIBBROTLI) + bool bcompress = false; +# else + bool bcompress = UHTTP::checkForCompression(size); # endif + + if (bcompress == false) *UClientImage_Base::body = output; + else { - output = UStringExt::deflate(output, 1); + UHTTP::setResponseCompressed(output); - size = output.size(); - - (void) header->insert(0, U_CONSTANT_TO_PARAM("Content-Encoding: gzip\r\n")); + size = UClientImage_Base::body->size(); } - *UHTTP::ext = *header; + (void) UHTTP::ext->append(*header); if (bcache) (void) UHTTP::checkContentLength(size); // NB: adjusting the size of response... else @@ -1099,10 +1101,6 @@ int USSIPlugIn::handlerRequest() (void) UHTTP::ext->append(UHTTP::getHeaderMimeType(U_NULLPTR, size, U_CTYPE_HTML)); } - U_http_info.nResponseCode = HTTP_OK; - - *UClientImage_Base::body = output; - UHTTP::handlerResponse(); } else if (alternative_response > 1) @@ -1122,8 +1120,7 @@ int USSIPlugIn::handlerRequest() (void) UClientImage_Base::wbuffer->replace(*header); (void) UClientImage_Base::wbuffer->append(U_CONSTANT_TO_PARAM(U_CRLF)); - U_http_info.endHeader = UClientImage_Base::wbuffer->size(); - U_http_info.nResponseCode = HTTP_OK; + U_http_info.endHeader = UClientImage_Base::wbuffer->size(); (void) UClientImage_Base::wbuffer->append(alternative_response == 2 ? output : *body); diff --git a/src/ulib/utility/uhttp.cpp b/src/ulib/utility/uhttp.cpp index 1375734e..c1828a7d 100644 --- a/src/ulib/utility/uhttp.cpp +++ b/src/ulib/utility/uhttp.cpp @@ -110,6 +110,9 @@ uint32_t UHTTP::is_response_compressed; uint32_t UHTTP::limit_request_body = U_STRING_MAX_SIZE; uint32_t UHTTP::request_read_timeout; +// https://www.google.com/url?q=https%3A%2F%2Fblogs.akamai.com%2F2016%2F02%2Funderstanding-brotlis-potential.html&sa=D&sntz=1&usg=AFQjCNGP4Nu9yPm65RKkAThsWxJ8qy49Sw +uint32_t UHTTP::brotli_level_for_dynamic_content = 2; + UCommand* UHTTP::pcmd; UDataSession* UHTTP::data_session; UDataSession* UHTTP::data_storage; @@ -4815,23 +4818,22 @@ U_NO_EXPORT void UHTTP::setResponseCompressed(const UString& data) U_INTERNAL_DUMP("U_http_is_accept_gzip = %b U_http_is_accept_brotli = %b", U_http_is_accept_gzip, U_http_is_accept_brotli) #ifdef USE_LIBBROTLI - if (U_http_is_accept_brotli) + if (U_http_is_accept_brotli && + (*UClientImage_Base::body = UStringExt::brotli(data, brotli_level_for_dynamic_content))) { +# ifndef U_CACHE_REQUEST_DISABLE + is_response_compressed = 2; // brotli +# endif + (void) ext->append(U_CONSTANT_TO_PARAM("Content-Encoding: br\r\n")); - if ((*UClientImage_Base::body = UStringExt::brotli(data, 6))) - { -# ifndef U_CACHE_REQUEST_DISABLE - is_response_compressed = 2; // brotli -# endif - - return; - } + return; } #endif #ifdef USE_LIBZ - if (U_http_is_accept_gzip) + if (U_http_is_accept_gzip && + (*UClientImage_Base::body = UStringExt::deflate(data, 1))) { # ifndef U_CACHE_REQUEST_DISABLE is_response_compressed = 1; // gzip @@ -4839,8 +4841,6 @@ U_NO_EXPORT void UHTTP::setResponseCompressed(const UString& data) (void) ext->append(U_CONSTANT_TO_PARAM("Content-Encoding: gzip\r\n")); - *UClientImage_Base::body = UStringExt::deflate(data, 1); - return; } # endif @@ -6966,32 +6966,20 @@ void UHTTP::setDynamicResponse() U_INTERNAL_ASSERT_MAJOR(U_http_info.nResponseCode, 0) - char* ptr; char* ptr1; UString compressed; - bool bcompress = false; const char* pEndHeader; uint32_t sz = 0, csz, ratio, clength = UClientImage_Base::wbuffer->size(); - ext->setBuffer(U_CAPACITY); - - ptr = ext->data(); - - U_INTERNAL_DUMP("U_http_is_accept_gzip = %b U_http_is_accept_brotli = %b", U_http_is_accept_gzip, U_http_is_accept_brotli) - -#if defined(USE_LIBZ) || defined(USE_LIBBROTLI) - if (UClientImage_Base::wbuffer->size() > (U_http_info.endHeader + U_MIN_SIZE_FOR_DEFLATE)) - { -# ifdef USE_LIBBROTLI - if (U_http_is_accept_brotli) bcompress = true; -# endif -# ifdef USE_LIBZ - if (U_http_is_accept_gzip) bcompress = true; -# endif - } +#if !defined(USE_LIBZ) && !defined(USE_LIBBROTLI) + bool bcompress = false; +#else + bool bcompress = checkForCompression(clength); #endif - U_INTERNAL_DUMP("bcompress = %b", bcompress) + ext->setBuffer(U_CAPACITY); + + char* ptr = ext->data(); if (U_http_info.endHeader) { @@ -7028,7 +7016,7 @@ void UHTTP::setDynamicResponse() #ifdef USE_LIBBROTLI if (U_http_is_accept_brotli && - (compressed = UStringExt::brotli(UClientImage_Base::wbuffer->c_pointer(U_http_info.endHeader), clength, 6))) + (compressed = UStringExt::brotli(UClientImage_Base::wbuffer->c_pointer(U_http_info.endHeader), clength, brotli_level_for_dynamic_content))) { bcompress = false; @@ -8000,6 +7988,23 @@ U_NO_EXPORT void UHTTP::setHeaderForCache(UHTTP::UFileCacheData* ptr, const UStr #endif } +#ifdef USE_LIBBROTLI +U_NO_EXPORT void UHTTP::checkArrayCompressData(UFileCacheData* ptr) +{ + U_TRACE(0, "UHTTP::checkArrayCompressData(%p)", ptr) + + if (ptr->array->size() == 2) + { + ptr->array->push_back(UString::getStringNull()); // 2 gzip(content) + ptr->array->push_back(UString::getStringNull()); // 3 gzip(header) + +# ifndef U_HTTP2_DISABLE + ptr->http2->push_back(UString::getStringNull()); // 1 gzip(header) +# endif + } +} +#endif + U_NO_EXPORT void UHTTP::putDataInCache(const UString& fmt, UString& content) { U_TRACE(0, "UHTTP::putDataInCache(%V,%V)", fmt.rep, content.rep) @@ -8155,16 +8160,6 @@ next: } # endif - if (file_data->array->size() == 2) - { - file_data->array->push_back(UString::getStringNull()); // 2 gzip(content) - file_data->array->push_back(UString::getStringNull()); // 3 gzip(header) - -# ifndef U_HTTP2_DISABLE - file_data->http2->push_back(UString::getStringNull()); // 1 gzip(header) -# endif - } - # ifdef USE_LIBBROTLI UString content2 = UStringExt::brotli(content); @@ -8172,6 +8167,8 @@ next: if ((size = content2.size()) < file_data->size) { + checkArrayCompressData(file_data); + if (size) ratio2 = (size * 100U) / file_data->size; U_INTERNAL_DUMP("ratio2 = %u (%u%%)", ratio2, 100-ratio2) @@ -11601,27 +11598,21 @@ U_EXPORT istream& operator>>(istream& is, UHTTP::UFileCacheData& d) UHTTP::setHeaderForCache(&d, decoded); } # ifdef USE_LIBZ - else + else if (u_is_img(d.mime_index) == false) { - if (u_is_img(d.mime_index)) - { - d.array->push_back(UString::getStringNull()); // 2 gzip(content) - d.array->push_back(UString::getStringNull()); // 3 gzip(header) - } - else - { - d.array->push_back(UStringExt::deflate(content, 2)); // 2 gzip(content) + d.array->push_back(UStringExt::deflate(content, 2)); // 2 gzip(content) - decoded = U_STRING_FROM_CONSTANT("Content-Encoding: gzip\r\n") + header; + decoded = U_STRING_FROM_CONSTANT("Content-Encoding: gzip\r\n") + header; - UHTTP::setHeaderForCache(&d, decoded); // 3 gzip(header) - } + UHTTP::setHeaderForCache(&d, decoded); // 3 gzip(header) } # endif # ifdef USE_LIBBROTLI if (u_is_img(d.mime_index) == false) { + UHTTP::checkArrayCompressData(&d); + d.array->push_back(UStringExt::brotli(content)); // 4 brotli(content) decoded = U_STRING_FROM_CONSTANT("Content-Encoding: br\r\n") + header;