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