aboutsummaryrefslogtreecommitdiff
path: root/Src/auth/post.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/auth/post.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/auth/post.cpp')
-rw-r--r--Src/auth/post.cpp218
1 files changed, 218 insertions, 0 deletions
diff --git a/Src/auth/post.cpp b/Src/auth/post.cpp
new file mode 100644
index 00000000..db755671
--- /dev/null
+++ b/Src/auth/post.cpp
@@ -0,0 +1,218 @@
+#include "api.h"
+#include "../xml/obj_xml.h"
+#include "api_auth.h"
+#include "../nu/AutoChar.h"
+#include "../jnetlib/api_httpget.h"
+#include "ifc_authcallback.h"
+#include <api/service/waservicefactory.h>
+#include <strsafe.h>
+
+
+static const GUID internetConfigGroupGUID =
+{
+ 0xc0a565dc, 0xcfe, 0x405a, { 0xa2, 0x7c, 0x46, 0x8b, 0xc, 0x8a, 0x3a, 0x5c }
+};
+
+
+#define USER_AGENT_SIZE (10 /*User-Agent*/ + 2 /*: */ + 6 /*Winamp*/ + 1 /*/*/ + 1 /*5*/ + 3/*.55*/ + 1 /*Null*/)
+static void SetUserAgent(api_httpreceiver *http)
+{
+ char user_agent[USER_AGENT_SIZE] = {0};
+ StringCchPrintfA(user_agent, USER_AGENT_SIZE, "User-Agent: Winamp/%S", WASABI_API_APP->main_getVersionNumString());
+ http->addheader(user_agent);
+}
+
+
+#define HTTP_BUFFER_SIZE 8192
+
+static int FeedXMLHTTP(api_httpreceiver *http, obj_xml *parser, bool *noData)
+{
+ char downloadedData[HTTP_BUFFER_SIZE] = {0};
+ int xmlResult = API_XML_SUCCESS;
+ int downloadSize = http->get_bytes(downloadedData, HTTP_BUFFER_SIZE);
+ if (downloadSize)
+ {
+ xmlResult = parser->xmlreader_feed((void *)downloadedData, downloadSize);
+ *noData=false;
+ }
+ else
+ *noData = true;
+
+ return xmlResult;
+}
+
+
+static int RunXMLDownload(api_httpreceiver *http, obj_xml *parser, ifc_authcallback *callback)
+{
+ int ret;
+ bool noData;
+ do
+ {
+ if (callback && callback->OnIdle())
+ {
+ return AUTH_ABORT;
+ }
+ else if (!callback)
+ {
+ Sleep(50);
+ }
+
+ ret = http->run();
+ if (FeedXMLHTTP(http, parser, &noData) != API_XML_SUCCESS)
+ return AUTH_ERROR_PARSING_XML;
+ }
+ while (ret == HTTPRECEIVER_RUN_OK);
+
+ // finish off the data
+ do
+ {
+ if (FeedXMLHTTP(http, parser, &noData) != API_XML_SUCCESS)
+ return AUTH_ERROR_PARSING_XML;
+ } while (!noData);
+
+ parser->xmlreader_feed(0, 0);
+ if (ret != HTTPRECEIVER_RUN_ERROR)
+ return AUTH_SUCCESS;
+ else
+ return AUTH_CONNECTIONRESET;
+}
+
+
+int PostXML(const char *url, const char *post_data, obj_xml *parser, ifc_authcallback *callback)
+{
+ if (!parser)
+ return AUTH_NOPARSER;
+
+ api_httpreceiver *http = 0;
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(httpreceiverGUID);
+ if (sf)
+ http = (api_httpreceiver *)sf->getInterface();
+
+ if (!http)
+ return AUTH_NOHTTP;
+
+ int use_proxy = 1;
+ bool proxy80 = AGAVE_API_CONFIG->GetBool(internetConfigGroupGUID, L"proxy80", false);
+ if (proxy80 && strstr(url, ":") && (!strstr(url, ":80/") && strstr(url, ":80") != (url + strlen(url) - 3)))
+ use_proxy = 0;
+
+ const wchar_t *proxy = use_proxy?AGAVE_API_CONFIG->GetString(internetConfigGroupGUID, L"proxy", 0):0;
+ size_t clen = strlen(post_data);
+
+ http->open(API_DNS_AUTODNS, HTTP_BUFFER_SIZE, (proxy && proxy[0]) ? (const char *)AutoChar(proxy) : NULL);
+ SetUserAgent(http);
+
+ char clen_header[1024] = {0};
+ StringCbPrintfA(clen_header, sizeof(clen_header), "Content-Length: %u", clen);
+ http->addheader(clen_header);
+ http->addheader("Content-Type: application/x-www-form-urlencoded; charset=UTF-8");
+ if (callback && callback->OnConnecting())
+ {
+ sf->releaseInterface(http);
+ return AUTH_ABORT;
+ }
+ http->connect(url, 0, "POST");
+
+ // POST the data
+ api_connection *connection = http->GetConnection();
+ if (connection)
+ {
+ if (callback && callback->OnIdle())
+ {
+ sf->releaseInterface(http);
+ return AUTH_ABORT;
+ }
+ else if (!callback)
+ {
+ Sleep(50);
+ }
+
+ if (http->run() == -1)
+ goto connection_failed;
+
+ if (callback && callback->OnSending())
+ {
+ sf->releaseInterface(http);
+ return AUTH_ABORT;
+ }
+
+ const char *dataIndex = post_data;
+ while (clen)
+ {
+ if (callback && callback->OnIdle())
+ {
+ sf->releaseInterface(http);
+ return AUTH_ABORT;
+ }
+ else if (!callback)
+ {
+ Sleep(50);
+ }
+
+ if (http->run() == -1)
+ goto connection_failed;
+
+ size_t lengthToSend = min(clen, connection->GetSendBytesAvailable());
+ if (lengthToSend)
+ {
+ connection->send(dataIndex, (int)lengthToSend);
+ dataIndex+=lengthToSend;
+ clen-=lengthToSend;
+ }
+ }
+ }
+
+ // retrieve reply
+ if (callback && callback->OnReceiving())
+ {
+ sf->releaseInterface(http);
+ return AUTH_ABORT;
+ }
+
+ int ret;
+ do
+ {
+ if (callback && callback->OnIdle())
+ {
+ sf->releaseInterface(http);
+ return AUTH_ABORT;
+ }
+ else if (!callback)
+ {
+ Sleep(50);
+ }
+
+ ret = http->run();
+ if (ret == -1) // connection failed
+ break;
+
+ // ---- check our reply code ----
+ int status = http->get_status();
+ switch (status)
+ {
+ case HTTPRECEIVER_STATUS_CONNECTING:
+ case HTTPRECEIVER_STATUS_READING_HEADERS:
+ break;
+
+ case HTTPRECEIVER_STATUS_READING_CONTENT:
+ {
+ int downloadError;
+ downloadError = RunXMLDownload(http, parser, callback);
+ sf->releaseInterface(http);
+ return downloadError;
+ }
+ break;
+ case HTTPRECEIVER_STATUS_ERROR:
+ default:
+ sf->releaseInterface(http);
+ return AUTH_404;
+ }
+ }
+ while (ret == HTTPRECEIVER_RUN_OK);
+
+
+connection_failed:
+ sf->releaseInterface(http);
+ return AUTH_404;
+}
+