From 6535170f3d2afff6d4e5eeb5358e8613b5165281 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 25 Jul 2013 21:55:13 +0000 Subject: [PATCH] Allow using custom method names in wxHTTP. Add wxHTTP::SetMethod(). Also simplify the code by determining the method to use in Connect() instead of doing it in BuildRequest() itself. Get rid of the now unused wxHTTP_Req enum. Closes #15354. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74597 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/protocol/http.h | 11 ++----- interface/wx/protocol/http.h | 17 +++++++++++ src/common/http.cpp | 59 +++++++++++++++--------------------- 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 5185e0139f..7c903f4ed1 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -562,6 +562,7 @@ Major new features in this release All: +- Allow using custom HTTP methods with wxHTTP (Kolya Kosenko). - Fix build with wxUSE_FFILE==0 (jroemmler). All (GUI): diff --git a/include/wx/protocol/http.h b/include/wx/protocol/http.h index 476df9189a..f2ee811ea5 100644 --- a/include/wx/protocol/http.h +++ b/include/wx/protocol/http.h @@ -36,6 +36,7 @@ public: wxString GetHeader(const wxString& header) const; int GetResponse() const { return m_http_response; } + void SetMethod(const wxString& method) { m_method = method; } void SetHeader(const wxString& header, const wxString& h_data); bool SetPostText(const wxString& contentType, const wxString& data, @@ -51,19 +52,12 @@ public: wxDEPRECATED(void SetPostBuffer(const wxString& post_buf)); protected: - enum wxHTTP_Req - { - wxHTTP_GET, - wxHTTP_POST, - wxHTTP_HEAD - }; - typedef wxStringToStringHashMap::iterator wxHeaderIterator; typedef wxStringToStringHashMap::const_iterator wxHeaderConstIterator; typedef wxStringToStringHashMap::iterator wxCookieIterator; typedef wxStringToStringHashMap::const_iterator wxCookieConstIterator; - bool BuildRequest(const wxString& path, wxHTTP_Req req); + bool BuildRequest(const wxString& path, const wxString& method); void SendHeaders(); bool ParseHeaders(); @@ -81,6 +75,7 @@ protected: // internal variables: + wxString m_method; wxStringToStringHashMap m_cookies; wxStringToStringHashMap m_headers; diff --git a/interface/wx/protocol/http.h b/interface/wx/protocol/http.h index fd72c127a5..e09bb02fb3 100644 --- a/interface/wx/protocol/http.h +++ b/interface/wx/protocol/http.h @@ -90,6 +90,23 @@ public: */ int GetResponse() const; + /** + Set HTTP method. + + Set common + or expanded HTTP method. + + Overrides GET or POST methods that is used by default. + + @param method + HTTP method name, e.g. "GET". + + @since 3.0.0 + + @see SetPostBuffer(), SetPostText() + */ + void SetMethod(const wxString& method); + /** It sets data of a field to be sent during the next request to the HTTP server. diff --git a/src/common/http.cpp b/src/common/http.cpp index 556618aca5..64326690a3 100644 --- a/src/common/http.cpp +++ b/src/common/http.cpp @@ -341,37 +341,23 @@ bool wxHTTP::Connect(const wxSockAddress& addr, bool WXUNUSED(wait)) return true; } -bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req) +bool wxHTTP::BuildRequest(const wxString& path, const wxString& method) { - const wxChar *request; - - switch (req) + // Use the data in the post buffer, if any. + if ( !m_postBuffer.IsEmpty() ) { - case wxHTTP_GET: - request = wxT("GET"); - break; - - case wxHTTP_POST: - request = wxT("POST"); - // Content length must be correct, so always set, possibly - // overriding the value set explicitly by a previous call to - // SetHeader("Content-Length"). - if ( !m_postBuffer.IsEmpty() ) - { - wxString len; - len << m_postBuffer.GetDataLen(); - - SetHeader(wxS("Content-Length"), len); - } - - // However if the user had explicitly set the content type, don't - // override it with the content type passed to SetPostText(). - if ( !m_contentType.empty() && GetContentType().empty() ) - SetHeader(wxS("Content-Type"), m_contentType); - break; - - default: - return false; + wxString len; + len << m_postBuffer.GetDataLen(); + + // Content length must be correct, so always set, possibly + // overriding the value set explicitly by a previous call to + // SetHeader("Content-Length"). + SetHeader(wxS("Content-Length"), len); + + // However if the user had explicitly set the content type, don't + // override it with the content type passed to SetPostText(). + if ( !m_contentType.empty() && GetContentType().empty() ) + SetHeader(wxS("Content-Type"), m_contentType); } m_http_response = 0; @@ -396,15 +382,14 @@ bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req) Notify(false); wxString buf; - buf.Printf(wxT("%s %s HTTP/1.0\r\n"), request, path.c_str()); + buf.Printf(wxT("%s %s HTTP/1.0\r\n"), method, path); const wxWX2MBbuf pathbuf = buf.mb_str(); Write(pathbuf, strlen(pathbuf)); SendHeaders(); Write("\r\n", 2); - if ( req == wxHTTP_POST ) { - if ( !m_postBuffer.IsEmpty() ) - Write(m_postBuffer.GetData(), m_postBuffer.GetDataLen()); + if ( !m_postBuffer.IsEmpty() ) { + Write(m_postBuffer.GetData(), m_postBuffer.GetDataLen()); m_postBuffer.Clear(); } @@ -538,7 +523,13 @@ wxInputStream *wxHTTP::GetInputStream(const wxString& path) return NULL; #endif - if (!BuildRequest(path, m_postBuffer.IsEmpty() ? wxHTTP_GET : wxHTTP_POST)) + // Use the user-specified method if any or determine the method to use + // automatically depending on whether we have anything to post or not. + wxString method = m_method; + if (method.empty()) + method = m_postBuffer.IsEmpty() ? wxS("GET"): wxS("POST"); + + if (!BuildRequest(path, method)) return NULL; inp_stream = new wxHTTPStream(this); -- 2.45.2