summaryrefslogtreecommitdiff
path: root/protocols/Steam/src/http_request.h
diff options
context:
space:
mode:
authoraunsane <aunsane@gmail.com>2017-12-28 21:21:10 +0300
committeraunsane <aunsane@gmail.com>2017-12-28 21:21:28 +0300
commit0156ed41dceeef48f070adf67f14d4ba4c4f6d61 (patch)
treed0e1dca4c2c9c3c056ae9cb69dde10ea59316481 /protocols/Steam/src/http_request.h
parentf0075f2b956969f29acd3bc9289c8a5f78faddad (diff)
Steam: refactoring
- reworking http requests - added ability to get game name by appid - another attempt to fix #633 - minor refactoring
Diffstat (limited to 'protocols/Steam/src/http_request.h')
-rw-r--r--protocols/Steam/src/http_request.h413
1 files changed, 312 insertions, 101 deletions
diff --git a/protocols/Steam/src/http_request.h b/protocols/Steam/src/http_request.h
index 841910dc32..43bb68d464 100644
--- a/protocols/Steam/src/http_request.h
+++ b/protocols/Steam/src/http_request.h
@@ -1,166 +1,377 @@
#ifndef _HTTP_REQUEST_H_
#define _HTTP_REQUEST_H_
-class HttpResponse : public NETLIBHTTPREQUEST, public MZeroedObject
+class HttpRequest;
+class HttpResponse;
+
+class HttpUri
{
+ friend class HttpRequest;
+
private:
- bool isEmptyResponse;
+ 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();
+ }
+
+ ~HttpUri()
+ {
+ if (m_request)
+ m_request->szUrl = NULL;
+ }
+
+ void FormatV(const char *urlFormat, va_list args)
+ {
+ m_uri.AppendFormatV(urlFormat, args);
+ if (m_request)
+ m_request->szUrl = m_uri.GetBuffer();
+ }
+
+ void AppendFormat(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();
+ }
public:
- const NETLIBHTTPREQUEST* request;
+ HttpUri& operator=(const HttpUri&); // to prevent copying;
- HttpResponse(const NETLIBHTTPREQUEST* response, const NETLIBHTTPREQUEST* request = NULL)
+ operator const char*() const
{
- this->request = request;
- isEmptyResponse = (response == NULL);
- if (response)
- {
- cbSize = response->cbSize;
- requestType = response->requestType;
- flags = response->flags;
- szUrl = mir_strdup(response->szUrl);
- headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER) * response->headersCount);
- headersCount = response->headersCount;
- for (int i = 0; i < headersCount; i++)
- {
- headers[i].szName = mir_strdup(response->headers[i].szName);
- headers[i].szValue = mir_strdup(response->headers[i].szValue);
- }
- pData = (char*)mir_alloc(response->dataLength);
- dataLength = response->dataLength;
- memcpy(pData, response->pData, dataLength);
- resultCode = response->resultCode;
- szResultDescr = mir_strdup(response->szResultDescr);
- nlc = response->nlc;
- timeout = response->timeout;
- }
- else if (request != NULL)
- {
- // when response is null, we must get resultCode from the request object
- resultCode = request->resultCode;
- }
+ return m_request
+ ? m_request->szUrl
+ : NULL;
}
- bool const operator !() const
+ HttpUri &operator<<(const PARAM &param)
{
- return isEmptyResponse;
+ AppendFormat(param.szName);
+ return *this;
}
- ~HttpResponse()
+ HttpUri &operator<<(const INT_PARAM &param)
{
- for (int i = 0; i < headersCount; i++)
- {
- mir_free(headers[i].szName);
- mir_free(headers[i].szValue);
- }
- mir_free(szUrl);
- mir_free(headers);
- mir_free(pData);
- mir_free(szResultDescr);
+ AppendFormat("%s=%i", param.szName, param.iValue);
+ return *this;
+ }
+
+ HttpUri &operator<<(const INT64_PARAM &param)
+ {
+ AppendFormat("%s=%lld", param.szName, param.iValue);
+ return *this;
+ }
+
+ HttpUri &operator<<(const CHAR_PARAM &param)
+ {
+ AppendFormat("%s=%s", param.szName, ptrA(mir_urlEncode(param.szValue)));
+ return *this;
}
};
-class HttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject
+class HttpHeaders
{
+ friend class HttpContent;
+ friend class HttpRequest;
+ friend class HttpResponse;
+
private:
- CMStringA m_url;
+ NETLIBHTTPREQUEST *m_request;
+
+ HttpHeaders(NETLIBHTTPREQUEST *request)
+ : m_request(request)
+ {
+ }
+
+ void Set(LPCSTR szName)
+ {
+ Set(szName, "");
+ }
+
+ void Set(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) const
+ {
+ return m_request
+ ? &m_request->headers[idx]
+ : NULL;
+ }
+
+ size_t GetSize() const
+ {
+ return m_request
+ ? m_request->headersCount
+ : 0;
+ }
+
+ HttpHeaders& operator<<(const PARAM &param)
+ {
+ Set(param.szName);
+ return *this;
+ }
+
+ HttpHeaders& operator<<(const CHAR_PARAM &param)
+ {
+ Set(param.szName, param.szValue);
+ return *this;
+ }
+};
+
+class HttpContent
+{
+ friend class HttpRequest;
+ friend class HttpResponse;
protected:
- enum HttpRequestUrlFormat { FORMAT };
+ HttpHeaders Headers;
+ NETLIBHTTPREQUEST *m_request;
- void Init(int type)
+ HttpContent(NETLIBHTTPREQUEST *request)
+ : Headers(request), m_request(request)
{
- cbSize = sizeof(NETLIBHTTPREQUEST);
- requestType = type;
- flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT;
- AddHeader("user-agent", "Steam 1.2.0 / iPhone");
}
- void AddHeader(LPCSTR szName, LPCSTR szValue)
+ virtual ~HttpContent()
+ {
+ if (m_request)
+ {
+ m_request->pData = nullptr;
+ m_request->dataLength = 0;
+ }
+ }
+
+public:
+ HttpContent& operator=(const HttpContent&); // to prevent copying;
+
+ operator bool() const
+ {
+ return m_request && m_request->pData && m_request->dataLength;
+ }
+
+ operator const char*() const
{
- headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1));
- headers[headersCount].szName = mir_strdup(szName);
- headers[headersCount].szValue = mir_strdup(szValue);
- headersCount++;
+ return m_request
+ ? m_request->pData
+ : nullptr;
}
- void AddParameter(const char *fmt, ...)
+ const char* GetData() const
+ {
+ return m_request
+ ? m_request->pData
+ : nullptr;
+ }
+
+ size_t GetSize() const
+ {
+ return m_request
+ ? m_request->dataLength
+ : 0;
+ }
+};
+
+class FormUrlEncodedContent : public HttpContent
+{
+ friend FormUrlEncodedContent* operator<<(FormUrlEncodedContent*, const PARAM&);
+ friend FormUrlEncodedContent* operator<<(FormUrlEncodedContent*, const BOOL_PARAM&);
+ friend FormUrlEncodedContent* operator<<(FormUrlEncodedContent*, const INT_PARAM&);
+ friend FormUrlEncodedContent* operator<<(FormUrlEncodedContent*, const INT64_PARAM&);
+ friend FormUrlEncodedContent* operator<<(FormUrlEncodedContent*, const CHAR_PARAM&);
+
+private:
+ CMStringA m_content;
+
+ void AppendFormat(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
- m_url += m_url.Find('?') == -1 ? '?' : '&';
- m_url.AppendFormatV(fmt, args);
+ 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();
+ }
}
- void AddParameter(LPCSTR name, LPCSTR value)
+public:
+ FormUrlEncodedContent(NETLIBHTTPREQUEST *request)
+ : HttpContent(request)
{
- AddParameter("%s=%s", name, value);
+ Headers << CHAR_PARAM("Content-Type", "application/x-www-form-urlencoded");
}
+};
+
+__forceinline FormUrlEncodedContent* operator<<(FormUrlEncodedContent *content, const PARAM &param)
+{
+ content->AppendFormat(param.szName);
+ return content;
+}
- void SetData(const char *data, size_t size)
+__forceinline FormUrlEncodedContent* operator<<(FormUrlEncodedContent *content, const BOOL_PARAM &param)
+{
+ content->AppendFormat("%s=%s", param.szName, param.bValue ? "true" : "false");
+ return content;
+}
+
+__forceinline FormUrlEncodedContent* operator<<(FormUrlEncodedContent *content, const INT_PARAM &param)
+{
+ content->AppendFormat("%s=%i", param.szName, param.iValue);
+ return content;
+}
+
+__forceinline FormUrlEncodedContent* operator<<(FormUrlEncodedContent *content, const INT64_PARAM &param)
+{
+ content->AppendFormat("%s=%lld", param.szName, param.iValue);
+ return content;
+}
+
+__forceinline FormUrlEncodedContent* operator<<(FormUrlEncodedContent *content, const CHAR_PARAM &param)
+{
+ content->AppendFormat("%s=%s", param.szName, ptrA(mir_urlEncode(param.szValue)));
+ return content;
+}
+
+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 operator!() const
{
- if (pData != NULL)
- mir_free(pData);
+ return !m_response || !m_response->pData;
+ }
+
+ operator bool() const
+ {
+ return m_response && m_response->pData;
+ }
- dataLength = (int)size;
- pData = (char*)mir_alloc(size + 1);
- memcpy(pData, data, size);
- pData[size] = 0;
+ bool IsSuccess() const
+ {
+ return m_response &&
+ 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;
+
+protected:
+ enum HttpRequestUrlFormat { FORMAT };
public:
- HttpRequest(int type, LPCSTR url)
+ HttpUri Uri;
+ HttpHeaders Headers;
+ HttpContent *Content;
+
+ HttpRequest(HttpMethod method, const char *url)
+ : Uri(this, url), Headers(this), Content(nullptr)
{
- Init(type);
+ cbSize = sizeof(NETLIBHTTPREQUEST);
+ requestType = method;
+ flags = NLHRF_HTTP11 | NLHRF_SSL;
- m_url = url;
+ Content = new HttpContent(this);
}
- HttpRequest(int type, HttpRequestUrlFormat, LPCSTR urlFormat, ...)
+ HttpRequest(HttpMethod method, HttpRequestUrlFormat, const char *urlFormat, ...)
+ : Uri(this, urlFormat), Headers(this), Content(nullptr)
{
- Init(type);
+ cbSize = sizeof(NETLIBHTTPREQUEST);
+ requestType = method;
+ flags = NLHRF_HTTP11 | NLHRF_SSL;
va_list formatArgs;
va_start(formatArgs, urlFormat);
- m_url.AppendFormatV(urlFormat, formatArgs);
+ Uri.FormatV(urlFormat, formatArgs);
va_end(formatArgs);
+
+ Content = new HttpContent(this);
}
~HttpRequest()
{
- for (int i = 0; i < headersCount; i++)
+ if (Content != nullptr)
{
- mir_free(headers[i].szName);
- mir_free(headers[i].szValue);
+ delete Content;
+ Content = nullptr;
}
- mir_free(headers);
-
- if (pData != NULL)
- mir_free(pData);
}
- HttpResponse* Send(HNETLIBUSER nlu)
+ operator NETLIBHTTPREQUEST*()
{
- szUrl = m_url.GetBuffer();
-
- Netlib_Logf(nlu, "Send request to %s", szUrl);
-
- NETLIBHTTPREQUEST* response = Netlib_HttpTransaction(nlu, this);
- HttpResponse* result = new HttpResponse(response, this);
- Netlib_FreeHttpRequest(response);
-
- return result;
+ return this;
}
};
-
-bool __forceinline ResponseHttpOk(const HttpResponse *response) {
- return (response && response->pData && (response->resultCode == HTTP_CODE_OK));
-}
-
-bool __forceinline CheckResponse(const HttpResponse *response) {
- return (response && response->pData);
-}
-
#endif //_HTTP_REQUEST_H_ \ No newline at end of file