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; | ||||
| 
 | ||||
| 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() | ||||
| { | ||||
| 	CURL *curl; | ||||
| @ -46,6 +72,12 @@ bool WebTransfer::SetHeaderReturn(bool recv_hdr) | ||||
| 	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) | ||||
| { | ||||
| 	void **userdata = (void **)stream; | ||||
| @ -81,6 +113,52 @@ bool WebTransfer::Download(const char *url, ITransferHandler *handler, void *dat | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	lastError = curl_easy_setopt(curl, CURLOPT_HTTPPOST, NULL); | ||||
| 	if (lastError) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	lastError = curl_easy_setopt(curl, CURLOPT_URL, url); | ||||
| 	if (lastError) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	lastError = curl_easy_perform(curl); | ||||
| 	 | ||||
| 	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) | ||||
| 	{ | ||||
| @ -112,3 +190,7 @@ IWebTransfer *Webternet::CreateSession() | ||||
| 	return WebTransfer::CreateWebSession(); | ||||
| } | ||||
| 
 | ||||
| IWebForm *Webternet::CreateForm() | ||||
| { | ||||
| 	return new WebForm(); | ||||
| } | ||||
|  | ||||
| @ -37,6 +37,21 @@ | ||||
| 
 | ||||
| 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 | ||||
| { | ||||
| public: | ||||
| @ -48,6 +63,11 @@ public: | ||||
| 	int LastErrorCode(); | ||||
| 	bool SetHeaderReturn(bool recv_hdr); | ||||
| 	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: | ||||
| 	CURL *curl; | ||||
| 	char errorBuffer[CURL_ERROR_SIZE]; | ||||
| @ -61,6 +81,7 @@ public: | ||||
| 	const char *GetInterfaceName(); | ||||
| public: | ||||
| 	IWebTransfer *CreateSession(); | ||||
| 	IWebForm *CreateForm(); | ||||
| }; | ||||
| 
 | ||||
| extern Webternet g_webternet; | ||||
|  | ||||
| @ -40,7 +40,7 @@ | ||||
|  */ | ||||
| 
 | ||||
| #define SMINTERFACE_WEBTERNET_NAME		"IWebternet" | ||||
| #define SMINTERFACE_WEBTERNET_VERSION	1 | ||||
| #define SMINTERFACE_WEBTERNET_VERSION	3 | ||||
| 
 | ||||
| namespace SourceMod | ||||
| { | ||||
| @ -56,6 +56,31 @@ namespace SourceMod | ||||
| 	class IWebTransfer; | ||||
| 	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. | ||||
| 	 */ | ||||
| @ -139,6 +164,30 @@ namespace SourceMod | ||||
| 		 * @return					True on success, false on failure. | ||||
| 		 */ | ||||
| 		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. | ||||
| 		 */ | ||||
| 		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