diff --git a/Framework/DataHandling/src/CheckMantidVersion.cpp b/Framework/DataHandling/src/CheckMantidVersion.cpp index 80400931d2119071c8aeff50193d115ea788739a..5538e3d929fb509505e321c1b315c9fe5bdf4e07 100644 --- a/Framework/DataHandling/src/CheckMantidVersion.cpp +++ b/Framework/DataHandling/src/CheckMantidVersion.cpp @@ -1,5 +1,5 @@ #include "MantidDataHandling/CheckMantidVersion.h" -#include "MantidKernel/InternetHelper.h" +#include "MantidKernel/GitHubApiHelper.h" #include "MantidKernel/MantidVersion.h" #include "MantidKernel/Strings.h" @@ -113,8 +113,8 @@ void CheckMantidVersion::exec() { // formatting issues like missing quotes or brackets. g_log.warning() << "Error found when parsing version information " "retrieved from GitHub as a JSON string. " - "Error trying to parse this JSON string: " << json - << std::endl + "Error trying to parse this JSON string: " + << json << std::endl << ". Parsing error details: " << r.getFormattedErrorMessages() << std::endl; } @@ -237,11 +237,11 @@ behaviour. */ std::string CheckMantidVersion::getVersionsFromGitHub(const std::string &url) { - Kernel::InternetHelper inetHelper; + Kernel::GitHubApiHelper inetHelper; std::ostringstream os; int tzd = 0; - inetHelper.headers().emplace( + inetHelper.addHeader( "if-modified-since", Poco::DateTimeFormatter::format( Poco::DateTimeParser::parse(MantidVersion::releaseDate(), tzd), diff --git a/Framework/DataHandling/src/DownloadInstrument.cpp b/Framework/DataHandling/src/DownloadInstrument.cpp index 8fe8bb838062aa90c07be434d11bcc771c92d7b0..42eb7c104d69a7792ada65967684bbee22c2b12e 100644 --- a/Framework/DataHandling/src/DownloadInstrument.cpp +++ b/Framework/DataHandling/src/DownloadInstrument.cpp @@ -1,7 +1,7 @@ #include "MantidDataHandling/DownloadInstrument.h" #include "MantidKernel/ChecksumHelper.h" #include "MantidKernel/ConfigService.h" -#include "MantidKernel/InternetHelper.h" +#include "MantidKernel/GitHubApiHelper.h" // Poco #include <Poco/DateTimeFormat.h> @@ -363,8 +363,8 @@ int DownloadInstrument::doDownloadFile(const std::string &urlFile, } int retStatus = 0; - InternetHelper inetHelper; - inetHelper.headers() = headers; + GitHubApiHelper inetHelper; + inetHelper.headers().insert(headers.begin(),headers.end()); retStatus = inetHelper.downloadFile(urlFile, localFilePath); return retStatus; } diff --git a/Framework/Kernel/CMakeLists.txt b/Framework/Kernel/CMakeLists.txt index 1ae8c3accbe45e3496a59ce9e1284c5b90460023..999146fc5f6c31c2885a93017a8e6c15115008e5 100644 --- a/Framework/Kernel/CMakeLists.txt +++ b/Framework/Kernel/CMakeLists.txt @@ -31,6 +31,7 @@ set ( SRC_FILES src/FilteredTimeSeriesProperty.cpp src/FloatingPointComparison.cpp src/FreeBlock.cpp + src/GitHubApiHelper.cpp src/Glob.cpp src/ICatalogInfo.cpp src/IPropertyManager.cpp @@ -177,6 +178,7 @@ set ( INC_FILES inc/MantidKernel/FloatingPointComparison.h inc/MantidKernel/FreeBlock.h inc/MantidKernel/FunctionTask.h + inc/MantidKernel/GitHubApiHelper.h inc/MantidKernel/Glob.h inc/MantidKernel/ICatalogInfo.h inc/MantidKernel/IPropertyManager.h @@ -501,6 +503,20 @@ configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/inc/MantidKernel/PocoVersion.h.in configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/src/ParaViewVersion.cpp.in ${CMAKE_CURRENT_SOURCE_DIR}/src/ParaViewVersion.cpp ) +########################################################################### +# This section deals with creating the GithubApiHelper implementation +########################################################################### + +if ( WIN32 ) + set ( GITHUB_AUTHORIZATION_TOKEN "8ec7afc857540ee60af78cba1cf7779a6ed0b6b9") +elseif ( APPLE ) + set ( GITHUB_AUTHORIZATION_TOKEN "9f1c1acd61ecb87b21ad0382f6b403c8294992c5") +else() + set ( GITHUB_AUTHORIZATION_TOKEN "ccacbaf39a7ad8151fca03b4ea99a29b28f0993b") +endif() +configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/inc/MantidKernel/GitHubApiHelper.h.in + ${CMAKE_CURRENT_SOURCE_DIR}/inc/MantidKernel/GitHubApiHelper.h +) ########################################################################### # Manipulate the Mantid.properties file to work wherever you build to diff --git a/Framework/Kernel/inc/MantidKernel/GitHubApiHelper.h.in b/Framework/Kernel/inc/MantidKernel/GitHubApiHelper.h.in new file mode 100644 index 0000000000000000000000000000000000000000..f375d6d8a55b2ea7d5aac97fa11d772dd4c4f5fc --- /dev/null +++ b/Framework/Kernel/inc/MantidKernel/GitHubApiHelper.h.in @@ -0,0 +1,55 @@ +#ifndef MANTID_KERNEL_GitHubApiHelper_H_ +#define MANTID_KERNEL_GitHubApiHelper_H_ + +#include "MantidKernel/InternetHelper.h" + +namespace Mantid { +namespace Kernel { + +/** GitHubApiHelper : A helper class for supporting access to the github api +through HTTP and HTTPS, inherits from the InternetHelper. +This class automatically adds the authorization to a read only account. + +Copyright © 2016 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source + +This file is part of Mantid. + +Mantid is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +Mantid is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +File change history is stored at: <https://github.com/mantidproject/mantid> +Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_KERNEL_DLL GitHubApiHelper : public InternetHelper { +public: + GitHubApiHelper(); + GitHubApiHelper(const Kernel::ProxyInfo &proxy); + virtual ~GitHubApiHelper(); + + void reset() override; + +protected: + virtual void processResponseHeaders(const Poco::Net::HTTPResponse &res) override; + +private: + void addAuthenticationToken() { + addHeader("Authorization", + "token @GITHUB_AUTHORIZATION_TOKEN@"); + } +}; + +} // namespace Kernel +} // namespace Mantid + +#endif /* MANTID_KERNEL_GitHubApiHelper_H_ */ \ No newline at end of file diff --git a/Framework/Kernel/inc/MantidKernel/InternetHelper.h b/Framework/Kernel/inc/MantidKernel/InternetHelper.h index 771a819cc33a388237f9f2be13a1594370286cac..0033490dcff3b177859c70a9e472ea12d61c4364 100644 --- a/Framework/Kernel/inc/MantidKernel/InternetHelper.h +++ b/Framework/Kernel/inc/MantidKernel/InternetHelper.h @@ -130,7 +130,7 @@ public: const std::string &getHeader(const std::string &key); void clearHeaders(); StringToStringMap &headers(); - void reset(); + virtual void reset(); // Proxy methods Kernel::ProxyInfo &getProxy(const std::string &url); @@ -147,6 +147,7 @@ protected: std::ostream &responseStream); virtual int sendHTTPRequest(const std::string &url, std::ostream &responseStream); + virtual void processResponseHeaders(const Poco::Net::HTTPResponse &res); virtual int processErrorStates(const Poco::Net::HTTPResponse &res, std::istream &rs, const std::string &url); diff --git a/Framework/Kernel/src/GitHubApiHelper.cpp b/Framework/Kernel/src/GitHubApiHelper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..23d49541660b7ef2fc626496cffb61fb287855f2 --- /dev/null +++ b/Framework/Kernel/src/GitHubApiHelper.cpp @@ -0,0 +1,69 @@ +#include "MantidKernel/GitHubApiHelper.h" +#include "MantidKernel/DateAndTime.h" +#include "MantidKernel/Logger.h" +#include <Poco/Net/HTTPResponse.h> + +namespace Mantid { +namespace Kernel { + +using namespace Poco::Net; +using std::map; +using std::string; + +namespace { +// anonymous namespace for some utility functions +/// static Logger object +Logger g_log("InternetHelper"); +} + +//---------------------------------------------------------------------------------------------- +/** Constructor +*/ +GitHubApiHelper::GitHubApiHelper() + : InternetHelper() +{ + addAuthenticationToken(); +} + + +//---------------------------------------------------------------------------------------------- +/** Constructor +*/ +GitHubApiHelper::GitHubApiHelper(const Kernel::ProxyInfo &proxy) + : InternetHelper(proxy) { + addAuthenticationToken(); +} + +//---------------------------------------------------------------------------------------------- +/** Destructor +*/ +GitHubApiHelper::~GitHubApiHelper() { +} + +void GitHubApiHelper::reset() { + InternetHelper::reset(); + addAuthenticationToken(); +} + +void GitHubApiHelper::processResponseHeaders(const Poco::Net::HTTPResponse &res) { + // get github api rate limit information if available; + int rateLimitRemaining; + int rateLimitLimit; + DateAndTime rateLimitReset; + try { + rateLimitLimit = + boost::lexical_cast<int>(res.get("X-RateLimit-Limit", "-1")); + rateLimitRemaining = + boost::lexical_cast<int>(res.get("X-RateLimit-Remaining", "-1")); + rateLimitReset.set_from_time_t( + boost::lexical_cast<int>(res.get("X-RateLimit-Reset", "0"))); + } catch (boost::bad_lexical_cast const &) { + rateLimitLimit = -1; + } + if (rateLimitLimit > -1) { + g_log.debug() << "GitHub API " << rateLimitRemaining << " of " << rateLimitLimit << + " calls left. Resets at " << rateLimitReset.toSimpleString() << std::endl; + } +} +} // namespace Kernel +} // namespace Mantid diff --git a/Framework/Kernel/src/InternetHelper.cpp b/Framework/Kernel/src/InternetHelper.cpp index ed4c980187d55becf0348a72f0419059af167011..957e068eea4bd8f79df8625a9b16bfb264de6974 100644 --- a/Framework/Kernel/src/InternetHelper.cpp +++ b/Framework/Kernel/src/InternetHelper.cpp @@ -134,6 +134,7 @@ int InternetHelper::sendRequestAndProcess(HTTPClientSession &session, if (retStatus == HTTP_OK || (retStatus == HTTP_CREATED && m_method == HTTPRequest::HTTP_POST)) { Poco::StreamCopier::copyStream(rs, responseStream); + processResponseHeaders(*m_response); return retStatus; } else if (isRelocated(retStatus)) { return this->processRelocation(*m_response, responseStream); @@ -227,10 +228,11 @@ int InternetHelper::sendHTTPRequest(const std::string &url, return retStatus; } -/** Performs a request using https -* @param url the address to the network resource -* @param responseStream The stream to fill with the reply on success -**/ + + /** Performs a request using https + * @param url the address to the network resource + * @param responseStream The stream to fill with the reply on success + **/ int InternetHelper::sendHTTPSRequest(const std::string &url, std::ostream &responseStream) { int retStatus = 0; @@ -301,6 +303,14 @@ void InternetHelper::setProxy(const Kernel::ProxyInfo &proxy) { m_isProxySet = true; } +/** Process any headers from the response stream +Basic implementation does nothing. + +@param res : The http response +*/ +void InternetHelper::processResponseHeaders(const Poco::Net::HTTPResponse& res) { +} + /** Process any HTTP errors states. @param res : The http response