summaryrefslogtreecommitdiffstats
path: root/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp')
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp194
1 files changed, 194 insertions, 0 deletions
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp
new file mode 100644
index 00000000000..6ef20e63ffd
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp
@@ -0,0 +1,194 @@
+//
+// HTTPSStreamFactory.cpp
+//
+// Library: NetSSL_OpenSSL
+// Package: HTTPSClient
+// Module: HTTPSStreamFactory
+//
+// Copyright (c) 2006-2012, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#include "Poco/Net/HTTPSStreamFactory.h"
+#include "Poco/Net/HTTPSClientSession.h"
+#include "Poco/Net/HTTPIOStream.h"
+#include "Poco/Net/HTTPRequest.h"
+#include "Poco/Net/HTTPResponse.h"
+#include "Poco/Net/HTTPCredentials.h"
+#include "Poco/Net/NetException.h"
+#include "Poco/URI.h"
+#include "Poco/URIStreamOpener.h"
+#include "Poco/UnbufferedStreamBuf.h"
+#include "Poco/NullStream.h"
+#include "Poco/StreamCopier.h"
+#include "Poco/Format.h"
+#include "Poco/Version.h"
+
+
+using Poco::URIStreamFactory;
+using Poco::URI;
+using Poco::URIStreamOpener;
+using Poco::UnbufferedStreamBuf;
+
+
+namespace Poco {
+namespace Net {
+
+
+HTTPSStreamFactory::HTTPSStreamFactory():
+ _proxyPort(HTTPSession::HTTP_PORT)
+{
+}
+
+
+HTTPSStreamFactory::HTTPSStreamFactory(const std::string& proxyHost, Poco::UInt16 proxyPort):
+ _proxyHost(proxyHost),
+ _proxyPort(proxyPort)
+{
+}
+
+
+HTTPSStreamFactory::HTTPSStreamFactory(const std::string& proxyHost, Poco::UInt16 proxyPort, const std::string& proxyUsername, const std::string& proxyPassword):
+ _proxyHost(proxyHost),
+ _proxyPort(proxyPort),
+ _proxyUsername(proxyUsername),
+ _proxyPassword(proxyPassword)
+{
+}
+
+
+HTTPSStreamFactory::~HTTPSStreamFactory()
+{
+}
+
+
+std::istream* HTTPSStreamFactory::open(const URI& uri)
+{
+ poco_assert (uri.getScheme() == "https" || uri.getScheme() == "http");
+
+ URI resolvedURI(uri);
+ URI proxyUri;
+ HTTPClientSession* pSession = 0;
+ HTTPResponse res;
+ try
+ {
+ bool retry = false;
+ bool authorize = false;
+ int redirects = 0;
+ std::string username;
+ std::string password;
+
+ do
+ {
+ if (!pSession)
+ {
+ if (resolvedURI.getScheme() != "http")
+ pSession = new HTTPSClientSession(resolvedURI.getHost(), resolvedURI.getPort());
+ else
+ pSession = new HTTPClientSession(resolvedURI.getHost(), resolvedURI.getPort());
+
+ if (proxyUri.empty())
+ {
+ if (!_proxyHost.empty())
+ {
+ pSession->setProxy(_proxyHost, _proxyPort);
+ pSession->setProxyCredentials(_proxyUsername, _proxyPassword);
+ }
+ }
+ else
+ {
+ pSession->setProxy(proxyUri.getHost(), proxyUri.getPort());
+ if (!_proxyUsername.empty())
+ {
+ pSession->setProxyCredentials(_proxyUsername, _proxyPassword);
+ }
+ }
+ }
+ std::string path = resolvedURI.getPathAndQuery();
+ if (path.empty()) path = "/";
+ HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
+
+ if (authorize)
+ {
+ HTTPCredentials::extractCredentials(uri, username, password);
+ HTTPCredentials cred(username, password);
+ cred.authenticate(req, res);
+ }
+
+ req.set("User-Agent", Poco::format("poco/%d.%d.%d",
+ (POCO_VERSION >> 24) & 0xFF,
+ (POCO_VERSION >> 16) & 0xFF,
+ (POCO_VERSION >> 8) & 0xFF));
+ req.set("Accept", "*/*");
+
+ pSession->sendRequest(req);
+ std::istream& rs = pSession->receiveResponse(res);
+ bool moved = (res.getStatus() == HTTPResponse::HTTP_MOVED_PERMANENTLY ||
+ res.getStatus() == HTTPResponse::HTTP_FOUND ||
+ res.getStatus() == HTTPResponse::HTTP_SEE_OTHER ||
+ res.getStatus() == HTTPResponse::HTTP_TEMPORARY_REDIRECT);
+ if (moved)
+ {
+ resolvedURI.resolve(res.get("Location"));
+ if (!username.empty())
+ {
+ resolvedURI.setUserInfo(username + ":" + password);
+ authorize = false;
+ }
+ delete pSession;
+ pSession = 0;
+ ++redirects;
+ retry = true;
+ }
+ else if (res.getStatus() == HTTPResponse::HTTP_OK)
+ {
+ return new HTTPResponseStream(rs, pSession);
+ }
+ else if (res.getStatus() == HTTPResponse::HTTP_USEPROXY && !retry)
+ {
+ // The requested resource MUST be accessed through the proxy
+ // given by the Location field. The Location field gives the
+ // URI of the proxy. The recipient is expected to repeat this
+ // single request via the proxy. 305 responses MUST only be generated by origin servers.
+ // only use for one single request!
+ proxyUri.resolve(res.get("Location"));
+ delete pSession;
+ pSession = 0;
+ retry = true; // only allow useproxy once
+ }
+ else if (res.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED && !authorize)
+ {
+ authorize = true;
+ retry = true;
+ Poco::NullOutputStream null;
+ Poco::StreamCopier::copyStream(rs, null);
+ }
+ else throw HTTPException(res.getReason(), uri.toString());
+ }
+ while (retry && redirects < MAX_REDIRECTS);
+ throw HTTPException("Too many redirects", uri.toString());
+ }
+ catch (...)
+ {
+ delete pSession;
+ throw;
+ }
+}
+
+
+void HTTPSStreamFactory::registerFactory()
+{
+ URIStreamOpener::defaultOpener().registerStreamFactory("https", new HTTPSStreamFactory);
+}
+
+
+void HTTPSStreamFactory::unregisterFactory()
+{
+ URIStreamOpener::defaultOpener().unregisterStreamFactory("https");
+}
+
+
+} } // namespace Poco::Net