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 wxLogFormatter to allow customizing wxLog output (Sébastien Gallou). | ||||||
| - Added "%z" support to wxDateTime::Format() and Parse() (Armel Asselin). | - Added "%z" support to wxDateTime::Format() and Parse() (Armel Asselin). | ||||||
|  | - Add wxHTTP::SetPostBuffer(wxMemoryBuffer) and SetPostText() (Eran Ifrah). | ||||||
|  |  | ||||||
| All (GUI): | All (GUI): | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ | |||||||
|  |  | ||||||
| #include "wx/hashmap.h" | #include "wx/hashmap.h" | ||||||
| #include "wx/protocol/protocol.h" | #include "wx/protocol/protocol.h" | ||||||
|  | #include "wx/buffer.h" | ||||||
|  |  | ||||||
| class WXDLLIMPEXP_NET wxHTTP : public wxProtocol | class WXDLLIMPEXP_NET wxHTTP : public wxProtocol | ||||||
| { | { | ||||||
| @@ -36,13 +37,19 @@ public: | |||||||
|     int GetResponse() const { return m_http_response; } |     int GetResponse() const { return m_http_response; } | ||||||
|  |  | ||||||
|     void SetHeader(const wxString& header, const wxString& h_data); |     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); |     void SetProxyMode(bool on); | ||||||
|  |  | ||||||
|     /* Cookies */ |     /* Cookies */ | ||||||
|     wxString GetCookie(const wxString& cookie) const; |     wxString GetCookie(const wxString& cookie) const; | ||||||
|     bool HasCookies() const { return m_cookies.size() > 0; } |     bool HasCookies() const { return m_cookies.size() > 0; } | ||||||
|  |  | ||||||
|  |     // Use the other SetPostBuffer() overload or SetPostText() instead. | ||||||
|  |     wxDEPRECATED(void SetPostBuffer(const wxString& post_buf)); | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
|     enum wxHTTP_Req |     enum wxHTTP_Req | ||||||
|     { |     { | ||||||
| @@ -80,7 +87,8 @@ protected: | |||||||
|     bool m_read, |     bool m_read, | ||||||
|          m_proxy_mode; |          m_proxy_mode; | ||||||
|     wxSockAddress *m_addr; |     wxSockAddress *m_addr; | ||||||
|     wxString m_post_buf; |     wxMemoryBuffer m_postBuffer; | ||||||
|  |     wxString       m_contentType; | ||||||
|     int m_http_response; |     int m_http_response; | ||||||
|  |  | ||||||
|     DECLARE_DYNAMIC_CLASS(wxHTTP) |     DECLARE_DYNAMIC_CLASS(wxHTTP) | ||||||
|   | |||||||
| @@ -110,12 +110,51 @@ public: | |||||||
|     bool HasCookies() const; |     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 |         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 data from |         be an HTTP @c POST instead of the default HTTP @c GET and the given @a | ||||||
|         @a post_buf will be posted as the body of this request. |         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_addr = NULL; | ||||||
|     m_read = false; |     m_read = false; | ||||||
|     m_proxy_mode = false; |     m_proxy_mode = false; | ||||||
|     m_post_buf = wxEmptyString; |  | ||||||
|     m_http_response = 0; |     m_http_response = 0; | ||||||
|  |  | ||||||
|     SetNotify(wxSOCKET_LOST_FLAG); |     SetNotify(wxSOCKET_LOST_FLAG); | ||||||
| @@ -193,7 +192,41 @@ wxString wxHTTP::GenerateAuthString(const wxString& user, const wxString& pass) | |||||||
|  |  | ||||||
| void wxHTTP::SetPostBuffer(const wxString& post_buf) | 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() | void wxHTTP::SendHeaders() | ||||||
| @@ -312,8 +345,21 @@ bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req) | |||||||
|  |  | ||||||
|         case wxHTTP_POST: |         case wxHTTP_POST: | ||||||
|             request = wxT("POST"); |             request = wxT("POST"); | ||||||
|             if ( GetHeader( wxT("Content-Length") ).empty() ) |             // Content length must be correct, so always set, possibly | ||||||
|                 SetHeader( wxT("Content-Length"), wxString::Format( wxT("%lu"), (unsigned long)m_post_buf.Len() ) ); |             // 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; |             break; | ||||||
|  |  | ||||||
|         default: |         default: | ||||||
| @@ -346,18 +392,10 @@ bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req) | |||||||
|     Write("\r\n", 2); |     Write("\r\n", 2); | ||||||
|  |  | ||||||
|     if ( req == wxHTTP_POST ) { |     if ( req == wxHTTP_POST ) { | ||||||
|         // Post data can be arbitrary binary data when the "binary" content |         if ( !m_postBuffer.IsEmpty() ) | ||||||
|         // transfer encoding is used so don't assume it's ASCII only or |             Write(m_postBuffer.GetData(), m_postBuffer.GetDataLen()); | ||||||
|         // 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 |  | ||||||
|  |  | ||||||
|         m_post_buf = wxEmptyString; |         m_postBuffer.Clear(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     wxString tmp_str; |     wxString tmp_str; | ||||||
| @@ -483,7 +521,7 @@ wxInputStream *wxHTTP::GetInputStream(const wxString& path) | |||||||
|         return NULL; |         return NULL; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     if (!BuildRequest(path, m_post_buf.empty() ? wxHTTP_GET : wxHTTP_POST)) |     if (!BuildRequest(path, m_postBuffer.IsEmpty() ? wxHTTP_GET : wxHTTP_POST)) | ||||||
|         return NULL; |         return NULL; | ||||||
|  |  | ||||||
|     inp_stream = new wxHTTPStream(this); |     inp_stream = new wxHTTPStream(this); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user