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