summaryrefslogtreecommitdiffstats
path: root/src/HTTP
diff options
context:
space:
mode:
authorx12xx12x <44411062+12xx12@users.noreply.github.com>2023-03-26 14:48:06 +0200
committerMattes D <github@xoft.cz>2023-05-19 16:25:12 +0200
commit800f1c0bc5bd4632bd0f246c756283cc47d31a34 (patch)
tree9200f7d4bb2a4e3d91161468859c403f9933eae1 /src/HTTP
parentRemoved all Printf-family functions from StringUtils. (diff)
downloadcuberite-800f1c0bc5bd4632bd0f246c756283cc47d31a34.tar
cuberite-800f1c0bc5bd4632bd0f246c756283cc47d31a34.tar.gz
cuberite-800f1c0bc5bd4632bd0f246c756283cc47d31a34.tar.bz2
cuberite-800f1c0bc5bd4632bd0f246c756283cc47d31a34.tar.lz
cuberite-800f1c0bc5bd4632bd0f246c756283cc47d31a34.tar.xz
cuberite-800f1c0bc5bd4632bd0f246c756283cc47d31a34.tar.zst
cuberite-800f1c0bc5bd4632bd0f246c756283cc47d31a34.zip
Diffstat (limited to 'src/HTTP')
-rw-r--r--src/HTTP/UrlClient.cpp133
-rw-r--r--src/HTTP/UrlClient.h48
-rw-r--r--src/HTTP/UrlParser.cpp11
-rw-r--r--src/HTTP/UrlParser.h3
4 files changed, 172 insertions, 23 deletions
diff --git a/src/HTTP/UrlClient.cpp b/src/HTTP/UrlClient.cpp
index 13a882205..3985e0707 100644
--- a/src/HTTP/UrlClient.cpp
+++ b/src/HTTP/UrlClient.cpp
@@ -4,11 +4,12 @@
// Implements the cUrlClient class for high-level URL interaction
#include "Globals.h"
-#include "UrlClient.h"
-#include "UrlParser.h"
-#include "HTTPMessageParser.h"
-#include "../mbedTLS++/X509Cert.h"
-#include "../mbedTLS++/CryptoKey.h"
+
+#include "HTTP/UrlClient.h"
+#include "HTTP/UrlParser.h"
+#include "HTTP/HTTPMessageParser.h"
+#include "mbedTLS++/X509Cert.h"
+#include "mbedTLS++/CryptoKey.h"
@@ -16,7 +17,44 @@
// fwd:
class cSchemeHandler;
-typedef std::shared_ptr<cSchemeHandler> cSchemeHandlerPtr;
+using cSchemeHandlerPtr = std::shared_ptr<cSchemeHandler>;
+
+
+/** This is a basic set of callbacks to enable quick implementation of HTTP request. */
+namespace
+{
+ class cSimpleHTTPCallbacks :
+ public cUrlClient::cCallbacks
+ {
+ public:
+
+ explicit cSimpleHTTPCallbacks(std::shared_ptr<cEvent> a_Event, AString & a_ResponseBody) :
+ m_Event(std::move(a_Event)), m_ResponseBody(a_ResponseBody)
+ {
+ }
+
+ void OnBodyFinished() override
+ {
+ m_Event->Set();
+ }
+
+ void OnError(const AString & a_ErrorMsg) override
+ {
+ LOGERROR("%s %d: HTTP Error: %s", __FILE__, __LINE__, a_ErrorMsg.c_str());
+ m_Event->Set();
+ }
+
+ void OnBodyData(const void * a_Data, size_t a_Size) override
+ {
+ m_ResponseBody.append(static_cast<const char *>(a_Data), a_Size);
+ }
+
+ std::shared_ptr<cEvent> m_Event;
+
+ /** The accumulator for the partial body data, so that OnBodyFinished() can send the entire thing at once. */
+ AString & m_ResponseBody;
+ };
+}
@@ -261,7 +299,7 @@ public:
m_Link = &a_Link;
if (m_IsTls)
{
- m_Link->StartTLSClient(m_ParentRequest.GetOwnCert(), m_ParentRequest.GetOwnPrivKey());
+ m_Link->StartTLSClient(m_ParentRequest.GetOwnCert(), m_ParentRequest.GetOwnPrivKey(), m_ParentRequest.m_UrlHost);
}
else
{
@@ -371,7 +409,7 @@ public:
return;
}
}
- m_ParentRequest.GetCallbacks().OnStatusLine(a_FirstLine.substr(1, idxFirstSpace), resultCode, a_FirstLine.substr(idxSecondSpace + 1));
+ m_ParentRequest.GetCallbacks().OnStatusLine(a_FirstLine.substr(0, idxFirstSpace), resultCode, a_FirstLine.substr(idxSecondSpace + 1));
}
@@ -613,12 +651,12 @@ std::pair<bool, AString> cUrlClient::Request(
const AString & a_URL,
cCallbacksPtr && a_Callbacks,
AStringMap && a_Headers,
- AString && a_Body,
+ const AString & a_Body,
AStringMap && a_Options
)
{
return cUrlClientRequest::Request(
- a_Method, a_URL, std::move(a_Callbacks), std::move(a_Headers), std::move(a_Body), std::move(a_Options)
+ a_Method, a_URL, std::move(a_Callbacks), std::move(a_Headers), a_Body, std::move(a_Options)
);
}
@@ -629,13 +667,13 @@ std::pair<bool, AString> cUrlClient::Request(
std::pair<bool, AString> cUrlClient::Get(
const AString & a_URL,
cCallbacksPtr && a_Callbacks,
- AStringMap a_Headers,
+ AStringMap && a_Headers,
const AString & a_Body,
- AStringMap a_Options
+ AStringMap && a_Options
)
{
return cUrlClientRequest::Request(
- "GET", a_URL, std::move(a_Callbacks), std::move(a_Headers), std::move(a_Body), std::move(a_Options)
+ "GET", a_URL, std::move(a_Callbacks), std::move(a_Headers), a_Body, std::move(a_Options)
);
}
@@ -647,12 +685,12 @@ std::pair<bool, AString> cUrlClient::Post(
const AString & a_URL,
cCallbacksPtr && a_Callbacks,
AStringMap && a_Headers,
- AString && a_Body,
+ const AString & a_Body,
AStringMap && a_Options
)
{
return cUrlClientRequest::Request(
- "POST", a_URL, std::move(a_Callbacks), std::move(a_Headers), std::move(a_Body), std::move(a_Options)
+ "POST", a_URL, std::move(a_Callbacks), std::move(a_Headers), a_Body, std::move(a_Options)
);
}
@@ -664,12 +702,12 @@ std::pair<bool, AString> cUrlClient::Put(
const AString & a_URL,
cCallbacksPtr && a_Callbacks,
AStringMap && a_Headers,
- AString && a_Body,
+ const AString & a_Body,
AStringMap && a_Options
)
{
return cUrlClientRequest::Request(
- "PUT", a_URL, std::move(a_Callbacks), std::move(a_Headers), std::move(a_Body), std::move(a_Options)
+ "PUT", a_URL, std::move(a_Callbacks), std::move(a_Headers), a_Body, std::move(a_Options)
);
}
@@ -677,3 +715,64 @@ std::pair<bool, AString> cUrlClient::Put(
+std::pair<bool, AString> cUrlClient::BlockingRequest(const AString & a_Method, const AString & a_URL, AStringMap && a_Headers, const AString & a_Body, AStringMap && a_Options)
+{
+ auto EvtFinished = std::make_shared<cEvent>();
+ AString Response;
+ auto Callbacks = std::make_unique<cSimpleHTTPCallbacks>(EvtFinished, Response);
+ auto [Success, ErrorMessage] = cUrlClient::Request(a_Method, a_URL, std::move(Callbacks), std::move(a_Headers), a_Body, std::move(a_Options));
+ if (Success)
+ {
+ EvtFinished->Wait();
+ }
+ else
+ {
+ LOGWARNING("%s: HTTP error: %s", __FUNCTION__, ErrorMessage.c_str());
+ return std::make_pair(false, AString());
+ }
+ return std::make_pair(true, Response);
+}
+
+
+
+
+
+std::pair<bool, AString> cUrlClient::BlockingGet(
+ const AString & a_URL,
+ AStringMap a_Headers,
+ const AString & a_Body,
+ AStringMap a_Options)
+{
+ return BlockingRequest("GET", a_URL, std::move(a_Headers), a_Body, std::move(a_Options));
+}
+
+
+
+
+
+std::pair<bool, AString> cUrlClient::BlockingPost(
+ const AString & a_URL,
+ AStringMap && a_Headers,
+ const AString & a_Body,
+ AStringMap && a_Options)
+{
+ return BlockingRequest("POST", a_URL, std::move(a_Headers), a_Body, std::move(a_Options));
+}
+
+
+
+
+
+std::pair<bool, AString> cUrlClient::BlockingPut(
+ const AString & a_URL,
+ AStringMap && a_Headers,
+ const AString & a_Body,
+ AStringMap && a_Options)
+{
+ return BlockingRequest("PUT", a_URL, std::move(a_Headers), a_Body, std::move(a_Options));
+}
+
+
+
+
+
diff --git a/src/HTTP/UrlClient.h b/src/HTTP/UrlClient.h
index 5f737b057..aaff60a87 100644
--- a/src/HTTP/UrlClient.h
+++ b/src/HTTP/UrlClient.h
@@ -86,7 +86,7 @@ public:
for such a response; instead, the redirect is silently attempted. */
virtual void OnRedirecting(const AString & a_NewLocation) {}
};
- typedef std::unique_ptr<cCallbacks> cCallbacksPtr;
+ using cCallbacksPtr = std::unique_ptr<cCallbacks>;
/** Used for HTTP status codes. */
@@ -115,7 +115,7 @@ public:
const AString & a_URL,
cCallbacksPtr && a_Callbacks,
AStringMap && a_Headers,
- AString && a_Body,
+ const AString & a_Body,
AStringMap && a_Options
);
@@ -123,9 +123,9 @@ public:
static std::pair<bool, AString> Get(
const AString & a_URL,
cCallbacksPtr && a_Callbacks,
- AStringMap a_Headers = AStringMap(),
+ AStringMap && a_Headers = AStringMap(),
const AString & a_Body = AString(),
- AStringMap a_Options = AStringMap()
+ AStringMap && a_Options = AStringMap()
);
/** Alias for Request("POST", ...) */
@@ -133,7 +133,7 @@ public:
const AString & a_URL,
cCallbacksPtr && a_Callbacks,
AStringMap && a_Headers,
- AString && a_Body,
+ const AString & a_Body,
AStringMap && a_Options
);
@@ -142,7 +142,43 @@ public:
const AString & a_URL,
cCallbacksPtr && a_Callbacks,
AStringMap && a_Headers,
- AString && a_Body,
+ const AString & a_Body,
+ AStringMap && a_Options
+ );
+
+ /** The method will run a thread blocking HTTP request. Any error handling
+ is done inside the functions. Check the LOG or stdout for any occurring
+ errors. Other parameters are the same as for the regular request method.
+ The return value is if the request was successful and the response. */
+ static std::pair<bool, AString> BlockingRequest(
+ const AString & a_Method,
+ const AString & a_URL,
+ AStringMap && a_Headers = AStringMap(),
+ const AString & a_Body = AString(),
+ AStringMap && a_Options = AStringMap()
+ );
+
+ /** Alias for BlockingRequest("GET", ...) */
+ static std::pair<bool, AString> BlockingGet(
+ const AString & a_URL,
+ AStringMap a_Headers = AStringMap(),
+ const AString & a_Body = AString(),
+ AStringMap a_Options = AStringMap()
+ );
+
+ /** Alias for BlockingRequest("POST", ...) */
+ static std::pair<bool, AString> BlockingPost(
+ const AString & a_URL,
+ AStringMap && a_Headers,
+ const AString & a_Body,
+ AStringMap && a_Options
+ );
+
+ /** Alias for BlockingRequest("PUT", ...) */
+ static std::pair<bool, AString> BlockingPut(
+ const AString & a_URL,
+ AStringMap && a_Headers,
+ const AString & a_Body,
AStringMap && a_Options
);
};
diff --git a/src/HTTP/UrlParser.cpp b/src/HTTP/UrlParser.cpp
index 85b1cd216..f89aaad45 100644
--- a/src/HTTP/UrlParser.cpp
+++ b/src/HTTP/UrlParser.cpp
@@ -4,6 +4,7 @@
// Implements the cUrlParser class that parses string URL into individual parts
#include "Globals.h"
+
#include "UrlParser.h"
@@ -198,3 +199,13 @@ std::pair<bool, AString> cUrlParser::Parse(
+std::pair<bool, AString> cUrlParser::Validate(const AString & a_Url)
+{
+ AString UrlScheme, UrlUsername, UrlPassword, UrlHost, UrlPath, UrlQuery, UrlFragment;
+ UInt16 Port;
+ return Parse(a_Url, UrlScheme, UrlUsername, UrlPassword, UrlHost, Port, UrlPath, UrlQuery, UrlFragment);
+}
+
+
+
+
diff --git a/src/HTTP/UrlParser.h b/src/HTTP/UrlParser.h
index 15a63e05d..76018460a 100644
--- a/src/HTTP/UrlParser.h
+++ b/src/HTTP/UrlParser.h
@@ -51,6 +51,9 @@ public:
AString & a_Query,
AString & a_Fragment
);
+
+ /** Checks if the supplied URL is valid */
+ static std::pair<bool, AString> Validate(const AString & a_Url);
};