Add SetPostBuffer(wxMemoryBuffer) and SetPostText() to wxHTTP.
This allows to post binary data or text data in e.g. UTF-8 encoding (which is by far the most common case) easily. Deprecate the existing SetPostBuffer(wxString) as it didn't explicitly specify the encoding to use for the data to be posted. Closes #13870. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70408 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
		| @@ -452,6 +452,7 @@ All: | ||||
|  | ||||
| - Added wxLogFormatter to allow customizing wxLog output (Sébastien Gallou). | ||||
| - Added "%z" support to wxDateTime::Format() and Parse() (Armel Asselin). | ||||
| - Add wxHTTP::SetPostBuffer(wxMemoryBuffer) and SetPostText() (Eran Ifrah). | ||||
|  | ||||
| All (GUI): | ||||
|  | ||||
|   | ||||
| @@ -17,6 +17,7 @@ | ||||
|  | ||||
| #include "wx/hashmap.h" | ||||
| #include "wx/protocol/protocol.h" | ||||
| #include "wx/buffer.h" | ||||
|  | ||||
| class WXDLLIMPEXP_NET wxHTTP : public wxProtocol | ||||
| { | ||||
| @@ -36,13 +37,19 @@ public: | ||||
|     int GetResponse() const { return m_http_response; } | ||||
|  | ||||
|     void SetHeader(const wxString& header, const wxString& h_data); | ||||
|     void SetPostBuffer(const wxString& post_buf); | ||||
|     bool SetPostText(const wxString& contentType, | ||||
|                      const wxString& data, | ||||
|                      const wxMBConv& conv = wxConvUTF8); | ||||
|     bool SetPostBuffer(const wxString& contentType, const wxMemoryBuffer& data); | ||||
|     void SetProxyMode(bool on); | ||||
|  | ||||
|     /* Cookies */ | ||||
|     wxString GetCookie(const wxString& cookie) const; | ||||
|     bool HasCookies() const { return m_cookies.size() > 0; } | ||||
|  | ||||
|     // Use the other SetPostBuffer() overload or SetPostText() instead. | ||||
|     wxDEPRECATED(void SetPostBuffer(const wxString& post_buf)); | ||||
|  | ||||
| protected: | ||||
|     enum wxHTTP_Req | ||||
|     { | ||||
| @@ -80,7 +87,8 @@ protected: | ||||
|     bool m_read, | ||||
|          m_proxy_mode; | ||||
|     wxSockAddress *m_addr; | ||||
|     wxString m_post_buf; | ||||
|     wxMemoryBuffer m_postBuffer; | ||||
|     wxString       m_contentType; | ||||
|     int m_http_response; | ||||
|  | ||||
|     DECLARE_DYNAMIC_CLASS(wxHTTP) | ||||
|   | ||||
| @@ -110,12 +110,51 @@ public: | ||||
|     bool HasCookies() const; | ||||
|  | ||||
|     /** | ||||
|         Set the data to be posted to the server. | ||||
|         Set the binary data to be posted to the server. | ||||
|  | ||||
|         If a non-empty string is passed to this method, the next request will | ||||
|         be an HTTP @c POST instead of the default HTTP @c GET and the data from | ||||
|         @a post_buf will be posted as the body of this request. | ||||
|         If a non-empty buffer is passed to this method, the next request will | ||||
|         be an HTTP @c POST instead of the default HTTP @c GET and the given @a | ||||
|         data will be posted as the body of this request. | ||||
|  | ||||
|         For textual data a more convenient SetPostText() can be used instead. | ||||
|  | ||||
|         @param contentType | ||||
|             The value of HTTP "Content-Type" header, e.g. "image/png". | ||||
|         @param data | ||||
|             The data to post. | ||||
|         @return | ||||
|             @true if any data was passed in or @false if the buffer was empty. | ||||
|  | ||||
|         @since 2.9.4 | ||||
|      */ | ||||
|     void SetPostBuffer(const wxString& post_buf); | ||||
|     bool SetPostBuffer(const wxString& contentType, const wxMemoryBuffer& data); | ||||
|  | ||||
|     /** | ||||
|         Set the text to be posted to the server. | ||||
|  | ||||
|         After a successful call to this method, the request will use HTTP @c | ||||
|         POST instead of the default @c GET when it's executed. | ||||
|  | ||||
|         Use SetPostBuffer() if you need to post non-textual data. | ||||
|  | ||||
|         @param contentType | ||||
|             The value of HTTP "Content-Type" header, e.g. "text/html; | ||||
|             charset=UTF-8". | ||||
|         @param data | ||||
|             The data to post. | ||||
|         @param conv | ||||
|             The conversion to use to convert @a data contents to a byte stream. | ||||
|             Its value should be consistent with the charset parameter specified | ||||
|             in @a contentType. | ||||
|         @return | ||||
|             @true if string was non-empty and was successfully converted using | ||||
|             the given @a conv or @false otherwise (in this case this request | ||||
|             won't be @c POST'ed correctly). | ||||
|  | ||||
|         @since 2.9.4 | ||||
|      */ | ||||
|     bool SetPostText(const wxString& contentType, | ||||
|                      const wxString& data, | ||||
|                      const wxMBConv& conv = wxConvUTF8); | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -48,7 +48,6 @@ wxHTTP::wxHTTP() | ||||
|     m_addr = NULL; | ||||
|     m_read = false; | ||||
|     m_proxy_mode = false; | ||||
|     m_post_buf = wxEmptyString; | ||||
|     m_http_response = 0; | ||||
|  | ||||
|     SetNotify(wxSOCKET_LOST_FLAG); | ||||
| @@ -193,7 +192,41 @@ wxString wxHTTP::GenerateAuthString(const wxString& user, const wxString& pass) | ||||
|  | ||||
| void wxHTTP::SetPostBuffer(const wxString& post_buf) | ||||
| { | ||||
|     m_post_buf = post_buf; | ||||
|     // Use To8BitData() for backwards compatibility in this deprecated method. | ||||
|     // The new code should use the other overload or SetPostText() and specify | ||||
|     // the encoding to use for the text explicitly. | ||||
|     wxScopedCharBuffer scb = post_buf.To8BitData(); | ||||
|     if ( scb.length() ) | ||||
|     { | ||||
|         m_postBuffer.Clear(); | ||||
|         m_postBuffer.AppendData(scb.data(), scb.length()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool | ||||
| wxHTTP::SetPostBuffer(const wxString& contentType, | ||||
|                       const wxMemoryBuffer& data) | ||||
| { | ||||
|     m_postBuffer = data; | ||||
|     m_contentType = contentType; | ||||
|  | ||||
|     return !m_postBuffer.IsEmpty(); | ||||
| } | ||||
|  | ||||
| bool | ||||
| wxHTTP::SetPostText(const wxString& contentType, | ||||
|                     const wxString& data, | ||||
|                     const wxMBConv& conv) | ||||
| { | ||||
|     wxScopedCharBuffer scb = data.mb_str(conv); | ||||
|     if ( !scb.length() ) | ||||
|         return false; | ||||
|  | ||||
|     m_postBuffer.Clear(); | ||||
|     m_postBuffer.AppendData(scb.data(), scb.length()); | ||||
|     m_contentType = contentType; | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| void wxHTTP::SendHeaders() | ||||
| @@ -312,8 +345,21 @@ bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req) | ||||
|  | ||||
|         case wxHTTP_POST: | ||||
|             request = wxT("POST"); | ||||
|             if ( GetHeader( wxT("Content-Length") ).empty() ) | ||||
|                 SetHeader( wxT("Content-Length"), wxString::Format( wxT("%lu"), (unsigned long)m_post_buf.Len() ) ); | ||||
|             // 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: | ||||
| @@ -346,18 +392,10 @@ bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req) | ||||
|     Write("\r\n", 2); | ||||
|  | ||||
|     if ( req == wxHTTP_POST ) { | ||||
|         // Post data can be arbitrary binary data when the "binary" content | ||||
|         // transfer encoding is used so don't assume it's ASCII only or | ||||
|         // NUL-terminated. | ||||
|         { | ||||
|             const wxScopedCharBuffer buf(m_post_buf.To8BitData()); | ||||
|             Write(buf, buf.length()); | ||||
|         } // delete the buffer before modifying the string it points to, it | ||||
|           // wouldn't really be a problem here even if we didn't do this | ||||
|           // because we won't use this buffer again but this will avoid any | ||||
|           // nasty surprises in the future if this code changes | ||||
|         if ( !m_postBuffer.IsEmpty() ) | ||||
|             Write(m_postBuffer.GetData(), m_postBuffer.GetDataLen()); | ||||
|  | ||||
|         m_post_buf = wxEmptyString; | ||||
|         m_postBuffer.Clear(); | ||||
|     } | ||||
|  | ||||
|     wxString tmp_str; | ||||
| @@ -483,7 +521,7 @@ wxInputStream *wxHTTP::GetInputStream(const wxString& path) | ||||
|         return NULL; | ||||
| #endif | ||||
|  | ||||
|     if (!BuildRequest(path, m_post_buf.empty() ? wxHTTP_GET : wxHTTP_POST)) | ||||
|     if (!BuildRequest(path, m_postBuffer.IsEmpty() ? wxHTTP_GET : wxHTTP_POST)) | ||||
|         return NULL; | ||||
|  | ||||
|     inp_stream = new wxHTTPStream(this); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user