# HG changeset patch # User Sebastien Jodogne # Date 1354118446 -3600 # Node ID de640de989b85fb27dce7604c0e04d12d48b7a38 # Parent 7f74209ea0f87dd21cc329b6b724b41540566a4b HttpFileSender diff -r 7f74209ea0f8 -r de640de989b8 CMakeLists.txt --- a/CMakeLists.txt Wed Nov 28 16:23:11 2012 +0100 +++ b/CMakeLists.txt Wed Nov 28 17:00:46 2012 +0100 @@ -109,6 +109,8 @@ Core/HttpServer/HttpHandler.cpp Core/HttpServer/HttpOutput.cpp Core/HttpServer/MongooseServer.cpp + Core/HttpServer/HttpFileSender.cpp + Core/HttpServer/FilesystemHttpSender.cpp Core/MultiThreading/BagOfRunnablesBySteps.cpp Core/PngWriter.cpp Core/SQLite/Connection.cpp diff -r 7f74209ea0f8 -r de640de989b8 Core/FileStorage.h --- a/Core/FileStorage.h Wed Nov 28 16:23:11 2012 +0100 +++ b/Core/FileStorage.h Wed Nov 28 17:00:46 2012 +0100 @@ -41,7 +41,9 @@ { class FileStorage : public boost::noncopyable { + // TODO REMOVE THIS friend class HttpOutput; + friend class FilesystemHttpSender; private: std::auto_ptr compressor_; diff -r 7f74209ea0f8 -r de640de989b8 Core/HttpServer/FilesystemHttpSender.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/HttpServer/FilesystemHttpSender.cpp Wed Nov 28 17:00:46 2012 +0100 @@ -0,0 +1,91 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program 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. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * 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 + * 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 . + **/ + +#include "FilesystemHttpSender.h" + +#include "../Toolbox.h" + +#include + +namespace Orthanc +{ + void FilesystemHttpSender::Setup() + { + boost::filesystem::path p(path_); + SetFilename(p.filename().string()); + SetContentType(Toolbox::AutodetectMimeType(p.filename().string())); + } + + uint64_t FilesystemHttpSender::GetFileSize() + { + return Toolbox::GetFileSize(path_); + } + + bool FilesystemHttpSender::SendData(HttpOutput& output) + { + FILE* fp = fopen(path_.c_str(), "rb"); + if (!fp) + { + return false; + } + + std::vector buffer(1024 * 1024); // Chunks of 1MB + + for (;;) + { + size_t nbytes = fread(&buffer[0], 1, buffer.size(), fp); + if (nbytes == 0) + { + break; + } + else + { + output.Send(&buffer[0], nbytes); + } + } + + fclose(fp); + + return true; + } + + FilesystemHttpSender::FilesystemHttpSender(const char* path) : path_(path) + { + Setup(); + } + + FilesystemHttpSender::FilesystemHttpSender(const FileStorage& storage, + const std::string& uuid) + { + path_ = storage.GetPath(uuid).string(); + Setup(); + } +} diff -r 7f74209ea0f8 -r de640de989b8 Core/HttpServer/FilesystemHttpSender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/HttpServer/FilesystemHttpSender.h Wed Nov 28 17:00:46 2012 +0100 @@ -0,0 +1,57 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program 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. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * 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 + * 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 . + **/ + +#pragma once + +#include "HttpFileSender.h" +#include "../FileStorage.h" + +namespace Orthanc +{ + class FilesystemHttpSender : public HttpFileSender + { + private: + std::string path_; + + void Setup(); + + protected: + virtual uint64_t GetFileSize(); + + virtual bool SendData(HttpOutput& output); + + public: + FilesystemHttpSender(const char* path); + + FilesystemHttpSender(const FileStorage& storage, + const std::string& uuid); + }; +} diff -r 7f74209ea0f8 -r de640de989b8 Core/HttpServer/HttpFileSender.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/HttpServer/HttpFileSender.cpp Wed Nov 28 17:00:46 2012 +0100 @@ -0,0 +1,66 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program 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. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * 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 + * 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 . + **/ + + +#include "HttpFileSender.h" + +#include + +namespace Orthanc +{ + void HttpFileSender::SendHeader(HttpOutput& output) + { + std::string header; + header += "Content-Length: " + boost::lexical_cast(GetFileSize()) + "\r\n"; + + if (contentType_.size() > 0) + { + header += "Content-Type: " + contentType_ + "\r\n"; + } + + if (filename_.size() > 0) + { + header += "Content-Disposition: attachment; filename=\"" + filename_ + "\"\r\n"; + } + + output.SendCustomOkHeader(header); + } + + void HttpFileSender::Send(HttpOutput& output) + { + SendHeader(output); + + if (!SendData(output)) + { + output.SendHeader(Orthanc_HttpStatus_500_InternalServerError); + } + } +} diff -r 7f74209ea0f8 -r de640de989b8 Core/HttpServer/HttpFileSender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/HttpServer/HttpFileSender.h Wed Nov 28 17:00:46 2012 +0100 @@ -0,0 +1,89 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program 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. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * 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 + * 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 . + **/ + + +#pragma once + +#include "HttpOutput.h" + +namespace Orthanc +{ + class HttpFileSender + { + private: + std::string contentType_; + std::string filename_; + + void SendHeader(HttpOutput& output); + + protected: + virtual uint64_t GetFileSize() = 0; + + virtual bool SendData(HttpOutput& output) = 0; + + public: + virtual ~HttpFileSender() + { + } + + void ResetContentType() + { + contentType_.clear(); + } + + void SetContentType(const std::string& contentType) + { + contentType_ = contentType; + } + + const std::string& GetContentType() const + { + return contentType_; + } + + void ResetFilename() + { + contentType_.clear(); + } + + void SetFilename(const std::string& filename) + { + filename_ = filename; + } + + const std::string& GetFilename() const + { + return filename_; + } + + void Send(HttpOutput& output); + }; +} diff -r 7f74209ea0f8 -r de640de989b8 OrthancServer/OrthancRestApi.cpp --- a/OrthancServer/OrthancRestApi.cpp Wed Nov 28 16:23:11 2012 +0100 +++ b/OrthancServer/OrthancRestApi.cpp Wed Nov 28 17:00:46 2012 +0100 @@ -35,6 +35,7 @@ #include "OrthancInitialization.h" #include "FromDcmtkBridge.h" #include "../Core/Uuid.h" +#include "../Core/HttpServer/FilesystemHttpSender.h" #include #include diff -r 7f74209ea0f8 -r de640de989b8 UnitTests/ServerIndex.cpp --- a/UnitTests/ServerIndex.cpp Wed Nov 28 16:23:11 2012 +0100 +++ b/UnitTests/ServerIndex.cpp Wed Nov 28 17:00:46 2012 +0100 @@ -5,7 +5,6 @@ #include #include - using namespace Orthanc; namespace @@ -261,10 +260,16 @@ + +#include "../Core/HttpServer/FilesystemHttpSender.h" + #include "../Core/Toolbox.h" #include "../Core/HttpServer/HttpOutput.h" #include "../Core/HttpServer/HttpHandler.h" +#include "../Core/HttpServer/HttpFileSender.h" + + namespace Orthanc { class RestApiPath @@ -377,131 +382,6 @@ }; - class HttpFileSender - { - private: - std::string contentType_; - std::string filename_; - - void SendHeader(HttpOutput& output) - { - std::string header; - header += "Content-Length: " + boost::lexical_cast(GetFileSize()) + "\r\n"; - - if (contentType_.size() > 0) - { - header += "Content-Type: " + contentType_ + "\r\n"; - } - - if (filename_.size() > 0) - { - header += "Content-Disposition: attachment; filename=\"" + filename_ + "\"\r\n"; - } - - output.SendCustomOkHeader(header); - } - - protected: - virtual uint64_t GetFileSize() = 0; - - virtual bool SendData(HttpOutput& output) = 0; - - public: - virtual ~HttpFileSender() - { - } - - void ResetContentType() - { - contentType_.clear(); - } - - void SetContentType(const std::string& contentType) - { - contentType_ = contentType; - } - - const std::string& GetContentType() const - { - return contentType_; - } - - void ResetFilename() - { - contentType_.clear(); - } - - void SetFilename(const std::string& filename) - { - filename_ = filename; - } - - const std::string& GetFilename() const - { - return filename_; - } - - void Send(HttpOutput& output) - { - SendHeader(output); - - if (!SendData(output)) - { - output.SendHeader(Orthanc_HttpStatus_500_InternalServerError); - } - } - }; - - - class FilesystemHttpSender : public HttpFileSender - { - private: - std::string path_; - - protected: - virtual uint64_t GetFileSize() - { - return Toolbox::GetFileSize(path_); - } - - virtual bool SendData(HttpOutput& output) - { - FILE* fp = fopen(path_.c_str(), "rb"); - if (!fp) - { - return false; - } - - std::vector buffer(1024 * 1024); // Chunks of 1MB - - for (;;) - { - size_t nbytes = fread(&buffer[0], 1, buffer.size(), fp); - if (nbytes == 0) - { - break; - } - else - { - output.Send(&buffer[0], nbytes); - } - } - - fclose(fp); - - return true; - } - - public: - FilesystemHttpSender(const char* path) : path_(path) - { - boost::filesystem::path p(path); - SetFilename(p.filename().string()); - SetContentType(Toolbox::AutodetectMimeType(p.filename().string())); - } - }; - - class RestApiOutput { private: @@ -994,14 +874,3 @@ /*LOG(WARNING) << "REST has started"; Toolbox::ServerBarrier();*/ } - - -/** - - output.AnswerBufferWithContentType(s, "application/json"); - output.AnswerFile(storage_, fileUuid, contentType, filename.c_str()); - output.Redirect("app/explorer.html"); - output.SendHeader(Orthanc_HttpStatus_415_UnsupportedMediaType); - output.SendMethodNotAllowedError("GET"); - -**/