Mercurial > hg > orthanc
comparison Plugins/Samples/ServeFolders/Plugin.cpp @ 1589:334d3a92ed83
improvements to the ServeFolders plugin
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 26 Aug 2015 17:43:00 +0200 |
parents | b5bc87a7212d |
children | 415dfd1d1c61 |
comparison
equal
deleted
inserted
replaced
1588:b5bc87a7212d | 1589:334d3a92ed83 |
---|---|
20 | 20 |
21 #include <orthanc/OrthancCPlugin.h> | 21 #include <orthanc/OrthancCPlugin.h> |
22 | 22 |
23 #include <json/reader.h> | 23 #include <json/reader.h> |
24 #include <json/value.h> | 24 #include <json/value.h> |
25 #include <string.h> | 25 #include <boost/filesystem.hpp> |
26 #include <stdio.h> | 26 |
27 #include <fstream> | |
28 #include <algorithm> | |
29 #include <sys/stat.h> | |
30 | 27 |
31 static OrthancPluginContext* context_ = NULL; | 28 static OrthancPluginContext* context_ = NULL; |
32 static std::map<std::string, std::string> folders_; | 29 static std::map<std::string, std::string> folders_; |
33 static const char* INDEX_URI = "/app/plugin-serve-folders.html"; | 30 static const char* INDEX_URI = "/app/plugin-serve-folders.html"; |
34 | 31 |
134 return false; | 131 return false; |
135 } | 132 } |
136 } | 133 } |
137 | 134 |
138 | 135 |
136 | |
137 static bool LookupFolder(std::string& folder, | |
138 OrthancPluginRestOutput* output, | |
139 const OrthancPluginHttpRequest* request) | |
140 { | |
141 const std::string uri = request->groups[0]; | |
142 | |
143 std::map<std::string, std::string>::const_iterator found = folders_.find(uri); | |
144 if (found == folders_.end()) | |
145 { | |
146 std::string s = "Unknown URI in plugin server-folders: " + uri; | |
147 OrthancPluginLogError(context_, s.c_str()); | |
148 OrthancPluginSendHttpStatusCode(context_, output, 404); | |
149 return false; | |
150 } | |
151 else | |
152 { | |
153 folder = found->second; | |
154 return true; | |
155 } | |
156 } | |
157 | |
158 | |
159 static int32_t IndexCallback(OrthancPluginRestOutput* output, | |
160 const char* url, | |
161 const OrthancPluginHttpRequest* request) | |
162 { | |
163 namespace fs = boost::filesystem; | |
164 | |
165 if (request->method != OrthancPluginHttpMethod_Get) | |
166 { | |
167 OrthancPluginSendMethodNotAllowed(context_, output, "GET"); | |
168 return 0; | |
169 } | |
170 | |
171 std::string folder; | |
172 if (LookupFolder(folder, output, request)) | |
173 { | |
174 std::string baseUri = "/" + std::string(request->groups[0]); | |
175 | |
176 if (fs::is_regular_file(fs::path(folder) / "index.html")) | |
177 { | |
178 std::string s = baseUri + "/index.html"; | |
179 OrthancPluginRedirect(context_, output, s.c_str()); | |
180 } | |
181 else | |
182 { | |
183 std::string s; | |
184 s += "<html>\n"; | |
185 s += " <body>\n"; | |
186 s += " <ul>\n"; | |
187 | |
188 fs::directory_iterator end; | |
189 for (fs::directory_iterator it(folder) ; it != end; ++it) | |
190 { | |
191 if (fs::is_regular_file(it->status())) | |
192 { | |
193 std::string f = it->path().filename().string(); | |
194 s += " <li><a href=\"" + baseUri + "/" + f + "\">" + f + "</a></li>"; | |
195 } | |
196 } | |
197 | |
198 s += " </ul>\n"; | |
199 s += " </body>\n"; | |
200 s += "</html>\n"; | |
201 | |
202 OrthancPluginAnswerBuffer(context_, output, s.c_str(), s.size(), "text/html"); | |
203 } | |
204 } | |
205 | |
206 return 0; | |
207 } | |
208 | |
209 | |
139 static int32_t FolderCallback(OrthancPluginRestOutput* output, | 210 static int32_t FolderCallback(OrthancPluginRestOutput* output, |
140 const char* url, | 211 const char* url, |
141 const OrthancPluginHttpRequest* request) | 212 const OrthancPluginHttpRequest* request) |
142 { | 213 { |
143 if (request->method != OrthancPluginHttpMethod_Get) | 214 if (request->method != OrthancPluginHttpMethod_Get) |
144 { | 215 { |
145 OrthancPluginSendMethodNotAllowed(context_, output, "GET"); | 216 OrthancPluginSendMethodNotAllowed(context_, output, "GET"); |
146 return 0; | 217 return 0; |
147 } | 218 } |
148 | 219 |
149 const std::string uri = request->groups[0]; | 220 std::string folder; |
150 const std::string item = request->groups[1]; | 221 |
151 | 222 if (LookupFolder(folder, output, request)) |
152 std::map<std::string, std::string>::const_iterator found = folders_.find(uri); | 223 { |
153 if (found == folders_.end()) | 224 const std::string item = request->groups[1]; |
154 { | 225 |
155 std::string s = "Unknown URI in plugin server-folders: " + uri; | 226 std::string path = folder + "/" + item; |
156 OrthancPluginLogError(context_, s.c_str()); | 227 const char* mime = GetMimeType(path); |
157 OrthancPluginSendHttpStatusCode(context_, output, 404); | 228 |
158 return 0; | 229 std::string s; |
159 } | 230 if (ReadFile(s, path)) |
160 | 231 { |
161 std::string path = found->second + "/" + item; | 232 const char* resource = s.size() ? s.c_str() : NULL; |
162 const char* mime = GetMimeType(path); | 233 OrthancPluginAnswerBuffer(context_, output, resource, s.size(), mime); |
163 | 234 } |
164 std::string s; | 235 else |
165 if (ReadFile(s, path)) | 236 { |
166 { | 237 std::string s = "Inexistent file in served folder: " + path; |
167 const char* resource = s.size() ? s.c_str() : NULL; | 238 OrthancPluginLogError(context_, s.c_str()); |
168 OrthancPluginAnswerBuffer(context_, output, resource, s.size(), mime); | 239 OrthancPluginSendHttpStatusCode(context_, output, 404); |
169 } | 240 } |
170 else | |
171 { | |
172 std::string s = "Inexistent file in served folder: " + path; | |
173 OrthancPluginLogError(context_, s.c_str()); | |
174 OrthancPluginSendHttpStatusCode(context_, output, 404); | |
175 } | 241 } |
176 | 242 |
177 return 0; | 243 return 0; |
178 } | 244 } |
179 | 245 |
198 { | 264 { |
199 s += "<ul>\n"; | 265 s += "<ul>\n"; |
200 for (std::map<std::string, std::string>::const_iterator | 266 for (std::map<std::string, std::string>::const_iterator |
201 it = folders_.begin(); it != folders_.end(); ++it) | 267 it = folders_.begin(); it != folders_.end(); ++it) |
202 { | 268 { |
203 s += "<li><a href=\"" + it->first + "/index.html\">" + it->first + "</li>\n"; | 269 s += "<li><a href=\"/" + it->first + "\">" + it->first + "</li>\n"; |
204 } | 270 } |
205 | 271 |
206 s += "</ul>\n"; | 272 s += "</ul>\n"; |
207 } | 273 } |
208 | 274 |
210 | 276 |
211 OrthancPluginAnswerBuffer(context_, output, s.c_str(), s.size(), "text/html"); | 277 OrthancPluginAnswerBuffer(context_, output, s.c_str(), s.size(), "text/html"); |
212 | 278 |
213 return 0; | 279 return 0; |
214 } | 280 } |
215 | |
216 | 281 |
217 | 282 |
218 extern "C" | 283 extern "C" |
219 { | 284 { |
220 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) | 285 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) |
264 for (Json::Value::Members::const_iterator | 329 for (Json::Value::Members::const_iterator |
265 it = members.begin(); it != members.end(); ++it) | 330 it = members.begin(); it != members.end(); ++it) |
266 { | 331 { |
267 std::string baseUri = *it; | 332 std::string baseUri = *it; |
268 | 333 |
269 // Remove the heading and trailing slashes if any | 334 // Remove the heading and trailing slashes in the root URI, if any |
270 while (!baseUri.empty() && | 335 while (!baseUri.empty() && |
271 *baseUri.begin() == '/') | 336 *baseUri.begin() == '/') |
272 { | 337 { |
273 baseUri = baseUri.substr(1); | 338 baseUri = baseUri.substr(1); |
274 } | 339 } |
283 { | 348 { |
284 OrthancPluginLogError(context_, "The URI of a folder to be served cannot be empty"); | 349 OrthancPluginLogError(context_, "The URI of a folder to be served cannot be empty"); |
285 return -1; | 350 return -1; |
286 } | 351 } |
287 | 352 |
288 const std::string path = configuration["ServeFolders"][*it].asString(); | 353 // Check whether the source folder exists and is indeed a directory |
289 const std::string regex = "/(" + baseUri + ")/(.*)"; | 354 const std::string folder = configuration["ServeFolders"][*it].asString(); |
290 | 355 if (!boost::filesystem::is_directory(folder)) |
291 OrthancPluginRegisterRestCallback(context, regex.c_str(), FolderCallback); | 356 { |
292 folders_[baseUri] = path; | 357 std::string msg = "Trying and serve an inexistent folder: " + folder; |
358 OrthancPluginLogError(context_, msg.c_str()); | |
359 return -1; | |
360 } | |
361 | |
362 folders_[baseUri] = folder; | |
363 | |
364 // Register the callback to serve the index of the folder | |
365 { | |
366 const std::string regex = "/(" + baseUri + ")"; | |
367 OrthancPluginRegisterRestCallback(context, regex.c_str(), IndexCallback); | |
368 } | |
369 | |
370 // Register the callback to serve the folder | |
371 { | |
372 const std::string regex = "/(" + baseUri + ")/(.*)"; | |
373 OrthancPluginRegisterRestCallback(context, regex.c_str(), FolderCallback); | |
374 } | |
293 } | 375 } |
294 | 376 |
295 OrthancPluginRegisterRestCallback(context, INDEX_URI, ListServedFolders); | 377 OrthancPluginRegisterRestCallback(context, INDEX_URI, ListServedFolders); |
296 OrthancPluginSetRootUri(context, INDEX_URI); | 378 OrthancPluginSetRootUri(context, INDEX_URI); |
297 | 379 |