summaryrefslogtreecommitdiffstats
path: root/src/HTTP/UrlClient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/HTTP/UrlClient.cpp')
-rw-r--r--src/HTTP/UrlClient.cpp74
1 files changed, 69 insertions, 5 deletions
diff --git a/src/HTTP/UrlClient.cpp b/src/HTTP/UrlClient.cpp
index f9e642b22..9346882f1 100644
--- a/src/HTTP/UrlClient.cpp
+++ b/src/HTTP/UrlClient.cpp
@@ -7,6 +7,8 @@
#include "UrlClient.h"
#include "UrlParser.h"
#include "HTTPMessageParser.h"
+#include "../PolarSSL++/X509Cert.h"
+#include "../PolarSSL++/CryptoKey.h"
@@ -67,6 +69,38 @@ public:
bool ShouldAllowRedirects() const;
+ cX509CertPtr GetOwnCert() const
+ {
+ auto itr = m_Options.find("OwnCert");
+ if (itr == m_Options.end())
+ {
+ return nullptr;
+ }
+ cX509CertPtr cert;
+ if (!cert->Parse(itr->second.data(), itr->second.size()))
+ {
+ LOGD("OwnCert failed to parse");
+ return nullptr;
+ }
+ return cert;
+ }
+
+ cCryptoKeyPtr GetOwnPrivKey() const
+ {
+ auto itr = m_Options.find("OwnPrivKey");
+ if (itr == m_Options.end())
+ {
+ return nullptr;
+ }
+ cCryptoKeyPtr key;
+ auto passItr = m_Options.find("OwnPrivKeyPassword");
+ auto pass = (passItr == m_Options.end()) ? AString() : passItr->second;
+ if (!key->ParsePrivate(itr->second.data(), itr->second.size(), pass))
+ {
+ return nullptr;
+ }
+ return key;
+ }
protected:
@@ -148,6 +182,9 @@ protected:
}
+ // cTCPLink::cCallbacks override: TLS handshake completed on the link:
+ virtual void OnTlsHandshakeCompleted(void) override;
+
/** Called when there's data incoming from the remote peer. */
virtual void OnReceivedData(const char * a_Data, size_t a_Length) override;
@@ -188,6 +225,9 @@ public:
/** Called when there's data incoming from the remote peer. */
virtual void OnReceivedData(const char * a_Data, size_t a_Length) = 0;
+ /** Called when the TLS handshake has completed on the underlying link. */
+ virtual void OnTlsHandshakeCompleted(void) = 0;
+
/** Called when the remote end closes the connection.
The link is still available for connection information query (IP / port).
Sending data on the link is not an error, but the data won't be delivered. */
@@ -223,7 +263,7 @@ public:
m_Link = &a_Link;
if (m_IsTls)
{
- // TODO: Start TLS
+ m_Link->StartTLSClient(m_ParentRequest.GetOwnCert(), m_ParentRequest.GetOwnPrivKey());
}
else
{
@@ -231,9 +271,12 @@ public:
}
}
+
+ /** Sends the HTTP request over the link.
+ Common code for both HTTP and HTTPS. */
void SendRequest()
{
- // Send the request:
+ // Compose the request line:
auto requestLine = m_ParentRequest.m_UrlPath;
if (requestLine.empty())
{
@@ -245,6 +288,8 @@ public:
requestLine.append(m_ParentRequest.m_UrlQuery);
}
m_Link->Send(Printf("%s %s HTTP/1.1\r\n", m_ParentRequest.m_Method.c_str(), requestLine.c_str()));
+
+ // Send the headers:
m_Link->Send(Printf("Host: %s\r\n", m_ParentRequest.m_UrlHost.c_str()));
m_Link->Send(Printf("Content-Length: %u\r\n", static_cast<unsigned>(m_ParentRequest.m_Body.size())));
for (auto itr = m_ParentRequest.m_Headers.cbegin(), end = m_ParentRequest.m_Headers.cend(); itr != end; ++itr)
@@ -252,6 +297,8 @@ public:
m_Link->Send(Printf("%s: %s\r\n", itr->first.c_str(), itr->second.c_str()));
} // for itr - m_Headers[]
m_Link->Send("\r\n", 2);
+
+ // Send the body:
m_Link->Send(m_ParentRequest.m_Body);
// Notify the callbacks that the request has been sent:
@@ -270,6 +317,12 @@ public:
}
+ virtual void OnTlsHandshakeCompleted(void) override
+ {
+ SendRequest();
+ }
+
+
virtual void OnRemoteClosed(void) override
{
m_Link = nullptr;
@@ -385,12 +438,12 @@ protected:
/** The network link. */
cTCPLink * m_Link;
- /** If true, the TLS should be started on the link before sending the request (used for https). */
- bool m_IsTls;
-
/** Parser of the HTTP response message. */
cHTTPMessageParser m_Parser;
+ /** If true, the TLS should be started on the link before sending the request (used for https). */
+ bool m_IsTls;
+
/** Set to true if the first line contains a redirecting HTTP status code and the options specify to follow redirects.
If true, and the parent request allows redirects, neither headers not the body contents are reported through the callbacks,
and after the entire request is parsed, the redirect is attempted. */
@@ -475,6 +528,17 @@ void cUrlClientRequest::OnConnected(cTCPLink & a_Link)
+void cUrlClientRequest::OnTlsHandshakeCompleted(void)
+{
+ // Notify the scheme handler and the callbacks:
+ m_SchemeHandler->OnTlsHandshakeCompleted();
+ m_Callbacks.OnTlsHandshakeCompleted();
+}
+
+
+
+
+
void cUrlClientRequest::OnReceivedData(const char * a_Data, size_t a_Length)
{
auto handler = m_SchemeHandler;