diff --git a/include/wx/webrequest.h b/include/wx/webrequest.h index 239db265b7..75106322ea 100644 --- a/include/wx/webrequest.h +++ b/include/wx/webrequest.h @@ -89,6 +89,12 @@ public: void SetState(State state, const wxString& failMsg = ""); + static void SplitParameters(const wxString& s, wxString& value, + wxWebRequestHeaderMap& parameters); + + static void SplitParameters(const wxString::const_iterator& begin, + const wxString::const_iterator& end, wxWebRequestHeaderMap& parameters); + protected: wxString m_method; Storage m_storage; diff --git a/interface/wx/webrequest.h b/interface/wx/webrequest.h index 03b563e48d..e97f5e85c9 100644 --- a/interface/wx/webrequest.h +++ b/interface/wx/webrequest.h @@ -320,6 +320,36 @@ public: */ wxFileOffset GetBytesExpectedToReceive() const; ///@} + + /** + Splits the given string into a value and a collection of parameters. + Parameters are expected to be separated by semicolons. + Enclosing quotes of parameter values are removed. + + For example, the string + @code + multipart/mixed; boundary="MIME_boundary_01234567" + @endcode + is split into the value + @code + multipart/mixed + @endcode + and the parameter + @code + boundary -> MIME_boundary_01234567 + @endcode + */ + static void SplitParameters(const wxString& s, wxString& value, + wxWebRequestHeaderMap& parameters); + + /** + Splits the given string into a collection of parameters. + Parameters are expected to be separated by semicolons. + + Enclosing quotes of parameter values are removed. + */ + static void SplitParameters(const wxString::const_iterator& begin, + const wxString::const_iterator& end, wxWebRequestHeaderMap& parameters); }; /** diff --git a/src/common/webrequest.cpp b/src/common/webrequest.cpp index bca423a6a7..6bd870c384 100644 --- a/src/common/webrequest.cpp +++ b/src/common/webrequest.cpp @@ -114,6 +114,69 @@ void wxWebRequest::SetState(State state, const wxString & failMsg) CallAfter(&wxWebRequest::ProcessStateEvent, state, failMsg); } +// The SplitParamaters implementation is adapted to wxWidgets +// from Poco::Net::MessageHeader::splitParameters + +void wxWebRequest::SplitParameters(const wxString& s, wxString& value, + wxWebRequestHeaderMap& parameters) +{ + value.clear(); + parameters.clear(); + wxString::const_iterator it = s.begin(); + wxString::const_iterator end = s.end(); + while ( it != end && wxIsspace(*it) ) ++it; + while ( it != end && *it != ';' ) value += *it++; + value.Trim(); + if ( it != end ) ++it; + SplitParameters(it, end, parameters); +} + +void wxWebRequest::SplitParameters(const wxString::const_iterator& begin, + const wxString::const_iterator& end, wxWebRequestHeaderMap& parameters) +{ + wxString pname; + wxString pvalue; + pname.reserve(32); + pvalue.reserve(64); + wxString::const_iterator it = begin; + while ( it != end ) + { + pname.clear(); + pvalue.clear(); + while ( it != end && wxIsspace(*it) ) ++it; + while ( it != end && *it != '=' && *it != ';' ) pname += *it++; + pname.Trim(); + if ( it != end && *it != ';' ) ++it; + while ( it != end && wxIsspace(*it) ) ++it; + while ( it != end && *it != ';' ) + { + if ( *it == '"' ) + { + ++it; + while ( it != end && *it != '"' ) + { + if ( *it == '\\' ) + { + ++it; + if ( it != end ) pvalue += *it++; + } + else pvalue += *it++; + } + if ( it != end ) ++it; + } + else if ( *it == '\\' ) + { + ++it; + if ( it != end ) pvalue += *it++; + } + else pvalue += *it++; + } + pvalue.Trim(); + if ( !pname.empty() ) parameters[pname] = pvalue; + if ( it != end ) ++it; + } +} + void wxWebRequest::ProcessStateEvent(State state, const wxString& failMsg) { if (!IsActiveState(state) && GetResponse()) diff --git a/tests/net/webrequest.cpp b/tests/net/webrequest.cpp index bb297c0ebc..175fd071fc 100644 --- a/tests/net/webrequest.cpp +++ b/tests/net/webrequest.cpp @@ -197,4 +197,17 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][.]") } } +TEST_CASE("WebRequestUtils", "[net]") +{ + wxString value; + wxWebRequestHeaderMap params; + + wxString header = "multipart/mixed; boundary=\"MIME_boundary_01234567\""; + + wxWebRequest::SplitParameters(header, value, params); + REQUIRE( value == "multipart/mixed" ); + REQUIRE( params.size() == 1 ); + REQUIRE( params["boundary"] == "MIME_boundary_01234567" ); +} + #endif // wxUSE_WEBREQUEST