Mercurial > hg > orthanc
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; |