Mercurial > hg > orthanc
comparison Plugins/Samples/WebSkeleton/Framework/Plugin.cpp @ 1181:17302d83abfd
Sample plugin framework to serve static resources
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 30 Sep 2014 14:13:20 +0200 |
parents | |
children | 6e7e5ed91c2d |
comparison
equal
deleted
inserted
replaced
1180:dea1c786e1c6 | 1181:17302d83abfd |
---|---|
1 /** | |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege, | |
4 * Belgium | |
5 * | |
6 * Permission is hereby granted, free of charge, to any person | |
7 * obtaining a copy of this software and associated documentation | |
8 * files (the "Software"), to deal in the Software without | |
9 * restriction, including without limitation the rights to use, copy, | |
10 * modify, merge, publish, distribute, sublicense, and/or sell copies | |
11 * of the Software, and to permit persons to whom the Software is | |
12 * furnished to do so, subject to the following conditions: | |
13 * | |
14 * The above copyright notice and this permission notice shall be | |
15 * included in all copies or substantial portions of the Software. | |
16 * | |
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
21 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
22 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
24 * SOFTWARE. | |
25 **/ | |
26 | |
27 | |
28 #include "../Configuration.h" | |
29 | |
30 #include <OrthancCPlugin.h> | |
31 #include <string> | |
32 #include <stdexcept> | |
33 #include <algorithm> | |
34 #include <sys/stat.h> | |
35 | |
36 #if ORTHANC_PLUGIN_STANDALONE == 1 | |
37 // This is an auto-generated file for standalone builds | |
38 #include <EmbeddedResources.h> | |
39 #endif | |
40 | |
41 static OrthancPluginContext* context = NULL; | |
42 | |
43 | |
44 static const char* GetMimeType(const std::string& path) | |
45 { | |
46 size_t dot = path.find_last_of('.'); | |
47 | |
48 std::string extension = (dot == std::string::npos) ? "" : path.substr(dot); | |
49 std::transform(extension.begin(), extension.end(), extension.begin(), tolower); | |
50 | |
51 if (extension == ".html") | |
52 { | |
53 return "text/html"; | |
54 } | |
55 else if (extension == ".css") | |
56 { | |
57 return "text/css"; | |
58 } | |
59 else if (extension == ".js") | |
60 { | |
61 return "application/javascript"; | |
62 } | |
63 else if (extension == ".gif") | |
64 { | |
65 return "image/gif"; | |
66 } | |
67 else if (extension == ".json") | |
68 { | |
69 return "application/json"; | |
70 } | |
71 else if (extension == ".xml") | |
72 { | |
73 return "application/xml"; | |
74 } | |
75 else if (extension == ".png") | |
76 { | |
77 return "image/png"; | |
78 } | |
79 else if (extension == ".jpg" || extension == ".jpeg") | |
80 { | |
81 return "image/jpeg"; | |
82 } | |
83 else | |
84 { | |
85 std::string s = "Unknown MIME type for extension: " + extension; | |
86 OrthancPluginLogWarning(context, s.c_str()); | |
87 return "application/octet-stream"; | |
88 } | |
89 } | |
90 | |
91 | |
92 static bool ReadFile(std::string& content, | |
93 const std::string& path) | |
94 { | |
95 struct stat s; | |
96 if (stat(path.c_str(), &s) != 0 || | |
97 !(s.st_mode & S_IFREG)) | |
98 { | |
99 // Either the path does not exist, or it is not a regular file | |
100 return false; | |
101 } | |
102 | |
103 FILE* fp = fopen(path.c_str(), "rb"); | |
104 if (fp == NULL) | |
105 { | |
106 return false; | |
107 } | |
108 | |
109 long size; | |
110 | |
111 if (fseek(fp, 0, SEEK_END) == -1 || | |
112 (size = ftell(fp)) < 0) | |
113 { | |
114 fclose(fp); | |
115 return false; | |
116 } | |
117 | |
118 content.resize(size); | |
119 | |
120 if (fseek(fp, 0, SEEK_SET) == -1) | |
121 { | |
122 fclose(fp); | |
123 return false; | |
124 } | |
125 | |
126 bool ok = true; | |
127 | |
128 if (size > 0 && | |
129 fread(&content[0], size, 1, fp) != 1) | |
130 { | |
131 ok = false; | |
132 } | |
133 | |
134 fclose(fp); | |
135 | |
136 return ok; | |
137 } | |
138 | |
139 | |
140 #if ORTHANC_PLUGIN_STANDALONE == 1 | |
141 static int32_t ServeStaticResource(OrthancPluginRestOutput* output, | |
142 const char* url, | |
143 const OrthancPluginHttpRequest* request) | |
144 { | |
145 if (request->method != OrthancPluginHttpMethod_Get) | |
146 { | |
147 OrthancPluginSendMethodNotAllowed(context, output, "GET"); | |
148 return 0; | |
149 } | |
150 | |
151 std::string path = "/" + std::string(request->groups[0]); | |
152 const char* mime = GetMimeType(path); | |
153 | |
154 try | |
155 { | |
156 std::string s; | |
157 Orthanc::EmbeddedResources::GetDirectoryResource | |
158 (s, Orthanc::EmbeddedResources::STATIC_RESOURCES, path.c_str()); | |
159 | |
160 const char* resource = s.size() ? s.c_str() : NULL; | |
161 OrthancPluginAnswerBuffer(context, output, resource, s.size(), mime); | |
162 | |
163 return 0; | |
164 } | |
165 catch (std::runtime_error&) | |
166 { | |
167 std::string s = "Unknown static resource in plugin: " + std::string(request->groups[0]); | |
168 OrthancPluginLogError(context, s.c_str()); | |
169 OrthancPluginSendHttpStatusCode(context, output, 404); | |
170 return 0; | |
171 } | |
172 } | |
173 #endif | |
174 | |
175 | |
176 #if ORTHANC_PLUGIN_STANDALONE == 0 | |
177 static int32_t ServeFolder(OrthancPluginRestOutput* output, | |
178 const char* url, | |
179 const OrthancPluginHttpRequest* request) | |
180 { | |
181 if (request->method != OrthancPluginHttpMethod_Get) | |
182 { | |
183 OrthancPluginSendMethodNotAllowed(context, output, "GET"); | |
184 return 0; | |
185 } | |
186 | |
187 std::string path = ORTHANC_PLUGIN_RESOURCES_ROOT "/" + std::string(request->groups[0]); | |
188 const char* mime = GetMimeType(path); | |
189 | |
190 std::string s; | |
191 if (ReadFile(s, path)) | |
192 { | |
193 const char* resource = s.size() ? s.c_str() : NULL; | |
194 OrthancPluginAnswerBuffer(context, output, resource, s.size(), mime); | |
195 | |
196 return 0; | |
197 } | |
198 else | |
199 { | |
200 std::string s = "Unknown static resource in plugin: " + std::string(request->groups[0]); | |
201 OrthancPluginLogError(context, s.c_str()); | |
202 OrthancPluginSendHttpStatusCode(context, output, 404); | |
203 return 0; | |
204 } | |
205 } | |
206 #endif | |
207 | |
208 | |
209 static int32_t RedirectRoot(OrthancPluginRestOutput* output, | |
210 const char* url, | |
211 const OrthancPluginHttpRequest* request) | |
212 { | |
213 if (request->method != OrthancPluginHttpMethod_Get) | |
214 { | |
215 OrthancPluginSendMethodNotAllowed(context, output, "GET"); | |
216 } | |
217 else | |
218 { | |
219 OrthancPluginRedirect(context, output, ORTHANC_PLUGIN_WEB_ROOT "index.html"); | |
220 } | |
221 | |
222 return 0; | |
223 } | |
224 | |
225 | |
226 extern "C" | |
227 { | |
228 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c) | |
229 { | |
230 context = c; | |
231 | |
232 /* Check the version of the Orthanc core */ | |
233 if (OrthancPluginCheckVersion(c) == 0) | |
234 { | |
235 char info[256]; | |
236 sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin", | |
237 c->orthancVersion, | |
238 ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, | |
239 ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, | |
240 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); | |
241 OrthancPluginLogError(context, info); | |
242 return -1; | |
243 } | |
244 | |
245 /* Register the callbacks */ | |
246 | |
247 #if ORTHANC_PLUGIN_STANDALONE == 1 | |
248 OrthancPluginLogInfo(context, "Serving static resources (standalone build)"); | |
249 OrthancPluginRegisterRestCallback(context, ORTHANC_PLUGIN_WEB_ROOT "(.*)", ServeStaticResource); | |
250 #else | |
251 OrthancPluginLogInfo(context, "Serving resources from folder: " ORTHANC_PLUGIN_RESOURCES_ROOT); | |
252 OrthancPluginRegisterRestCallback(context, ORTHANC_PLUGIN_WEB_ROOT "(.*)", ServeFolder); | |
253 #endif | |
254 | |
255 OrthancPluginRegisterRestCallback(context, "/", RedirectRoot); | |
256 | |
257 return 0; | |
258 } | |
259 | |
260 | |
261 ORTHANC_PLUGINS_API void OrthancPluginFinalize() | |
262 { | |
263 } | |
264 | |
265 | |
266 ORTHANC_PLUGINS_API const char* OrthancPluginGetName() | |
267 { | |
268 return ORTHANC_PLUGIN_NAME; | |
269 } | |
270 | |
271 | |
272 ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() | |
273 { | |
274 return ORTHANC_PLUGIN_VERSION; | |
275 } | |
276 } |