comparison Plugins/Engine/PluginsHttpHandler.cpp @ 912:dcb2469f00f4 plugins

PluginsHttpHandler::RestApiGet
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 20 Jun 2014 14:55:24 +0200
parents ef71057d8b26
children 3e43de893d88
comparison
equal deleted inserted replaced
911:306afd58a0b3 912:dcb2469f00f4
30 **/ 30 **/
31 31
32 32
33 #include "PluginsHttpHandler.h" 33 #include "PluginsHttpHandler.h"
34 34
35 #include "../../Core/ChunkedBuffer.h"
35 #include "../../Core/OrthancException.h" 36 #include "../../Core/OrthancException.h"
36 #include "../../Core/Toolbox.h" 37 #include "../../Core/Toolbox.h"
37 #include "../../Core/HttpServer/HttpOutput.h" 38 #include "../../Core/HttpServer/HttpOutput.h"
38 #include "../../Core/ImageFormats/PngWriter.h" 39 #include "../../Core/ImageFormats/PngWriter.h"
39 40
43 namespace Orthanc 44 namespace Orthanc
44 { 45 {
45 namespace 46 namespace
46 { 47 {
47 // Anonymous namespace to avoid clashes between compilation modules 48 // Anonymous namespace to avoid clashes between compilation modules
48 class StringHttpOutput : public HttpOutput 49 class StringHttpOutput : public IHttpOutputStream
49 { 50 {
50 private: 51 private:
51 std::string target_; 52 ChunkedBuffer buffer_;
52 53
53 public: 54 public:
54 const std::string& GetOutput() const 55 void GetOutput(std::string& output)
55 { 56 {
56 return target_; 57 buffer_.Flatten(output);
58 }
59
60 virtual void OnHttpStatusReceived(HttpStatus status)
61 {
62 if (status != HttpStatus_200_Ok)
63 {
64 throw OrthancException(ErrorCode_BadRequest);
65 }
57 } 66 }
58 67
59 virtual void Send(bool isHeader, const void* buffer, size_t length) 68 virtual void Send(bool isHeader, const void* buffer, size_t length)
60 { 69 {
61 if (isHeader) 70 if (!isHeader)
62 { 71 {
63 return; 72 buffer_.AddChunk(reinterpret_cast<const char*>(buffer), length);
64 }
65
66 size_t pos = target_.size();
67 target_.resize(pos + length);
68
69 if (length > 0)
70 {
71 memcpy(&target_[pos], buffer, length);
72 } 73 }
73 } 74 }
74 }; 75 };
75 } 76 }
76 77
223 return true; 224 return true;
224 } 225 }
225 } 226 }
226 227
227 228
229 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
230 const void* data,
231 size_t size)
232 {
233 target.size = size;
234
235 if (size == 0)
236 {
237 target.data = NULL;
238 }
239 else
240 {
241 target.data = malloc(size);
242 if (target.data != NULL)
243 {
244 memcpy(target.data, data, size);
245 }
246 else
247 {
248 throw OrthancException(ErrorCode_NotEnoughMemory);
249 }
250 }
251 }
252
253
254 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
255 const std::string& str)
256 {
257 if (str.size() == 0)
258 {
259 target.size = 0;
260 target.data = NULL;
261 }
262 else
263 {
264 CopyToMemoryBuffer(target, str.c_str(), str.size());
265 }
266 }
267
268
269 void PluginsHttpHandler::RegisterRestCallback(const void* parameters)
270 {
271 const _OrthancPluginRestCallback& p =
272 *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters);
273
274 LOG(INFO) << "Plugin has registered a REST callback on: " << p.pathRegularExpression;
275 pimpl_->callbacks_.push_back(std::make_pair(new boost::regex(p.pathRegularExpression), p.callback));
276 }
277
278
279
280 void PluginsHttpHandler::AnswerBuffer(const void* parameters)
281 {
282 const _OrthancPluginAnswerBuffer& p =
283 *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters);
284
285 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
286 translatedOutput->AnswerBufferWithContentType(p.answer, p.answerSize, p.mimeType);
287 }
288
289
290 void PluginsHttpHandler::CompressAndAnswerPngImage(const void* parameters)
291 {
292 const _OrthancPluginCompressAndAnswerPngImage& p =
293 *reinterpret_cast<const _OrthancPluginCompressAndAnswerPngImage*>(parameters);
294
295 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
296
297 PixelFormat format;
298 switch (p.format)
299 {
300 case OrthancPluginPixelFormat_Grayscale8:
301 format = PixelFormat_Grayscale8;
302 break;
303
304 case OrthancPluginPixelFormat_Grayscale16:
305 format = PixelFormat_Grayscale16;
306 break;
307
308 case OrthancPluginPixelFormat_SignedGrayscale16:
309 format = PixelFormat_SignedGrayscale16;
310 break;
311
312 case OrthancPluginPixelFormat_RGB24:
313 format = PixelFormat_RGB24;
314 break;
315
316 case OrthancPluginPixelFormat_RGBA32:
317 format = PixelFormat_RGBA32;
318 break;
319
320 default:
321 throw OrthancException(ErrorCode_ParameterOutOfRange);
322 }
323
324 ImageAccessor accessor;
325 accessor.AssignReadOnly(format, p.width, p.height, p.pitch, p.buffer);
326
327 PngWriter writer;
328 std::string png;
329 writer.WriteToMemory(png, accessor);
330
331 translatedOutput->AnswerBufferWithContentType(png, "image/png");
332 }
333
334
335 void PluginsHttpHandler::GetDicomForInstance(const void* parameters)
336 {
337 const _OrthancPluginGetDicomForInstance& p =
338 *reinterpret_cast<const _OrthancPluginGetDicomForInstance*>(parameters);
339
340 std::string dicom;
341 pimpl_->context_.ReadFile(dicom, p.instanceId, FileContentType_Dicom);
342 CopyToMemoryBuffer(*p.target, dicom);
343 }
344
345
346 void PluginsHttpHandler::RestApiGet(const void* parameters)
347 {
348 const _OrthancPluginRestApiGet& p =
349 *reinterpret_cast<const _OrthancPluginRestApiGet*>(parameters);
350
351 HttpHandler::Arguments headers; // No HTTP header
352 std::string body; // No body for a GET request
353
354 UriComponents uri;
355 HttpHandler::Arguments getArguments;
356 HttpHandler::ParseGetQuery(uri, getArguments, p.uri);
357
358 StringHttpOutput stream;
359 HttpOutput http(stream);
360
361 LOG(INFO) << "Plugin making REST call on URI " << p.uri;
362
363 if (pimpl_->restApi_ != NULL &&
364 pimpl_->restApi_->Handle(http, HttpMethod_Get, uri, headers, getArguments, body))
365 {
366 std::string result;
367 stream.GetOutput(result);
368 CopyToMemoryBuffer(*p.target, result);
369 }
370 else
371 {
372 throw OrthancException(ErrorCode_BadRequest);
373 }
374 }
375
376
228 bool PluginsHttpHandler::InvokeService(_OrthancPluginService service, 377 bool PluginsHttpHandler::InvokeService(_OrthancPluginService service,
229 const void* parameters) 378 const void* parameters)
230 { 379 {
231 switch (service) 380 switch (service)
232 { 381 {
233 case _OrthancPluginService_RegisterRestCallback: 382 case _OrthancPluginService_RegisterRestCallback:
234 { 383 {
235 const _OrthancPluginRestCallback& p = 384 RegisterRestCallback(parameters);
236 *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters);
237
238 LOG(INFO) << "Plugin has registered a REST callback on: " << p.pathRegularExpression;
239 pimpl_->callbacks_.push_back(std::make_pair(new boost::regex(p.pathRegularExpression), p.callback));
240
241 return true; 385 return true;
242 } 386 }
243 387
244 case _OrthancPluginService_AnswerBuffer: 388 case _OrthancPluginService_AnswerBuffer:
245 { 389 {
246 const _OrthancPluginAnswerBuffer& p = 390 AnswerBuffer(parameters);
247 *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters);
248
249 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
250 translatedOutput->AnswerBufferWithContentType(p.answer, p.answerSize, p.mimeType);
251
252 return true; 391 return true;
253 } 392 }
254 393
255 case _OrthancPluginService_CompressAndAnswerPngImage: 394 case _OrthancPluginService_CompressAndAnswerPngImage:
256 { 395 {
257 const _OrthancPluginCompressAndAnswerPngImage& p = 396 CompressAndAnswerPngImage(parameters);
258 *reinterpret_cast<const _OrthancPluginCompressAndAnswerPngImage*>(parameters);
259
260 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
261
262 PixelFormat format;
263 switch (p.format)
264 {
265 case OrthancPluginPixelFormat_Grayscale8:
266 format = PixelFormat_Grayscale8;
267 break;
268
269 case OrthancPluginPixelFormat_Grayscale16:
270 format = PixelFormat_Grayscale16;
271 break;
272
273 case OrthancPluginPixelFormat_SignedGrayscale16:
274 format = PixelFormat_SignedGrayscale16;
275 break;
276
277 case OrthancPluginPixelFormat_RGB24:
278 format = PixelFormat_RGB24;
279 break;
280
281 case OrthancPluginPixelFormat_RGBA32:
282 format = PixelFormat_RGBA32;
283 break;
284
285 default:
286 throw OrthancException(ErrorCode_ParameterOutOfRange);
287 }
288
289 ImageAccessor accessor;
290 accessor.AssignReadOnly(format, p.width, p.height, p.pitch, p.buffer);
291
292 PngWriter writer;
293 std::string png;
294 writer.WriteToMemory(png, accessor);
295
296 translatedOutput->AnswerBufferWithContentType(png, "image/png");
297
298 return true; 397 return true;
299 } 398 }
300 399
301 case _OrthancPluginService_GetDicomForInstance: 400 case _OrthancPluginService_GetDicomForInstance:
302 { 401 {
303 const _OrthancPluginGetDicomForInstance& p = 402 GetDicomForInstance(parameters);
304 *reinterpret_cast<const _OrthancPluginGetDicomForInstance*>(parameters); 403 return true;
305 404 }
306 std::string dicom; 405
307 pimpl_->context_.ReadFile(dicom, p.instanceId, FileContentType_Dicom); 406 case _OrthancPluginService_RestApiGet:
308 407 {
309 p.target->size = dicom.size(); 408 RestApiGet(parameters);
310
311 if (dicom.size() == 0)
312 {
313 p.target->data = NULL;
314 }
315 else
316 {
317 p.target->data = malloc(dicom.size());
318 if (p.target->data != NULL)
319 {
320 memcpy(p.target->data, &dicom[0], dicom.size());
321 }
322 else
323 {
324 return false;
325 }
326 }
327
328 return true; 409 return true;
329 } 410 }
330 411
331 default: 412 default:
332 return false; 413 return false;