diff options
Diffstat (limited to 'protocols/Slack/src/http_request.h')
-rw-r--r-- | protocols/Slack/src/http_request.h | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/protocols/Slack/src/http_request.h b/protocols/Slack/src/http_request.h new file mode 100644 index 0000000000..03f5894c6f --- /dev/null +++ b/protocols/Slack/src/http_request.h @@ -0,0 +1,347 @@ +#ifndef _HTTP_REQUEST_H_ +#define _HTTP_REQUEST_H_ + +typedef void (CSlackProto::*HttpCallback)(NETLIBHTTPREQUEST*, struct AsyncHttpRequest*); + +class HttpRequest; +class HttpResponse; + +struct VALUE +{ + LPCSTR szName; + __forceinline VALUE(LPCSTR _name) : szName(_name) { } +}; + +struct INT_VALUE : public VALUE +{ + int iValue; + __forceinline INT_VALUE(LPCSTR _name, int _value) + : VALUE(_name), iValue(_value) { } +}; + +struct LONG_VALUE : public VALUE +{ + LONGLONG llValue; + __forceinline LONG_VALUE(LPCSTR _name, LONGLONG _value) + : VALUE(_name), llValue(_value) { } +}; + +struct CHAR_VALUE : public VALUE +{ + LPCSTR szValue; + __forceinline CHAR_VALUE(LPCSTR _name, LPCSTR _value) + : VALUE(_name), szValue(_value) { } +}; + +struct ENCODED_VALUE : public VALUE +{ + LPSTR szValue; + __forceinline ENCODED_VALUE(LPCSTR _name, LPCSTR _value) + : VALUE(_name) { szValue = mir_urlEncode(_value); } + __forceinline ~ENCODED_VALUE() { mir_free(szValue); } +}; + +class HttpUri +{ + friend class HttpRequest; + +private: + CMStringA m_uri; + NETLIBHTTPREQUEST *m_request; + + HttpUri(NETLIBHTTPREQUEST *request, const char *uri) + : m_request(request), m_uri(uri) + { + if (m_request) + m_request->szUrl = m_uri.GetBuffer(); + } + + HttpUri(NETLIBHTTPREQUEST *request, const char *urlFormat, va_list args) + : m_request(request) + { + m_uri.AppendFormatV(urlFormat, args); + if (m_request) + m_request->szUrl = m_uri.GetBuffer(); + } + + void Add(const char *fmt, ...) + { + va_list args; + va_start(args, fmt); + m_uri += (m_uri.Find('?') == -1) ? '?' : '&'; + m_uri.AppendFormatV(fmt, args); + va_end(args); + + if (m_request) + m_request->szUrl = m_uri.GetBuffer(); + } + + ~HttpUri() + { + if (m_request) + m_request->szUrl = NULL; + } + +public: + HttpUri& operator=(const HttpUri&); // to prevent copying; + + operator const char*() + { + return m_request + ? m_request->szUrl + : NULL; + } + + HttpUri &operator<<(const VALUE ¶m) + { + Add(param.szName); + return *this; + } + + HttpUri &operator<<(const INT_VALUE ¶m) + { + Add("%s=%i", param.szName, param.iValue); + return *this; + } + + HttpUri &operator<<(const LONG_VALUE ¶m) + { + Add("%s=%lld", param.szName, param.llValue); + return *this; + } + + HttpUri &operator<<(const CHAR_VALUE ¶m) + { + Add("%s=%s", param.szName, param.szValue); + return *this; + } + + HttpUri &operator<<(const ENCODED_VALUE ¶m) + { + Add("%s=%s", param.szName, param.szValue); + return *this; + } +}; + +class HttpHeaders +{ + friend class HttpRequest; + friend class HttpResponse; + +private: + NETLIBHTTPREQUEST *m_request; + + HttpHeaders(NETLIBHTTPREQUEST *request) + : m_request(request) + { + } + + void Add(LPCSTR szName) + { + Add(szName, ""); + } + + void Add(LPCSTR szName, LPCSTR szValue) + { + if (!m_request) + return; + + m_request->headers = (NETLIBHTTPHEADER*)mir_realloc(m_request->headers, + sizeof(NETLIBHTTPHEADER)*(m_request->headersCount + 1)); + m_request->headers[m_request->headersCount].szName = mir_strdup(szName); + m_request->headers[m_request->headersCount].szValue = mir_strdup(szValue); + m_request->headersCount++; + } + +public: + HttpHeaders& operator=(const HttpHeaders&); // to prevent copying; + + const NETLIBHTTPHEADER* operator[](size_t idx) + { + return m_request + ? &m_request->headers[idx] + : NULL; + } + + HttpHeaders& operator<<(const VALUE ¶m) + { + Add(param.szName); + return *this; + } + + HttpHeaders& operator<<(const CHAR_VALUE ¶m) + { + Add(param.szName, param.szValue); + return *this; + } + + HttpHeaders& operator<<(const ENCODED_VALUE ¶m) + { + Add(param.szName, param.szValue); + return *this; + } +}; + +class HttpContent +{ + friend class HttpRequest; + friend class HttpResponse; + +protected: + CMStringA m_content; + NETLIBHTTPREQUEST *m_request; + + HttpContent(NETLIBHTTPREQUEST *request) + : m_request(request) + { + } + + ~HttpContent() + { + if (m_request) + { + m_request->pData = NULL; + m_request->dataLength = 0; + } + } + + void Add(const char *fmt, ...) + { + va_list args; + va_start(args, fmt); + if (!m_content.IsEmpty()) + m_content += '&'; + m_content.AppendFormatV(fmt, args); + va_end(args); + + if (m_request) + { + m_request->pData = m_content.GetBuffer(); + m_request->dataLength = m_content.GetLength(); + } + } + +public: + HttpContent& operator=(const HttpContent&); // to prevent copying; + + bool operator!() const + { + return !m_request || !m_request->pData || !m_request->dataLength; + } + + operator const char*() + { + return m_request + ? m_request->pData + : NULL; + } + + virtual size_t GetSize() const + { + return m_request + ? m_request->dataLength + : 0; + } + + HttpContent & operator<<(const VALUE ¶m) + { + Add(param.szName); + return *this; + } + + HttpContent & operator<<(const INT_VALUE ¶m) + { + Add("%s=%i", param.szName, param.iValue); + return *this; + } + + HttpContent & operator<<(const LONG_VALUE ¶m) + { + Add("%s=%lld", param.szName, param.llValue); + return *this; + } + + HttpContent & operator<<(const CHAR_VALUE ¶m) + { + Add("%s=%s", param.szName, param.szValue); + return *this; + } + + HttpContent &operator<<(const ENCODED_VALUE ¶m) + { + Add("%s=%s", param.szName, param.szValue); + return *this; + } +}; + +enum HttpMethod +{ + HttpGet = 1, + HttpPost +}; + +class HttpResponse +{ + friend class HttpRequest; + +private: + NETLIBHTTPREQUEST *m_response; + +public: + HttpRequest *Request; + HttpHeaders Headers; + HttpContent Content; + + HttpResponse(HttpRequest *request, NETLIBHTTPREQUEST *response) + : Request(request), m_response(response), + Headers(response), Content(response) + { + } + + ~HttpResponse() + { + Netlib_FreeHttpRequest(m_response); + } + + bool IsSuccess() const + { + return m_response->resultCode >= HTTP_CODE_OK && + m_response->resultCode <= HTTP_CODE_MULTI_STATUS; + } + + int GetStatusCode() const + { + return m_response->resultCode; + } +}; + +class HttpRequest : protected NETLIBHTTPREQUEST, public MZeroedObject +{ + friend class HttpUri; + friend class HttpHeaders; + friend class HttpContent; + friend class FormContent; + +public: + HttpUri Uri; + HttpHeaders Headers; + HttpContent Content; + + HttpRequest(HttpMethod method, const char *url) + : Uri(this, url), Headers(this), Content(this) + { + cbSize = sizeof(NETLIBHTTPREQUEST); + requestType = method; + } + + ~HttpRequest() + { + } + + operator NETLIBHTTPREQUEST*() + { + return this; + } +}; + +#endif //_HTTP_REQUEST_H_
\ No newline at end of file |