15#include <Poco/Net/AcceptCertificateHandler.h>
16#include <Poco/Net/HTMLForm.h>
17#include <Poco/Net/HTTPRequest.h>
18#include <Poco/Net/HTTPResponse.h>
19#include <Poco/Net/HTTPSClientSession.h>
20#include <Poco/Net/NetException.h>
21#include <Poco/Net/PrivateKeyPassphraseHandler.h>
22#include <Poco/Net/SSLManager.h>
23#include <Poco/StreamCopier.h>
24#include <Poco/TemporaryFile.h>
27#include <Poco/Exception.h>
29#include <Poco/FileStream.h>
30#include <Poco/Net/Context.h>
31#include <Poco/Net/HTTPClientSession.h>
32#include <Poco/Net/HTTPMessage.h>
33#include <Poco/Net/InvalidCertificateHandler.h>
34#include <Poco/SharedPtr.h>
35#include <Poco/Timespan.h>
36#include <Poco/Types.h>
38#if defined(_WIN32) || defined(_WIN64)
42#include <boost/lexical_cast.hpp>
50using namespace Types::Core;
60Logger
g_log(
"InternetHelper");
63std::once_flag SSL_INIT_FLAG;
71 Poco::SharedPtr<InvalidCertificateHandler> certificateHandler =
new AcceptCertificateHandler(
true);
74 const Context::Ptr context =
new Context(Context::CLIENT_USE,
"",
"",
"", Context::VERIFY_NONE);
78 SSLManager::instance().initializeClient(
nullptr, certificateHandler, context);
85void initializeSSL() { std::call_once(SSL_INIT_FLAG, doSSLInit); }
92 : m_proxyInfo(), m_isProxySet(false), m_timeout(30), m_isTimeoutSet(false), m_contentLength(0),
93 m_method(HTTPRequest::HTTP_GET), m_contentType(
"application/json"), m_body(), m_headers(), m_request(nullptr),
94 m_response(nullptr) {}
100 : m_proxyInfo(proxy), m_isProxySet(true), m_timeout(30), m_isTimeoutSet(false), m_contentLength(0),
101 m_method(HTTPRequest::HTTP_GET), m_contentType(
"application/json"), m_body(), m_headers(), m_request(nullptr),
102 m_response(nullptr) {}
110 auto proxy = this->
getProxy(proxyUrl);
111 if (!proxy.emptyProxy()) {
112 session.setProxyHost(proxy.host());
113 session.setProxyPort(
static_cast<Poco::UInt16
>(proxy.port()));
118 m_request = std::make_unique<HTTPRequest>(
m_method, uri.getPathAndQuery(), HTTPMessage::HTTP_1_1);
119 m_response = std::make_unique<HTTPResponse>();
131 m_request->setContentLength(HTTPMessage::UNKNOWN_CONTENT_LENGTH);
132 m_request->setChunkedTransferEncoding(
true);
138 m_request->set(header.first, header.second);
143 std::ostream &responseStream) {
148 std::istream &rs = session.receiveResponse(*
m_response);
150 g_log.
debug() <<
"Answer from web: " <<
static_cast<int>(retStatus) <<
" " <<
m_response->getReason() <<
'\n';
153 Poco::StreamCopier::copyStream(rs, responseStream);
162 Poco::StreamCopier::copyStream(rs, responseStream);
168 std::ostream &responseStream) {
169 std::string newLocation = response.get(
"location",
"");
170 if (!newLocation.empty()) {
172 return this->
sendRequest(newLocation, responseStream);
174 g_log.
warning(
"Apparent relocation did not give new location\n");
175 return static_cast<HTTPStatus>(response.getStatus());
187 if (uri.getPath().empty())
189 if ((uri.getScheme() ==
"https") || (uri.getPort() == 443)) {
204 const std::string insecString =
"password=";
205 if (std::string::npos == url.find(insecString)) {
206 g_log.
debug() <<
"Sending " << schemeName <<
" " <<
m_method <<
" request to: " << url <<
"\n";
209 <<
" request to an url where the query string seems to contain a "
210 "password! (not shown for security reasons)."
226 Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort());
227 session.setTimeout(Poco::Timespan(
getTimeout(), 0));
234 }
catch (HostNotFoundException &ex) {
236 }
catch (Poco::Exception &ex) {
255 HTTPSClientSession session(uri.getHost(),
static_cast<Poco::UInt16
>(uri.getPort()));
256 session.setTimeout(Poco::Timespan(
getTimeout(), 0));
263 if (urlforProxy.empty()) {
264 urlforProxy =
"http://" + uri.getHost();
270 }
catch (HostNotFoundException &ex) {
272 }
catch (Poco::Exception &ex) {
316 const std::string &url) {
317 const auto retStatus =
static_cast<HTTPStatus>(res.getStatus());
318 g_log.
debug() <<
"Answer from web: " <<
static_cast<int>(res.getStatus()) <<
" " << res.getReason() <<
'\n';
321 int rateLimitRemaining;
322 DateAndTime rateLimitReset;
324 rateLimitRemaining = boost::lexical_cast<int>(res.get(
"X-RateLimit-Remaining",
"-1"));
325 rateLimitReset.set_from_time_t(boost::lexical_cast<int>(res.get(
"X-RateLimit-Reset",
"0")));
326 }
catch (boost::bad_lexical_cast
const &) {
327 rateLimitRemaining = -1;
332 "have entered processErrorStates",
333 static_cast<int>(retStatus));
336 "never have entered processErrorStates",
337 static_cast<int>(retStatus));
340 "processing should never have entered "
341 "processErrorStates",
342 static_cast<int>(retStatus));
345 static_cast<int>(retStatus));
348 rateLimitReset.toSimpleString() +
" GMT",
349 static_cast<int>(retStatus));
351 std::stringstream info;
352 std::stringstream ss;
353 Poco::StreamCopier::copyStream(rs, ss);
355 info <<
"Failed to download " << url <<
" with the link "
356 <<
"<a href=\"" << url <<
"\">.\n"
357 <<
"Hint. Check that link is correct</a>";
360 info << res.getReason();
390 g_log.
debug() <<
"DownloadFile from \"" << urlFile <<
"\" to file: \"" << localFilePath <<
"\"\n";
392 Poco::TemporaryFile tempFile;
393 Poco::FileStream tempFileStream(tempFile.path());
394 const auto retStatus =
sendRequest(urlFile, tempFileStream);
395 tempFileStream.close();
400 Poco::File file(localFilePath);
405 tempFile.moveTo(localFilePath);
432 std::stringstream info;
433 info <<
"Failed to access " << url <<
" because there is no connection to the host " << ex.message()
434 <<
".\nHint: Check your connection following this link: <a href=\"" << url <<
"\">" << url <<
"</a> ";
444 m_timeout = timeout.is_initialized() ? timeout.get() : 30;
454 if (method ==
"POST") {
517 Poco::URI uri(
"http://www.mantidproject.org");
523 std::ostringstream ss;
double value
The value of the point.
BuilderMethod< ArgType > m_method
Exception thrown when error occurs accessing an internet resource.
const std::string & getResponseReason()
Gets the body set for future requests.
Kernel::ProxyInfo m_proxyInfo
const std::string & getBody()
Gets the body set for future requests.
void createRequest(Poco::URI &uri)
std::string m_contentType
void setContentLength(std::streamsize length)
Sets the content length.
InternetHelper::HTTPStatus processRelocation(const Poco::Net::HTTPResponse &response, std::ostream &responseStream)
void logDebugRequestSending(const std::string &schemeName, const std::string &url) const
Helper to log (debug level) the request being sent (careful not to print blatant passwords,...
void setBody(const std::string &body)
Sets the body & content length for future requests, this will also set the method to POST is the body...
bool isRelocated(const HTTPStatus &response)
Checks the HTTP status to decide if this is a relocation.
std::unique_ptr< Poco::Net::HTTPRequest > m_request
void addHeader(const std::string &key, const std::string &value)
Adds a header.
void setupProxyOnSession(Poco::Net::HTTPClientSession &session, const std::string &proxyUrl)
StringToStringMap m_headers
void setProxy(const Kernel::ProxyInfo &proxy)
sets the proxy details.
void throwNotConnected(const std::string &url, const Poco::Net::HostNotFoundException &ex)
Throw an exception occurs when the computer is not connected to the internet.
std::streamsize getContentLength()
Gets the content length.
void clearProxy()
Clears cached proxy details.
HTTPStatus getResponseStatus()
Gets the body set for future requests.
virtual ~InternetHelper()
Destructor.
const std::string & getHeader(const std::string &key)
Gets the value of a header.
virtual HTTPStatus sendHTTPSRequest(const std::string &url, std::ostream &responseStream)
Performs a request using https.
Kernel::ProxyInfo & getProxy(const std::string &url)
Gets proxy details for a system and a url.
void setTimeout(int seconds)
Sets the timeout in seconds.
virtual HTTPStatus processErrorStates(const Poco::Net::HTTPResponse &res, std::istream &rs, const std::string &url)
Process any HTTP errors states.
virtual HTTPStatus sendHTTPRequest(const std::string &url, std::ostream &responseStream)
Performs a request using http.
std::streamsize m_contentLength
virtual HTTPStatus sendRequest(const std::string &url, std::ostream &responseStream)
Performs a request using http or https depending on the url.
const std::string & getMethod()
Gets the method.
StringToStringMap & headers()
Returns a reference to the headers map.
virtual HTTPStatus downloadFile(const std::string &urlFile, const std::string &localFilePath="")
Download a url and fetch it inside the local path given.
int getTimeout()
Gets the timeout in seconds.
virtual HTTPStatus sendRequestAndProcess(Poco::Net::HTTPClientSession &session, Poco::URI &uri, std::ostream &responseStream)
void removeHeader(const std::string &key)
Removes a header.
const std::string & getContentType()
Gets the Content Type.
virtual void reset()
Resets properties to defaults (except the proxy)
std::unique_ptr< Poco::Net::HTTPResponse > m_response
InternetHelper()
Constructor.
void setContentType(const std::string &contentType)
Sets the Content Type.
void clearHeaders()
Clears all headers.
void setMethod(const std::string &method)
Sets the Method.
virtual void processResponseHeaders(const Poco::Net::HTTPResponse &res)
Process any headers from the response stream Basic implementation does nothing.
void debug(const std::string &msg)
Logs at debug level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
static const char * version()
The full version number.
ProxyInfo : Container for carrying around network proxy information.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Logger g_log("DateAndTime")
Helper class which provides the Collimation Length for SANS instruments.