oatpp / oatpp

🌱Light and powerful C++ web framework for highly scalable and resource-efficient web application. It's zero-dependency and easy-portable.
https://oatpp.io/
Apache License 2.0
7.81k stars 1.3k forks source link

gzip encode suggestion: #385

Open formoon opened 3 years ago

formoon commented 3 years ago

I tried oatpp-zlib, this module works, but the effect is not good. Mainly in some browsers, such as chrome, when gzip encoding is preferred to send requests, oatpp still uses deflate plain text to respond, and gzip encoding is not preferred. I simply made some changes to make gzip the best choice when supported by the browser. Now it can work when tested with safari/chrome. But the modification method is awkward and unsafe. I hope to see the official improvement in the next version.

oatpp/oatpp/src/oatpp/web/protocol/http/encoding/ProviderCollection.hpp:

...
public:
  const char * Preferred=nullptr; 
...

oatpp/oatpp/src/oatpp/web/protocol/http/utils/CommunicationUtils.cpp:

...
    if(suggested) {
      if (providers->Preferred){
        oatpp::parser::Caret caret(suggested.getData(), suggested.getSize());
        if(caret.findText(providers->Preferred)){
          auto provider = providers->get(data::share::StringKeyLabelCI(providers->Preferred));
          if(provider) {
            return provider;
          }
        }
      }
...

last in AppComponent.hpp:

  OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
    OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router); // get Router component
    OATPP_COMPONENT(std::shared_ptr<oatpp::async::Executor>, executor); // get Async executor component
    auto components = std::make_shared<oatpp::web::server::HttpProcessor::Components>(router);
    auto encoders = std::make_shared<oatpp::web::protocol::http::encoding::ProviderCollection>();
    encoders->add(std::make_shared<oatpp::zlib::GzipEncoderProvider>());
    encoders->add(std::make_shared<oatpp::zlib::DeflateEncoderProvider>());
    encoders->Preferred="gzip"; //make gzip as preferred encoder
    components->contentEncodingProviders = encoders;
    return std::make_shared<oatpp::web::server::AsyncHttpConnectionHandler>(components, executor);
  }());
formoon commented 3 years ago

I think better method is change http::HeaderValueData 's tokens to ordered set, then the encoder name send from browser ranked first will be preferred.

lganzzzo commented 3 years ago

Hey @formoon ,

Thanks for reporting this issue.

I think better method is change http::HeaderValueData 's tokens to ordered set, then the encoder name send from browser ranked first will be preferred.

Yes, I also think that something like this (storing tokens order in addition to existing info) would be a better solution.