# HG changeset patch # User Sebastien Jodogne # Date 1350999826 -7200 # Node ID 93e1b0e3b83a75b7e4ccb4cbfefd3cdfe5b9d785 # Parent 66c2605532b311f37a3091a0aef980b469e52777 filenames when downloading json/dicom diff -r 66c2605532b3 -r 93e1b0e3b83a Core/HttpServer/HttpOutput.cpp --- a/Core/HttpServer/HttpOutput.cpp Tue Oct 23 15:12:40 2012 +0200 +++ b/Core/HttpServer/HttpOutput.cpp Tue Oct 23 15:43:46 2012 +0200 @@ -49,33 +49,17 @@ void HttpOutput::SendOkHeader(const std::string& contentType) { - SendOkHeader(contentType.c_str(), false, 0); - } - - void HttpOutput::SendOkHeader() - { - SendOkHeader(NULL, false, 0); + SendOkHeader(contentType.c_str(), false, 0, NULL); } - void HttpOutput::SendOkHeader(uint64_t contentLength) - { - SendOkHeader(NULL, true, contentLength); - } - - void HttpOutput::SendOkHeader(const std::string& contentType, - uint64_t contentLength) - { - SendOkHeader(contentType.c_str(), true, contentLength); - } - - void HttpOutput::SendOkHeader(const char* contentType, bool hasContentLength, - uint64_t contentLength) + uint64_t contentLength, + const char* contentFilename) { std::string s = "HTTP/1.1 200 OK\r\n"; - if (contentType) + if (contentType && contentType[0] != '\0') { s += "Content-Type: " + std::string(contentType) + "\r\n"; } @@ -85,6 +69,11 @@ s += "Content-Length: " + boost::lexical_cast(contentLength) + "\r\n"; } + if (contentFilename && contentFilename[0] != '\0') + { + s += "Content-Disposition: attachment; filename=\"" + std::string(contentFilename) + "\"\r\n"; + } + s += "\r\n"; Send(&s[0], s.size()); @@ -126,7 +115,7 @@ void HttpOutput::AnswerBufferWithContentType(const std::string& buffer, const std::string& contentType) { - SendOkHeader(contentType.c_str(), true, buffer.size()); + SendOkHeader(contentType.c_str(), true, buffer.size(), NULL); SendString(buffer); } @@ -135,13 +124,14 @@ size_t size, const std::string& contentType) { - SendOkHeader(contentType.c_str(), true, size); + SendOkHeader(contentType.c_str(), true, size, NULL); Send(buffer, size); } void HttpOutput::AnswerFileWithContentType(const std::string& path, - const std::string& contentType) + const std::string& contentType, + const char* filename) { uint64_t fileSize = Toolbox::GetFileSize(path); @@ -152,7 +142,7 @@ return; } - SendOkHeader(contentType.c_str(), true, fileSize); + SendOkHeader(contentType.c_str(), true, fileSize, filename); std::vector buffer(1024 * 1024); // Chunks of 1MB @@ -173,18 +163,20 @@ } - void HttpOutput::AnswerFileAutodetectContentType(const std::string& path) + void HttpOutput::AnswerFileAutodetectContentType(const std::string& path, + const char* filename) { - AnswerFileWithContentType(path, Toolbox::AutodetectMimeType(path)); + AnswerFileWithContentType(path, Toolbox::AutodetectMimeType(path), filename); } void HttpOutput::AnswerFile(const FileStorage& storage, const std::string& uuid, - const std::string& contentType) + const std::string& contentType, + const char* filename) { boost::filesystem::path p(storage.GetPath(uuid)); - AnswerFileWithContentType(p.string(), contentType); + AnswerFileWithContentType(p.string(), contentType, filename); } diff -r 66c2605532b3 -r 93e1b0e3b83a Core/HttpServer/HttpOutput.h --- a/Core/HttpServer/HttpOutput.h Tue Oct 23 15:12:40 2012 +0200 +++ b/Core/HttpServer/HttpOutput.h Tue Oct 23 15:43:46 2012 +0200 @@ -46,7 +46,8 @@ void SendOkHeader(const char* contentType, bool hasContentLength, - uint64_t contentLength); + uint64_t contentLength, + const char* contentFilename); public: virtual ~HttpOutput() @@ -55,16 +56,9 @@ virtual void Send(const void* buffer, size_t length) = 0; - void SendString(const std::string& s); - - void SendOkHeader(); - - void SendOkHeader(uint64_t contentLength); - void SendOkHeader(const std::string& contentType); - void SendOkHeader(const std::string& contentType, - uint64_t contentLength); + void SendString(const std::string& s); void SendMethodNotAllowedError(const std::string& allowed); @@ -73,11 +67,6 @@ // Higher-level constructs to send entire files or buffers ------------------- - void AnswerBuffer(const std::string& buffer) - { - AnswerBufferWithContentType(buffer, ""); - } - void AnswerBufferWithContentType(const std::string& buffer, const std::string& contentType); @@ -85,25 +74,17 @@ size_t size, const std::string& contentType); - void AnswerFile(const std::string& path) - { - AnswerFileWithContentType(path, ""); - } - void AnswerFileWithContentType(const std::string& path, - const std::string& contentType); + const std::string& contentType, + const char* filename = NULL); - void AnswerFileAutodetectContentType(const std::string& path); - - void AnswerFile(const FileStorage& storage, - const std::string& uuid) - { - AnswerFile(storage, uuid, ""); - } + void AnswerFileAutodetectContentType(const std::string& path, + const char* filename = NULL); void AnswerFile(const FileStorage& storage, const std::string& uuid, - const std::string& contentType); + const std::string& contentType, + const char* filename = NULL); void Redirect(const std::string& path); }; diff -r 66c2605532b3 -r 93e1b0e3b83a Core/HttpServer/MongooseServer.cpp --- a/Core/HttpServer/MongooseServer.cpp Tue Oct 23 15:12:40 2012 +0200 +++ b/Core/HttpServer/MongooseServer.cpp Tue Oct 23 15:43:46 2012 +0200 @@ -522,7 +522,7 @@ return (void*) ""; case PostDataStatus_Pending: - output.AnswerBuffer(""); + output.AnswerBufferWithContentType(NULL, 0, ""); return (void*) ""; default: diff -r 66c2605532b3 -r 93e1b0e3b83a NEWS --- a/NEWS Tue Oct 23 15:12:40 2012 +0200 +++ b/NEWS Tue Oct 23 15:43:46 2012 +0200 @@ -1,12 +1,13 @@ Pending changes in the mainline =============================== -* URI "/system" +* Use HTTP Content-Disposition to set a filename when downloading JSON/DCM +* URI "/system" for general information about Orthanc * Versioning info and help on the command line * Improved logging * Possibility of dynamic linking against jsoncpp, sqlite, boost and dmctk * Fix some bugs -* Switch to 8042 port for HTTP +* Switch to default 8042 port for HTTP Version 0.2.2 (2012/10/04) diff -r 66c2605532b3 -r 93e1b0e3b83a OrthancServer/OrthancRestApi.cpp --- a/OrthancServer/OrthancRestApi.cpp Tue Oct 23 15:12:40 2012 +0200 +++ b/OrthancServer/OrthancRestApi.cpp Tue Oct 23 15:43:46 2012 +0200 @@ -566,17 +566,19 @@ uri[2] == "tags" || uri[2] == "simplified-tags")) { - std::string fileUuid, contentType; + std::string fileUuid, contentType, filename; if (uri[2] == "file") { existingResource = index_.GetDicomFile(fileUuid, uri[1]); contentType = "application/dicom"; + filename = fileUuid + ".dcm"; } else if (uri[2] == "tags" || uri[2] == "simplified-tags") { existingResource = index_.GetJsonFile(fileUuid, uri[1]); contentType = "application/json"; + filename = fileUuid + ".json"; } if (existingResource) @@ -590,7 +592,7 @@ } else { - output.AnswerFile(storage_, fileUuid, contentType); + output.AnswerFile(storage_, fileUuid, contentType, filename.c_str()); return; } }