Mercurial > hg > orthanc-stone
view Framework/Oracle/GenericOracleRunner.cpp @ 1109:79b1b541fe15 broker
ThreadedOracle::SetRootDirectory()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 30 Oct 2019 11:56:10 +0100 |
parents | 98cdfe5768a4 |
children | b82b74d13830 |
line wrap: on
line source
/** * Stone of Orthanc * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics * Department, University Hospital of Liege, Belgium * Copyright (C) 2017-2019 Osimis S.A., Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program 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 * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ #include "GenericOracleRunner.h" #include "CustomOracleCommand.h" #include "GetOrthancImageCommand.h" #include "GetOrthancWebViewerJpegCommand.h" #include "HttpCommand.h" #include "OracleCommandExceptionMessage.h" #include "OrthancRestApiCommand.h" #include "ReadFileCommand.h" #include <Core/Compression/GzipCompressor.h> #include <Core/HttpClient.h> #include <Core/OrthancException.h> #include <Core/Toolbox.h> #include <Core/SystemToolbox.h> #include <boost/filesystem.hpp> namespace OrthancStone { static void CopyHttpHeaders(Orthanc::HttpClient& client, const Orthanc::HttpClient::HttpHeaders& headers) { for (Orthanc::HttpClient::HttpHeaders::const_iterator it = headers.begin(); it != headers.end(); it++ ) { client.AddHeader(it->first, it->second); } } static void DecodeAnswer(std::string& answer, const Orthanc::HttpClient::HttpHeaders& headers) { Orthanc::HttpCompression contentEncoding = Orthanc::HttpCompression_None; for (Orthanc::HttpClient::HttpHeaders::const_iterator it = headers.begin(); it != headers.end(); ++it) { std::string s; Orthanc::Toolbox::ToLowerCase(s, it->first); if (s == "content-encoding") { if (it->second == "gzip") { contentEncoding = Orthanc::HttpCompression_Gzip; } else { throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol, "Unsupported HTTP Content-Encoding: " + it->second); } break; } } if (contentEncoding == Orthanc::HttpCompression_Gzip) { std::string compressed; answer.swap(compressed); Orthanc::GzipCompressor compressor; compressor.Uncompress(answer, compressed.c_str(), compressed.size()); LOG(INFO) << "Uncompressing gzip Encoding: from " << compressed.size() << " to " << answer.size() << " bytes"; } } static IMessage* Execute(const HttpCommand& command) { Orthanc::HttpClient client; client.SetUrl(command.GetUrl()); client.SetMethod(command.GetMethod()); client.SetTimeout(command.GetTimeout()); CopyHttpHeaders(client, command.GetHttpHeaders()); if (command.HasCredentials()) { client.SetCredentials(command.GetUsername().c_str(), command.GetPassword().c_str()); } if (command.GetMethod() == Orthanc::HttpMethod_Post || command.GetMethod() == Orthanc::HttpMethod_Put) { client.SetBody(command.GetBody()); } std::string answer; Orthanc::HttpClient::HttpHeaders answerHeaders; client.ApplyAndThrowException(answer, answerHeaders); DecodeAnswer(answer, answerHeaders); return new HttpCommand::SuccessMessage(command, answerHeaders, answer); } static IMessage* Execute(const Orthanc::WebServiceParameters& orthanc, const OrthancRestApiCommand& command) { Orthanc::HttpClient client(orthanc, command.GetUri()); client.SetMethod(command.GetMethod()); client.SetTimeout(command.GetTimeout()); CopyHttpHeaders(client, command.GetHttpHeaders()); if (command.GetMethod() == Orthanc::HttpMethod_Post || command.GetMethod() == Orthanc::HttpMethod_Put) { client.SetBody(command.GetBody()); } std::string answer; Orthanc::HttpClient::HttpHeaders answerHeaders; client.ApplyAndThrowException(answer, answerHeaders); DecodeAnswer(answer, answerHeaders); return new OrthancRestApiCommand::SuccessMessage(command, answerHeaders, answer); } static IMessage* Execute(const Orthanc::WebServiceParameters& orthanc, const GetOrthancImageCommand& command) { Orthanc::HttpClient client(orthanc, command.GetUri()); client.SetTimeout(command.GetTimeout()); CopyHttpHeaders(client, command.GetHttpHeaders()); std::string answer; Orthanc::HttpClient::HttpHeaders answerHeaders; client.ApplyAndThrowException(answer, answerHeaders); DecodeAnswer(answer, answerHeaders); return command.ProcessHttpAnswer(answer, answerHeaders); } static IMessage* Execute(const Orthanc::WebServiceParameters& orthanc, const GetOrthancWebViewerJpegCommand& command) { Orthanc::HttpClient client(orthanc, command.GetUri()); client.SetTimeout(command.GetTimeout()); CopyHttpHeaders(client, command.GetHttpHeaders()); std::string answer; Orthanc::HttpClient::HttpHeaders answerHeaders; client.ApplyAndThrowException(answer, answerHeaders); DecodeAnswer(answer, answerHeaders); return command.ProcessHttpAnswer(answer); } static IMessage* Execute(const std::string& root, const ReadFileCommand& command) { boost::filesystem::path a(root); boost::filesystem::path b(command.GetPath()); boost::filesystem::path path; if (b.is_absolute()) { path = b; } else { path = a / b; } std::string content; Orthanc::SystemToolbox::ReadFile(content, path.string(), true /* log */); return new ReadFileCommand::SuccessMessage(command, content); } IMessage* GenericOracleRunner::Run(IOracleCommand& command) { try { switch (command.GetType()) { case IOracleCommand::Type_Sleep: throw Orthanc::OrthancException(Orthanc::ErrorCode_BadParameterType, "Sleep command cannot be executed by the runner"); case IOracleCommand::Type_Http: return Execute(dynamic_cast<const HttpCommand&>(command)); case IOracleCommand::Type_OrthancRestApi: return Execute(orthanc_, dynamic_cast<const OrthancRestApiCommand&>(command)); case IOracleCommand::Type_GetOrthancImage: return Execute(orthanc_, dynamic_cast<const GetOrthancImageCommand&>(command)); case IOracleCommand::Type_GetOrthancWebViewerJpeg: return Execute(orthanc_, dynamic_cast<const GetOrthancWebViewerJpegCommand&>(command)); case IOracleCommand::Type_Custom: return dynamic_cast<CustomOracleCommand&>(command).Execute(*this); case IOracleCommand::Type_ReadFile: return Execute(rootDirectory_, dynamic_cast<const ReadFileCommand&>(command)); default: throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); } } catch (Orthanc::OrthancException& e) { LOG(ERROR) << "Exception within the oracle: " << e.What(); return new OracleCommandExceptionMessage(command, e); } catch (...) { LOG(ERROR) << "Threaded exception within the oracle"; return new OracleCommandExceptionMessage(command, Orthanc::ErrorCode_InternalError); } } }