comparison Plugins/Engine/PluginsHttpHandler.cpp @ 901:7d88f3f4a3b3 plugins

refactoring IsServedUri, answer PNG images, regular expression groups
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 18 Jun 2014 15:22:13 +0200
parents 1b92ce45cc8d
children 2732b5f57d9c
comparison
equal deleted inserted replaced
900:1b92ce45cc8d 901:7d88f3f4a3b3
33 #include "PluginsHttpHandler.h" 33 #include "PluginsHttpHandler.h"
34 34
35 #include "../../Core/OrthancException.h" 35 #include "../../Core/OrthancException.h"
36 #include "../../Core/Toolbox.h" 36 #include "../../Core/Toolbox.h"
37 #include "../../Core/HttpServer/HttpOutput.h" 37 #include "../../Core/HttpServer/HttpOutput.h"
38 #include "../../Core/ImageFormats/PngWriter.h"
38 39
39 #include <boost/regex.hpp> 40 #include <boost/regex.hpp>
40 #include <glog/logging.h> 41 #include <glog/logging.h>
41 42
42 namespace Orthanc 43 namespace Orthanc
45 { 46 {
46 typedef std::pair<boost::regex*, OrthancPluginRestCallback> Callback; 47 typedef std::pair<boost::regex*, OrthancPluginRestCallback> Callback;
47 typedef std::list<Callback> Callbacks; 48 typedef std::list<Callback> Callbacks;
48 49
49 Callbacks callbacks_; 50 Callbacks callbacks_;
50 OrthancPluginRestCallback currentCallback_;
51
52 PImpl() : currentCallback_(NULL)
53 {
54 }
55 }; 51 };
56 52
57 53
58 PluginsHttpHandler::PluginsHttpHandler() 54 PluginsHttpHandler::PluginsHttpHandler()
59 { 55 {
68 { 64 {
69 delete it->first; 65 delete it->first;
70 } 66 }
71 } 67 }
72 68
73
74 bool PluginsHttpHandler::IsServedUri(const UriComponents& uri)
75 {
76 pimpl_->currentCallback_ = NULL;
77 std::string tmp = Toolbox::FlattenUri(uri);
78
79 for (PImpl::Callbacks::const_iterator it = pimpl_->callbacks_.begin();
80 it != pimpl_->callbacks_.end(); it++)
81 {
82 if (boost::regex_match(tmp, *(it->first)))
83 {
84 pimpl_->currentCallback_ = it->second;
85 return true;
86 }
87 }
88
89 return false;
90 }
91 69
92 bool PluginsHttpHandler::Handle(HttpOutput& output, 70 bool PluginsHttpHandler::Handle(HttpOutput& output,
93 HttpMethod method, 71 HttpMethod method,
94 const UriComponents& uri, 72 const UriComponents& uri,
95 const Arguments& headers, 73 const Arguments& headers,
96 const Arguments& getArguments, 74 const Arguments& getArguments,
97 const std::string& postData) 75 const std::string& postData)
98 { 76 {
99 std::string flatUri = Toolbox::FlattenUri(uri); 77 std::string flatUri = Toolbox::FlattenUri(uri);
78 OrthancPluginRestCallback callback = NULL;
79
80 std::vector<std::string> groups;
81 std::vector<const char*> cgroups;
82
83 bool found = false;
84 for (PImpl::Callbacks::const_iterator it = pimpl_->callbacks_.begin();
85 it != pimpl_->callbacks_.end() && !found; it++)
86 {
87 boost::cmatch what;
88 if (boost::regex_match(flatUri.c_str(), what, *(it->first)))
89 {
90 callback = it->second;
91
92 if (what.size() > 1)
93 {
94 groups.resize(what.size() - 1);
95 cgroups.resize(what.size() - 1);
96 for (size_t i = 1; i < what.size(); i++)
97 {
98 groups[i - 1] = what[i];
99 cgroups[i - 1] = groups[i - 1].c_str();
100 }
101 }
102
103 found = true;
104 }
105 }
106
107 if (!found)
108 {
109 return false;
110 }
100 111
101 LOG(INFO) << "Delegating HTTP request to plugin for URI: " << flatUri; 112 LOG(INFO) << "Delegating HTTP request to plugin for URI: " << flatUri;
102 113
103 std::vector<const char*> getKeys(getArguments.size()); 114 std::vector<const char*> getKeys(getArguments.size());
104 std::vector<const char*> getValues(getArguments.size()); 115 std::vector<const char*> getValues(getArguments.size());
138 default: 149 default:
139 throw OrthancException(ErrorCode_InternalError); 150 throw OrthancException(ErrorCode_InternalError);
140 } 151 }
141 152
142 153
154 request.groupValues = (cgroups.size() ? &cgroups[0] : NULL);
155 request.groupCount = cgroups.size();
143 request.getCount = getArguments.size(); 156 request.getCount = getArguments.size();
144 request.body = (postData.size() ? &postData[0] : NULL); 157 request.body = (postData.size() ? &postData[0] : NULL);
145 request.bodySize = postData.size(); 158 request.bodySize = postData.size();
146 159
147 if (getArguments.size() > 0) 160 if (getArguments.size() > 0)
148 { 161 {
149 request.getKeys = &getKeys[0]; 162 request.getKeys = &getKeys[0];
150 request.getValues = &getValues[0]; 163 request.getValues = &getValues[0];
151 } 164 }
152 165
153 assert(pimpl_->currentCallback_ != NULL); 166 assert(callback != NULL);
154 int32_t error = (*pimpl_->currentCallback_) (reinterpret_cast<OrthancPluginRestOutput*>(&output), 167 int32_t error = callback(reinterpret_cast<OrthancPluginRestOutput*>(&output),
155 flatUri.c_str(), 168 flatUri.c_str(),
156 &request); 169 &request);
157 170
158 if (error < 0) 171 if (error < 0)
159 { 172 {
160 LOG(ERROR) << "Plugin failed with error code " << error; 173 LOG(ERROR) << "Plugin failed with error code " << error;
161 return false; 174 return false;
173 186
174 187
175 bool PluginsHttpHandler::InvokeService(OrthancPluginService service, 188 bool PluginsHttpHandler::InvokeService(OrthancPluginService service,
176 const void* parameters) 189 const void* parameters)
177 { 190 {
178
179
180 /*void PluginsManager::RegisterRestCallback(const OrthancPluginContext* context,
181 const char* pathRegularExpression,
182 OrthancPluginRestCallback callback)
183 {
184 LOG(INFO) << "Plugin has registered a REST callback on: " << pathRegularExpression;
185 PluginsManager* manager = reinterpret_cast<PluginsManager*>(context->pluginsManager);
186 manager->restCallbacks_.push_back(std::make_pair(pathRegularExpression, callback));
187 }*/
188
189
190 /*static void AnswerBuffer(OrthancPluginRestOutput* output,
191 const char* answer,
192 uint32_t answerSize,
193 const char* mimeType)
194 {
195 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(output);
196 translatedOutput->AnswerBufferWithContentType(answer, answerSize, mimeType);
197 }*/
198
199
200
201 /*for (PluginsManager::RestCallbacks::const_iterator
202 it = manager.GetRestCallbacks().begin(); it != manager.GetRestCallbacks().end(); ++it)
203 {
204 pimpl_->callbacks_.push_back(std::make_pair(new boost::regex(it->first), it->second));
205 }*/
206
207
208 switch (service) 191 switch (service)
209 { 192 {
210 case OrthancPluginService_RegisterRestCallback: 193 case OrthancPluginService_RegisterRestCallback:
211 { 194 {
212 const _OrthancPluginRestCallbackParams& p = 195 const _OrthancPluginRestCallbackParams& p =
227 translatedOutput->AnswerBufferWithContentType(p.answer, p.answerSize, p.mimeType); 210 translatedOutput->AnswerBufferWithContentType(p.answer, p.answerSize, p.mimeType);
228 211
229 return true; 212 return true;
230 } 213 }
231 214
215 case OrthancPluginService_CompressAndAnswerPngImage:
216 {
217 const _OrthancPluginCompressAndAnswerPngImageParams& p =
218 *reinterpret_cast<const _OrthancPluginCompressAndAnswerPngImageParams*>(parameters);
219
220 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
221
222 PixelFormat format;
223 switch (p.format)
224 {
225 case OrthancPluginPixelFormat_Grayscale8:
226 format = PixelFormat_Grayscale8;
227 break;
228
229 case OrthancPluginPixelFormat_Grayscale16:
230 format = PixelFormat_Grayscale16;
231 break;
232
233 case OrthancPluginPixelFormat_SignedGrayscale16:
234 format = PixelFormat_SignedGrayscale16;
235 break;
236
237 case OrthancPluginPixelFormat_RGB24:
238 format = PixelFormat_RGB24;
239 break;
240
241 case OrthancPluginPixelFormat_RGBA32:
242 format = PixelFormat_RGBA32;
243 break;
244
245 default:
246 throw OrthancException(ErrorCode_ParameterOutOfRange);
247 }
248
249 ImageAccessor accessor;
250 accessor.AssignReadOnly(format, p.width, p.height, p.pitch, p.buffer);
251
252 PngWriter writer;
253 std::string png;
254 writer.WriteToMemory(png, accessor);
255
256 translatedOutput->AnswerBufferWithContentType(png, "image/png");
257
258 return true;
259 }
260
232 default: 261 default:
233 return false; 262 return false;
234 } 263 }
235 } 264 }
236 265