| From 4cab5e5c0c5f19fcee7d37b4a38b156d63a150d4 Mon Sep 17 00:00:00 2001 |
| From: Peter Thorson <git@zaphoyd.com> |
| Date: Sun, 11 Jun 2017 16:13:25 -0500 |
| Subject: [PATCH] minor adjustments to recent extension negotiation related |
| fixes, refactor a bit more extension negotiation code to be simpler |
| |
| --- |
| websocketpp/impl/connection_impl.hpp | 6 +-- |
| websocketpp/processors/hybi13.hpp | 92 ++++++++++++++++++------------------ |
| 2 files changed, 49 insertions(+), 49 deletions(-) |
| |
| Index: websocketpp-0.7.0/websocketpp/impl/connection_impl.hpp |
| =================================================================== |
| --- websocketpp-0.7.0.orig/websocketpp/impl/connection_impl.hpp |
| +++ websocketpp-0.7.0/websocketpp/impl/connection_impl.hpp |
| @@ -1222,17 +1222,17 @@ |
| std::pair<lib::error_code,std::string> neg_results; |
| neg_results = m_processor->negotiate_extensions(m_request); |
| |
| - if (neg_results.first == error::make_error_code(error::extension_parse_error)) { |
| + if (neg_results.first == processor::error::make_error_code(processor::error::extension_parse_error)) { |
| // There was a fatal error in extension parsing that should result in |
| // a failed connection attempt. |
| - m_alog.write(log::alevel::info, "Bad request: " + neg_results.first.message()); |
| + m_elog.write(log::elevel::info, "Bad request: " + neg_results.first.message()); |
| m_response.set_status(http::status_code::bad_request); |
| return neg_results.first; |
| } else if (neg_results.first) { |
| // There was a fatal error in extension processing that is probably our |
| // fault. Consider extension negotiation to have failed and continue as |
| // if extensions were not supported |
| - m_alog.write(log::alevel::info, |
| + m_elog.write(log::elevel::info, |
| "Extension negotiation failed: " + neg_results.first.message()); |
| } else { |
| // extension negotiation succeeded, set response header accordingly |
| Index: websocketpp-0.7.0/websocketpp/processors/hybi13.hpp |
| =================================================================== |
| --- websocketpp-0.7.0.orig/websocketpp/processors/hybi13.hpp |
| +++ websocketpp-0.7.0/websocketpp/processors/hybi13.hpp |
| @@ -97,11 +97,6 @@ |
| /** |
| * This exists mostly because the code for requests and responses is |
| * identical and I can't have virtual template methods. |
| - * |
| - * NOTE: this method makes assumptions that the permessage-deflate |
| - * extension is the only one supported. If additional extensions are |
| - * ever supported it should be reviewed carefully. Most cases where |
| - * that assumption is made are explicitly noted. |
| */ |
| template <typename header_type> |
| err_str_pair negotiate_extensions_helper(header_type const & header) { |
| @@ -130,55 +125,60 @@ |
| |
| http::parameter_list::const_iterator it; |
| |
| + // look through the list of extension requests to find the first |
| + // one that we can accept. |
| if (m_permessage_deflate.is_implemented()) { |
| err_str_pair neg_ret; |
| for (it = p.begin(); it != p.end(); ++it) { |
| - // look through each extension, if the key is permessage-deflate |
| - if (it->first == "permessage-deflate") { |
| - // if we have already successfully negotiated this extension |
| - // then skip any other requests to negotiate the same one |
| - // with different parameters |
| - if (m_permessage_deflate.is_enabled()) { |
| - continue; |
| - } |
| - |
| - |
| - neg_ret = m_permessage_deflate.negotiate(it->second); |
| - |
| - if (neg_ret.first) { |
| - // Figure out if this is an error that should halt all |
| - // extension negotiations or simply cause negotiation of |
| - // this specific extension to fail. |
| - //std::cout << "permessage-compress negotiation failed: " |
| - // << neg_ret.first.message() << std::endl; |
| - } else { |
| - // Note: this list will need commas if WebSocket++ ever |
| - // supports more than one extension |
| - |
| - // Actually try to initialize the extension before we |
| - // deem negotiation complete |
| - ret.first = m_permessage_deflate.init(base::m_server); |
| - if (!ret.first) { |
| - |
| - // TODO: support multiple extensions. |
| - // right now, because there is only one extension |
| - // supported, it failing to negotiate means we are |
| - // done with all negotiating. In the future if more |
| - // extensions are supported a better solution will |
| - // be needed here. |
| - break; |
| - } else { |
| - ret.second += neg_ret.second; |
| - |
| - // continue looking for more extensions |
| - continue; |
| - } |
| - |
| - } |
| + // not a permessage-deflate extension request, ignore |
| + if (it->first != "permessage-deflate") { |
| + continue; |
| + } |
| + |
| + // if we have already successfully negotiated this extension |
| + // then skip any other requests to negotiate the same one |
| + // with different parameters |
| + if (m_permessage_deflate.is_enabled()) { |
| + continue; |
| + } |
| + |
| + // attempt to negotiate this offer |
| + neg_ret = m_permessage_deflate.negotiate(it->second); |
| + |
| + if (neg_ret.first) { |
| + // negotiation offer failed. Do nothing. We will continue |
| + // searching for a permessage-deflate config that succeeds |
| + continue; |
| + } |
| + |
| + // Negotiation tentatively succeeded |
| + |
| + // Actually try to initialize the extension before we |
| + // deem negotiation complete |
| + lib::error_code ec = m_permessage_deflate.init(base::m_server); |
| + |
| + if (ec) { |
| + // Negotiation succeeded but initialization failed this is |
| + // an error that should stop negotiation of permessage |
| + // deflate. Return the reason for the init failure |
| + |
| + ret.first = ec; |
| + break; |
| + } else { |
| + // Successfully initialized, push the negotiated response into |
| + // the reply and stop looking for additional permessage-deflate |
| + // extensions |
| + ret.second += neg_ret.second; |
| + break; |
| } |
| } |
| } |
| |
| + // support for future extensions would go here. Should check the value of |
| + // ret.first before continuing. Might need to consider whether failure of |
| + // negotiation of an earlier extension should stop negotiation of subsequent |
| + // ones |
| + |
| return ret; |
| } |
| |