Added form POSTing and HTTP error code handling to Webternet (bug 3530, r=pred).
This commit is contained in:
		
							parent
							
								
									7b6dcfce87
								
							
						
					
					
						commit
						0cf5f4ae2a
					
				@ -2,6 +2,32 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Webternet g_webternet;
 | 
					Webternet g_webternet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WebForm::WebForm() : first(NULL), last(NULL), lastError(CURL_FORMADD_OK)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool WebForm::AddString(const char *name, const char *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						lastError = curl_formadd(&first,
 | 
				
			||||||
 | 
							&last,
 | 
				
			||||||
 | 
							CURLFORM_COPYNAME,
 | 
				
			||||||
 | 
							name,
 | 
				
			||||||
 | 
							CURLFORM_COPYCONTENTS,
 | 
				
			||||||
 | 
							data,
 | 
				
			||||||
 | 
							CURLFORM_END);
 | 
				
			||||||
 | 
						return lastError == CURL_FORMADD_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					curl_httppost *WebForm::GetFormData()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return first;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WebForm::~WebForm()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						curl_formfree(first);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WebTransfer *WebTransfer::CreateWebSession()
 | 
					WebTransfer *WebTransfer::CreateWebSession()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	CURL *curl;
 | 
						CURL *curl;
 | 
				
			||||||
@ -46,6 +72,12 @@ bool WebTransfer::SetHeaderReturn(bool recv_hdr)
 | 
				
			|||||||
	return lastError == 0;
 | 
						return lastError == 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool WebTransfer::SetFailOnHTTPError(bool fail)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						lastError = curl_easy_setopt(curl, CURLOPT_FAILONERROR, fail ? 1 : 0);
 | 
				
			||||||
 | 
						return lastError == 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static size_t curl_write_to_sm(void *ptr, size_t bytes, size_t nmemb, void *stream)
 | 
					static size_t curl_write_to_sm(void *ptr, size_t bytes, size_t nmemb, void *stream)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	void **userdata = (void **)stream;
 | 
						void **userdata = (void **)stream;
 | 
				
			||||||
@ -81,6 +113,12 @@ bool WebTransfer::Download(const char *url, ITransferHandler *handler, void *dat
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lastError = curl_easy_setopt(curl, CURLOPT_HTTPPOST, NULL);
 | 
				
			||||||
 | 
						if (lastError)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lastError = curl_easy_setopt(curl, CURLOPT_URL, url);
 | 
						lastError = curl_easy_setopt(curl, CURLOPT_URL, url);
 | 
				
			||||||
	if (lastError)
 | 
						if (lastError)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -92,6 +130,46 @@ bool WebTransfer::Download(const char *url, ITransferHandler *handler, void *dat
 | 
				
			|||||||
	return (lastError == 0);
 | 
						return (lastError == 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool WebTransfer::PostAndDownload(const char *url,
 | 
				
			||||||
 | 
													  IWebForm *form,
 | 
				
			||||||
 | 
													  ITransferHandler *handler,
 | 
				
			||||||
 | 
													  void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						WebForm *realform = (WebForm*)form;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lastError = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_to_sm);
 | 
				
			||||||
 | 
						if (lastError)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *userdata[3];
 | 
				
			||||||
 | 
						userdata[0] = this;
 | 
				
			||||||
 | 
						userdata[1] = handler;
 | 
				
			||||||
 | 
						userdata[2] = data;
 | 
				
			||||||
 | 
						lastError = curl_easy_setopt(curl, CURLOPT_WRITEDATA, userdata);
 | 
				
			||||||
 | 
						if (lastError)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lastError = curl_easy_setopt(curl, CURLOPT_HTTPPOST, realform->GetFormData());
 | 
				
			||||||
 | 
						if (lastError)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lastError = curl_easy_setopt(curl, CURLOPT_URL, url);
 | 
				
			||||||
 | 
						if (lastError)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lastError = curl_easy_perform(curl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (lastError == 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WebTransfer::~WebTransfer()
 | 
					WebTransfer::~WebTransfer()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	curl_easy_cleanup(curl);
 | 
						curl_easy_cleanup(curl);
 | 
				
			||||||
@ -112,3 +190,7 @@ IWebTransfer *Webternet::CreateSession()
 | 
				
			|||||||
	return WebTransfer::CreateWebSession();
 | 
						return WebTransfer::CreateWebSession();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IWebForm *Webternet::CreateForm()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return new WebForm();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,21 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using namespace SourceMod;
 | 
					using namespace SourceMod;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WebForm : public IWebForm
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						WebForm();
 | 
				
			||||||
 | 
						~WebForm();
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						bool AddString(const char *name, const char *data);
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						curl_httppost *GetFormData();
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						curl_httppost *first;
 | 
				
			||||||
 | 
						curl_httppost *last;
 | 
				
			||||||
 | 
						CURLFORMcode lastError;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WebTransfer : public IWebTransfer
 | 
					class WebTransfer : public IWebTransfer
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
@ -48,6 +63,11 @@ public:
 | 
				
			|||||||
	int LastErrorCode();
 | 
						int LastErrorCode();
 | 
				
			||||||
	bool SetHeaderReturn(bool recv_hdr);
 | 
						bool SetHeaderReturn(bool recv_hdr);
 | 
				
			||||||
	bool Download(const char *url, ITransferHandler *handler, void *data);
 | 
						bool Download(const char *url, ITransferHandler *handler, void *data);
 | 
				
			||||||
 | 
						bool SetFailOnHTTPError(bool fail);
 | 
				
			||||||
 | 
						bool PostAndDownload(const char *url,
 | 
				
			||||||
 | 
							IWebForm *form,
 | 
				
			||||||
 | 
							ITransferHandler *handler,
 | 
				
			||||||
 | 
							void *data);
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	CURL *curl;
 | 
						CURL *curl;
 | 
				
			||||||
	char errorBuffer[CURL_ERROR_SIZE];
 | 
						char errorBuffer[CURL_ERROR_SIZE];
 | 
				
			||||||
@ -61,6 +81,7 @@ public:
 | 
				
			|||||||
	const char *GetInterfaceName();
 | 
						const char *GetInterfaceName();
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	IWebTransfer *CreateSession();
 | 
						IWebTransfer *CreateSession();
 | 
				
			||||||
 | 
						IWebForm *CreateForm();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern Webternet g_webternet;
 | 
					extern Webternet g_webternet;
 | 
				
			||||||
 | 
				
			|||||||
@ -40,7 +40,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SMINTERFACE_WEBTERNET_NAME		"IWebternet"
 | 
					#define SMINTERFACE_WEBTERNET_NAME		"IWebternet"
 | 
				
			||||||
#define SMINTERFACE_WEBTERNET_VERSION	1
 | 
					#define SMINTERFACE_WEBTERNET_VERSION	3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SourceMod
 | 
					namespace SourceMod
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -56,6 +56,31 @@ namespace SourceMod
 | 
				
			|||||||
	class IWebTransfer;
 | 
						class IWebTransfer;
 | 
				
			||||||
	class IWebternet;
 | 
						class IWebternet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @brief Form for POSTing data.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						class IWebForm
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * @brief Free with delete.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							virtual ~IWebForm()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * @brief Adds raw data to the form.
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * All data is copied locally and may go out of scope.
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * @param name				Field name (null terminated).
 | 
				
			||||||
 | 
							 * @param data				Field data (null terminated).
 | 
				
			||||||
 | 
							 * @return					True on success, false on failure.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							virtual bool AddString(const char *name, const char *data) = 0;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @brief Transfer handler interface.
 | 
						 * @brief Transfer handler interface.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
@ -139,6 +164,30 @@ namespace SourceMod
 | 
				
			|||||||
		 * @return					True on success, false on failure.
 | 
							 * @return					True on success, false on failure.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		virtual bool Download(const char *url, ITransferHandler *handler, void *data) = 0;
 | 
							virtual bool Download(const char *url, ITransferHandler *handler, void *data) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * @brief Downloads a URL with POST options.
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * @param url				URL to download.
 | 
				
			||||||
 | 
							 * @param form				Form to read POST info from.
 | 
				
			||||||
 | 
							 * @param handler			Handler object.
 | 
				
			||||||
 | 
							 * @param userdata			User data pointer.
 | 
				
			||||||
 | 
							 * @return					True on success, false on failure.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							virtual bool PostAndDownload(const char *url,
 | 
				
			||||||
 | 
								IWebForm *form,
 | 
				
			||||||
 | 
								ITransferHandler *handler,
 | 
				
			||||||
 | 
								void *data) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * @brief Sets whether an HTTP failure (>= 400) returns false from Download().
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * Note: defaults to false.
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * @param fail				True to fail, false otherwise.
 | 
				
			||||||
 | 
							 * @return					True on success, false otherwise.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							virtual bool SetFailOnHTTPError(bool fail) = 0;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@ -156,6 +205,13 @@ namespace SourceMod
 | 
				
			|||||||
		 * @return				Object, or NULL on failure.
 | 
							 * @return				Object, or NULL on failure.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		virtual IWebTransfer *CreateSession() = 0;
 | 
							virtual IWebTransfer *CreateSession() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * @brief Creates a form for building POST data.
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * @return				New form, or NULL on failure.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							virtual IWebForm *CreateForm() = 0;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user