Mercurial > hg > orthanc
comparison Core/HttpServer/HttpOutput.cpp @ 155:93e1b0e3b83a
filenames when downloading json/dicom
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 23 Oct 2012 15:43:46 +0200 |
parents | fe180eae201d |
children | 7f74209ea0f8 |
comparison
equal
deleted
inserted
replaced
154:66c2605532b3 | 155:93e1b0e3b83a |
---|---|
47 Send(&s[0], s.size()); | 47 Send(&s[0], s.size()); |
48 } | 48 } |
49 | 49 |
50 void HttpOutput::SendOkHeader(const std::string& contentType) | 50 void HttpOutput::SendOkHeader(const std::string& contentType) |
51 { | 51 { |
52 SendOkHeader(contentType.c_str(), false, 0); | 52 SendOkHeader(contentType.c_str(), false, 0, NULL); |
53 } | 53 } |
54 | |
55 void HttpOutput::SendOkHeader() | |
56 { | |
57 SendOkHeader(NULL, false, 0); | |
58 } | |
59 | |
60 void HttpOutput::SendOkHeader(uint64_t contentLength) | |
61 { | |
62 SendOkHeader(NULL, true, contentLength); | |
63 } | |
64 | |
65 void HttpOutput::SendOkHeader(const std::string& contentType, | |
66 uint64_t contentLength) | |
67 { | |
68 SendOkHeader(contentType.c_str(), true, contentLength); | |
69 } | |
70 | |
71 | 54 |
72 void HttpOutput::SendOkHeader(const char* contentType, | 55 void HttpOutput::SendOkHeader(const char* contentType, |
73 bool hasContentLength, | 56 bool hasContentLength, |
74 uint64_t contentLength) | 57 uint64_t contentLength, |
58 const char* contentFilename) | |
75 { | 59 { |
76 std::string s = "HTTP/1.1 200 OK\r\n"; | 60 std::string s = "HTTP/1.1 200 OK\r\n"; |
77 | 61 |
78 if (contentType) | 62 if (contentType && contentType[0] != '\0') |
79 { | 63 { |
80 s += "Content-Type: " + std::string(contentType) + "\r\n"; | 64 s += "Content-Type: " + std::string(contentType) + "\r\n"; |
81 } | 65 } |
82 | 66 |
83 if (hasContentLength) | 67 if (hasContentLength) |
84 { | 68 { |
85 s += "Content-Length: " + boost::lexical_cast<std::string>(contentLength) + "\r\n"; | 69 s += "Content-Length: " + boost::lexical_cast<std::string>(contentLength) + "\r\n"; |
70 } | |
71 | |
72 if (contentFilename && contentFilename[0] != '\0') | |
73 { | |
74 s += "Content-Disposition: attachment; filename=\"" + std::string(contentFilename) + "\"\r\n"; | |
86 } | 75 } |
87 | 76 |
88 s += "\r\n"; | 77 s += "\r\n"; |
89 | 78 |
90 Send(&s[0], s.size()); | 79 Send(&s[0], s.size()); |
124 | 113 |
125 | 114 |
126 void HttpOutput::AnswerBufferWithContentType(const std::string& buffer, | 115 void HttpOutput::AnswerBufferWithContentType(const std::string& buffer, |
127 const std::string& contentType) | 116 const std::string& contentType) |
128 { | 117 { |
129 SendOkHeader(contentType.c_str(), true, buffer.size()); | 118 SendOkHeader(contentType.c_str(), true, buffer.size(), NULL); |
130 SendString(buffer); | 119 SendString(buffer); |
131 } | 120 } |
132 | 121 |
133 | 122 |
134 void HttpOutput::AnswerBufferWithContentType(const void* buffer, | 123 void HttpOutput::AnswerBufferWithContentType(const void* buffer, |
135 size_t size, | 124 size_t size, |
136 const std::string& contentType) | 125 const std::string& contentType) |
137 { | 126 { |
138 SendOkHeader(contentType.c_str(), true, size); | 127 SendOkHeader(contentType.c_str(), true, size, NULL); |
139 Send(buffer, size); | 128 Send(buffer, size); |
140 } | 129 } |
141 | 130 |
142 | 131 |
143 void HttpOutput::AnswerFileWithContentType(const std::string& path, | 132 void HttpOutput::AnswerFileWithContentType(const std::string& path, |
144 const std::string& contentType) | 133 const std::string& contentType, |
134 const char* filename) | |
145 { | 135 { |
146 uint64_t fileSize = Toolbox::GetFileSize(path); | 136 uint64_t fileSize = Toolbox::GetFileSize(path); |
147 | 137 |
148 FILE* fp = fopen(path.c_str(), "rb"); | 138 FILE* fp = fopen(path.c_str(), "rb"); |
149 if (!fp) | 139 if (!fp) |
150 { | 140 { |
151 SendHeaderInternal(Orthanc_HttpStatus_500_InternalServerError); | 141 SendHeaderInternal(Orthanc_HttpStatus_500_InternalServerError); |
152 return; | 142 return; |
153 } | 143 } |
154 | 144 |
155 SendOkHeader(contentType.c_str(), true, fileSize); | 145 SendOkHeader(contentType.c_str(), true, fileSize, filename); |
156 | 146 |
157 std::vector<uint8_t> buffer(1024 * 1024); // Chunks of 1MB | 147 std::vector<uint8_t> buffer(1024 * 1024); // Chunks of 1MB |
158 | 148 |
159 for (;;) | 149 for (;;) |
160 { | 150 { |
171 | 161 |
172 fclose(fp); | 162 fclose(fp); |
173 } | 163 } |
174 | 164 |
175 | 165 |
176 void HttpOutput::AnswerFileAutodetectContentType(const std::string& path) | 166 void HttpOutput::AnswerFileAutodetectContentType(const std::string& path, |
167 const char* filename) | |
177 { | 168 { |
178 AnswerFileWithContentType(path, Toolbox::AutodetectMimeType(path)); | 169 AnswerFileWithContentType(path, Toolbox::AutodetectMimeType(path), filename); |
179 } | 170 } |
180 | 171 |
181 | 172 |
182 void HttpOutput::AnswerFile(const FileStorage& storage, | 173 void HttpOutput::AnswerFile(const FileStorage& storage, |
183 const std::string& uuid, | 174 const std::string& uuid, |
184 const std::string& contentType) | 175 const std::string& contentType, |
176 const char* filename) | |
185 { | 177 { |
186 boost::filesystem::path p(storage.GetPath(uuid)); | 178 boost::filesystem::path p(storage.GetPath(uuid)); |
187 AnswerFileWithContentType(p.string(), contentType); | 179 AnswerFileWithContentType(p.string(), contentType, filename); |
188 } | 180 } |
189 | 181 |
190 | 182 |
191 | 183 |
192 void HttpOutput::Redirect(const std::string& path) | 184 void HttpOutput::Redirect(const std::string& path) |