comparison Plugins/Engine/OrthancPlugins.cpp @ 1132:f739d3f6cfcf

rename
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 09 Sep 2014 10:43:23 +0200
parents Plugins/Engine/PluginsHttpHandler.cpp@da56a7916e8a
children 382e162c074c
comparison
equal deleted inserted replaced
1131:ac6bd50a8c83 1132:f739d3f6cfcf
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege,
4 * Belgium
5 *
6 * This program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * In addition, as a special exception, the copyright holders of this
12 * program give permission to link the code of its release with the
13 * OpenSSL project's "OpenSSL" library (or with modified versions of it
14 * that use the same license as the "OpenSSL" library), and distribute
15 * the linked executables. You must obey the GNU General Public License
16 * in all respects for all of the code used other than "OpenSSL". If you
17 * modify file(s) with this exception, you may extend this exception to
18 * your version of the file(s), but you are not obligated to do so. If
19 * you do not wish to do so, delete this exception statement from your
20 * version. If you delete this exception statement from all source files
21 * in the program, then also delete it here.
22 *
23 * This program is distributed in the hope that it will be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 **/
31
32
33 #include "PluginsHttpHandler.h"
34
35 #include "../../Core/ChunkedBuffer.h"
36 #include "../../Core/OrthancException.h"
37 #include "../../Core/Toolbox.h"
38 #include "../../Core/HttpServer/HttpOutput.h"
39 #include "../../Core/ImageFormats/PngWriter.h"
40 #include "../../OrthancServer/ServerToolbox.h"
41
42 #include <boost/regex.hpp>
43 #include <glog/logging.h>
44
45 namespace Orthanc
46 {
47 namespace
48 {
49 // Anonymous namespace to avoid clashes between compilation modules
50 class StringHttpOutput : public IHttpOutputStream
51 {
52 private:
53 ChunkedBuffer buffer_;
54
55 public:
56 void GetOutput(std::string& output)
57 {
58 buffer_.Flatten(output);
59 }
60
61 virtual void OnHttpStatusReceived(HttpStatus status)
62 {
63 if (status != HttpStatus_200_Ok)
64 {
65 throw OrthancException(ErrorCode_BadRequest);
66 }
67 }
68
69 virtual void Send(bool isHeader, const void* buffer, size_t length)
70 {
71 if (!isHeader)
72 {
73 buffer_.AddChunk(reinterpret_cast<const char*>(buffer), length);
74 }
75 }
76 };
77 }
78
79
80
81 struct PluginsHttpHandler::PImpl
82 {
83 typedef std::pair<boost::regex*, OrthancPluginRestCallback> RestCallback;
84 typedef std::list<RestCallback> RestCallbacks;
85 typedef std::list<OrthancPluginOnStoredInstanceCallback> OnStoredCallbacks;
86
87 ServerContext& context_;
88 RestCallbacks restCallbacks_;
89 OrthancRestApi* restApi_;
90 OnStoredCallbacks onStoredCallbacks_;
91
92 PImpl(ServerContext& context) : context_(context), restApi_(NULL)
93 {
94 }
95 };
96
97
98 static char* CopyString(const std::string& str)
99 {
100 char *result = reinterpret_cast<char*>(malloc(str.size() + 1));
101 if (result == NULL)
102 {
103 throw OrthancException(ErrorCode_NotEnoughMemory);
104 }
105
106 if (str.size() == 0)
107 {
108 result[0] = '\0';
109 }
110 else
111 {
112 memcpy(result, &str[0], str.size() + 1);
113 }
114
115 return result;
116 }
117
118
119 PluginsHttpHandler::PluginsHttpHandler(ServerContext& context)
120 {
121 pimpl_.reset(new PImpl(context));
122 }
123
124
125 PluginsHttpHandler::~PluginsHttpHandler()
126 {
127 for (PImpl::RestCallbacks::iterator it = pimpl_->restCallbacks_.begin();
128 it != pimpl_->restCallbacks_.end(); ++it)
129 {
130 // Delete the regular expression associated with this callback
131 delete it->first;
132 }
133 }
134
135
136 static void ArgumentsToPlugin(std::vector<const char*>& keys,
137 std::vector<const char*>& values,
138 const HttpHandler::Arguments& arguments)
139 {
140 keys.resize(arguments.size());
141 values.resize(arguments.size());
142
143 size_t pos = 0;
144 for (HttpHandler::Arguments::const_iterator
145 it = arguments.begin(); it != arguments.end(); ++it)
146 {
147 keys[pos] = it->first.c_str();
148 values[pos] = it->second.c_str();
149 pos++;
150 }
151 }
152
153
154 bool PluginsHttpHandler::Handle(HttpOutput& output,
155 HttpMethod method,
156 const UriComponents& uri,
157 const Arguments& headers,
158 const Arguments& getArguments,
159 const std::string& postData)
160 {
161 std::string flatUri = Toolbox::FlattenUri(uri);
162 OrthancPluginRestCallback callback = NULL;
163
164 std::vector<std::string> groups;
165 std::vector<const char*> cgroups;
166
167 // Loop over the callbacks registered by the plugins
168 bool found = false;
169 for (PImpl::RestCallbacks::const_iterator it = pimpl_->restCallbacks_.begin();
170 it != pimpl_->restCallbacks_.end() && !found; ++it)
171 {
172 // Check whether the regular expression associated to this
173 // callback matches the URI
174 boost::cmatch what;
175 if (boost::regex_match(flatUri.c_str(), what, *(it->first)))
176 {
177 callback = it->second;
178
179 // Extract the value of the free parameters of the regular expression
180 if (what.size() > 1)
181 {
182 groups.resize(what.size() - 1);
183 cgroups.resize(what.size() - 1);
184 for (size_t i = 1; i < what.size(); i++)
185 {
186 groups[i - 1] = what[i];
187 cgroups[i - 1] = groups[i - 1].c_str();
188 }
189 }
190
191 found = true;
192 }
193 }
194
195 if (!found)
196 {
197 return false;
198 }
199
200 LOG(INFO) << "Delegating HTTP request to plugin for URI: " << flatUri;
201
202 std::vector<const char*> getKeys, getValues, headersKeys, headersValues;
203
204 OrthancPluginHttpRequest request;
205 memset(&request, 0, sizeof(OrthancPluginHttpRequest));
206
207 ArgumentsToPlugin(headersKeys, headersValues, headers);
208
209 switch (method)
210 {
211 case HttpMethod_Get:
212 request.method = OrthancPluginHttpMethod_Get;
213 ArgumentsToPlugin(getKeys, getValues, getArguments);
214 break;
215
216 case HttpMethod_Post:
217 request.method = OrthancPluginHttpMethod_Post;
218 break;
219
220 case HttpMethod_Delete:
221 request.method = OrthancPluginHttpMethod_Delete;
222 break;
223
224 case HttpMethod_Put:
225 request.method = OrthancPluginHttpMethod_Put;
226 break;
227
228 default:
229 throw OrthancException(ErrorCode_InternalError);
230 }
231
232
233 request.groups = (cgroups.size() ? &cgroups[0] : NULL);
234 request.groupsCount = cgroups.size();
235 request.getCount = getArguments.size();
236 request.body = (postData.size() ? &postData[0] : NULL);
237 request.bodySize = postData.size();
238 request.headersCount = headers.size();
239
240 if (getArguments.size() > 0)
241 {
242 request.getKeys = &getKeys[0];
243 request.getValues = &getValues[0];
244 }
245
246 if (headers.size() > 0)
247 {
248 request.headersKeys = &headersKeys[0];
249 request.headersValues = &headersValues[0];
250 }
251
252 assert(callback != NULL);
253 int32_t error = callback(reinterpret_cast<OrthancPluginRestOutput*>(&output),
254 flatUri.c_str(),
255 &request);
256
257 if (error < 0)
258 {
259 LOG(ERROR) << "Plugin callback failed with error code " << error;
260 return false;
261 }
262 else
263 {
264 if (error > 0)
265 {
266 LOG(WARNING) << "Plugin callback finished with warning code " << error;
267 }
268
269 return true;
270 }
271 }
272
273
274 void PluginsHttpHandler::SignalStoredInstance(DicomInstanceToStore& instance,
275 const std::string& instanceId)
276 {
277 for (PImpl::OnStoredCallbacks::const_iterator
278 callback = pimpl_->onStoredCallbacks_.begin();
279 callback != pimpl_->onStoredCallbacks_.end(); ++callback)
280 {
281 (*callback) (reinterpret_cast<OrthancPluginDicomInstance*>(&instance),
282 instanceId.c_str());
283 }
284 }
285
286
287
288 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
289 const void* data,
290 size_t size)
291 {
292 target.size = size;
293
294 if (size == 0)
295 {
296 target.data = NULL;
297 }
298 else
299 {
300 target.data = malloc(size);
301 if (target.data != NULL)
302 {
303 memcpy(target.data, data, size);
304 }
305 else
306 {
307 throw OrthancException(ErrorCode_NotEnoughMemory);
308 }
309 }
310 }
311
312
313 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
314 const std::string& str)
315 {
316 if (str.size() == 0)
317 {
318 target.size = 0;
319 target.data = NULL;
320 }
321 else
322 {
323 CopyToMemoryBuffer(target, str.c_str(), str.size());
324 }
325 }
326
327
328 void PluginsHttpHandler::RegisterRestCallback(const void* parameters)
329 {
330 const _OrthancPluginRestCallback& p =
331 *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters);
332
333 LOG(INFO) << "Plugin has registered a REST callback on: " << p.pathRegularExpression;
334 pimpl_->restCallbacks_.push_back(std::make_pair(new boost::regex(p.pathRegularExpression), p.callback));
335 }
336
337
338
339 void PluginsHttpHandler::RegisterOnStoredInstanceCallback(const void* parameters)
340 {
341 const _OrthancPluginOnStoredInstanceCallback& p =
342 *reinterpret_cast<const _OrthancPluginOnStoredInstanceCallback*>(parameters);
343
344 LOG(INFO) << "Plugin has registered an OnStoredInstance callback";
345 pimpl_->onStoredCallbacks_.push_back(p.callback);
346 }
347
348
349
350 void PluginsHttpHandler::AnswerBuffer(const void* parameters)
351 {
352 const _OrthancPluginAnswerBuffer& p =
353 *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters);
354
355 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
356 translatedOutput->SetContentType(p.mimeType);
357 translatedOutput->SendBody(p.answer, p.answerSize);
358 }
359
360
361 void PluginsHttpHandler::Redirect(const void* parameters)
362 {
363 const _OrthancPluginOutputPlusArgument& p =
364 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters);
365
366 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
367 translatedOutput->Redirect(p.argument);
368 }
369
370
371 void PluginsHttpHandler::SendHttpStatusCode(const void* parameters)
372 {
373 const _OrthancPluginSendHttpStatusCode& p =
374 *reinterpret_cast<const _OrthancPluginSendHttpStatusCode*>(parameters);
375
376 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
377 translatedOutput->SendStatus(static_cast<HttpStatus>(p.status));
378 }
379
380
381 void PluginsHttpHandler::SendUnauthorized(const void* parameters)
382 {
383 const _OrthancPluginOutputPlusArgument& p =
384 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters);
385
386 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
387 translatedOutput->SendUnauthorized(p.argument);
388 }
389
390
391 void PluginsHttpHandler::SendMethodNotAllowed(const void* parameters)
392 {
393 const _OrthancPluginOutputPlusArgument& p =
394 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters);
395
396 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
397 translatedOutput->SendMethodNotAllowed(p.argument);
398 }
399
400
401 void PluginsHttpHandler::SetCookie(const void* parameters)
402 {
403 const _OrthancPluginSetCookie& p =
404 *reinterpret_cast<const _OrthancPluginSetCookie*>(parameters);
405
406 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
407 translatedOutput->SetCookie(p.cookie, p.value);
408 }
409
410
411 void PluginsHttpHandler::CompressAndAnswerPngImage(const void* parameters)
412 {
413 const _OrthancPluginCompressAndAnswerPngImage& p =
414 *reinterpret_cast<const _OrthancPluginCompressAndAnswerPngImage*>(parameters);
415
416 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
417
418 PixelFormat format;
419 switch (p.format)
420 {
421 case OrthancPluginPixelFormat_Grayscale8:
422 format = PixelFormat_Grayscale8;
423 break;
424
425 case OrthancPluginPixelFormat_Grayscale16:
426 format = PixelFormat_Grayscale16;
427 break;
428
429 case OrthancPluginPixelFormat_SignedGrayscale16:
430 format = PixelFormat_SignedGrayscale16;
431 break;
432
433 case OrthancPluginPixelFormat_RGB24:
434 format = PixelFormat_RGB24;
435 break;
436
437 case OrthancPluginPixelFormat_RGBA32:
438 format = PixelFormat_RGBA32;
439 break;
440
441 default:
442 throw OrthancException(ErrorCode_ParameterOutOfRange);
443 }
444
445 ImageAccessor accessor;
446 accessor.AssignReadOnly(format, p.width, p.height, p.pitch, p.buffer);
447
448 PngWriter writer;
449 std::string png;
450 writer.WriteToMemory(png, accessor);
451
452 translatedOutput->SetContentType("image/png");
453 translatedOutput->SendBody(png);
454 }
455
456
457 void PluginsHttpHandler::GetDicomForInstance(const void* parameters)
458 {
459 const _OrthancPluginGetDicomForInstance& p =
460 *reinterpret_cast<const _OrthancPluginGetDicomForInstance*>(parameters);
461
462 std::string dicom;
463 pimpl_->context_.ReadFile(dicom, p.instanceId, FileContentType_Dicom);
464 CopyToMemoryBuffer(*p.target, dicom);
465 }
466
467
468 void PluginsHttpHandler::RestApiGet(const void* parameters)
469 {
470 const _OrthancPluginRestApiGet& p =
471 *reinterpret_cast<const _OrthancPluginRestApiGet*>(parameters);
472
473 HttpHandler::Arguments headers; // No HTTP header
474 std::string body; // No body for a GET request
475
476 UriComponents uri;
477 HttpHandler::Arguments getArguments;
478 HttpHandler::ParseGetQuery(uri, getArguments, p.uri);
479
480 StringHttpOutput stream;
481 HttpOutput http(stream, false /* no keep alive */);
482
483 LOG(INFO) << "Plugin making REST GET call on URI " << p.uri;
484
485 if (pimpl_->restApi_ != NULL &&
486 pimpl_->restApi_->Handle(http, HttpMethod_Get, uri, headers, getArguments, body))
487 {
488 std::string result;
489 stream.GetOutput(result);
490 CopyToMemoryBuffer(*p.target, result);
491 }
492 else
493 {
494 throw OrthancException(ErrorCode_BadRequest);
495 }
496 }
497
498
499 void PluginsHttpHandler::RestApiPostPut(bool isPost, const void* parameters)
500 {
501 const _OrthancPluginRestApiPostPut& p =
502 *reinterpret_cast<const _OrthancPluginRestApiPostPut*>(parameters);
503
504 HttpHandler::Arguments headers; // No HTTP header
505 HttpHandler::Arguments getArguments; // No GET argument for POST/PUT
506
507 UriComponents uri;
508 Toolbox::SplitUriComponents(uri, p.uri);
509
510 // TODO Avoid unecessary memcpy
511 std::string body(p.body, p.bodySize);
512
513 StringHttpOutput stream;
514 HttpOutput http(stream, false /* no keep alive */);
515
516 HttpMethod method = (isPost ? HttpMethod_Post : HttpMethod_Put);
517 LOG(INFO) << "Plugin making REST " << EnumerationToString(method) << " call on URI " << p.uri;
518
519 if (pimpl_->restApi_ != NULL &&
520 pimpl_->restApi_->Handle(http, method, uri, headers, getArguments, body))
521 {
522 std::string result;
523 stream.GetOutput(result);
524 CopyToMemoryBuffer(*p.target, result);
525 }
526 else
527 {
528 throw OrthancException(ErrorCode_BadRequest);
529 }
530 }
531
532
533 void PluginsHttpHandler::RestApiDelete(const void* parameters)
534 {
535 // The "parameters" point to the URI
536 UriComponents uri;
537 Toolbox::SplitUriComponents(uri, reinterpret_cast<const char*>(parameters));
538
539 HttpHandler::Arguments headers; // No HTTP header
540 HttpHandler::Arguments getArguments; // No GET argument for POST/PUT
541 std::string body; // No body for DELETE
542
543 StringHttpOutput stream;
544 HttpOutput http(stream, false /* no keep alive */);
545
546 LOG(INFO) << "Plugin making REST DELETE call on URI "
547 << reinterpret_cast<const char*>(parameters);
548
549 if (pimpl_->restApi_ == NULL ||
550 !pimpl_->restApi_->Handle(http, HttpMethod_Delete, uri, headers, getArguments, body))
551 {
552 throw OrthancException(ErrorCode_BadRequest);
553 }
554 }
555
556
557 void PluginsHttpHandler::LookupResource(_OrthancPluginService service,
558 const void* parameters)
559 {
560 const _OrthancPluginLookupResource& p =
561 *reinterpret_cast<const _OrthancPluginLookupResource*>(parameters);
562
563 /**
564 * The enumeration below only uses the tags that are indexed in
565 * the Orthanc database. It reflects the
566 * "CandidateResources::ApplyFilter()" method of the
567 * "OrthancFindRequestHandler" class.
568 **/
569
570 DicomTag tag(0, 0);
571 ResourceType level;
572 switch (service)
573 {
574 case _OrthancPluginService_LookupPatient:
575 tag = DICOM_TAG_PATIENT_ID;
576 level = ResourceType_Patient;
577 break;
578
579 case _OrthancPluginService_LookupStudy:
580 tag = DICOM_TAG_STUDY_INSTANCE_UID;
581 level = ResourceType_Study;
582 break;
583
584 case _OrthancPluginService_LookupStudyWithAccessionNumber:
585 tag = DICOM_TAG_ACCESSION_NUMBER;
586 level = ResourceType_Study;
587 break;
588
589 case _OrthancPluginService_LookupSeries:
590 tag = DICOM_TAG_SERIES_INSTANCE_UID;
591 level = ResourceType_Series;
592 break;
593
594 case _OrthancPluginService_LookupInstance:
595 tag = DICOM_TAG_SOP_INSTANCE_UID;
596 level = ResourceType_Instance;
597 break;
598
599 default:
600 throw OrthancException(ErrorCode_InternalError);
601 }
602
603 std::list<std::string> result;
604 pimpl_->context_.GetIndex().LookupTagValue(result, tag, p.identifier, level);
605
606 if (result.size() == 1)
607 {
608 *p.result = CopyString(result.front());
609 }
610 else
611 {
612 throw OrthancException(ErrorCode_UnknownResource);
613 }
614 }
615
616
617 static void AccessInstanceMetadataInternal(bool checkExistence,
618 const _OrthancPluginAccessDicomInstance& params,
619 const DicomInstanceToStore& instance)
620 {
621 MetadataType metadata;
622
623 try
624 {
625 metadata = StringToMetadata(params.key);
626 }
627 catch (OrthancException&)
628 {
629 // Unknown metadata
630 if (checkExistence)
631 {
632 *params.resultInt64 = -1;
633 }
634 else
635 {
636 *params.resultString = NULL;
637 }
638
639 return;
640 }
641
642 ServerIndex::MetadataMap::const_iterator it =
643 instance.GetMetadata().find(std::make_pair(ResourceType_Instance, metadata));
644
645 if (checkExistence)
646 {
647 if (it != instance.GetMetadata().end())
648 {
649 *params.resultInt64 = 1;
650 }
651 else
652 {
653 *params.resultInt64 = 0;
654 }
655 }
656 else
657 {
658 if (it != instance.GetMetadata().end())
659 {
660 *params.resultString = it->second.c_str();
661 }
662 else
663 {
664 // Error: Missing metadata
665 *params.resultString = NULL;
666 }
667 }
668 }
669
670
671 static void AccessDicomInstance(_OrthancPluginService service,
672 const void* parameters)
673 {
674 const _OrthancPluginAccessDicomInstance& p =
675 *reinterpret_cast<const _OrthancPluginAccessDicomInstance*>(parameters);
676
677 DicomInstanceToStore& instance =
678 *reinterpret_cast<DicomInstanceToStore*>(p.instance);
679
680 switch (service)
681 {
682 case _OrthancPluginService_GetInstanceRemoteAet:
683 *p.resultString = instance.GetRemoteAet().c_str();
684 return;
685
686 case _OrthancPluginService_GetInstanceSize:
687 *p.resultInt64 = instance.GetBufferSize();
688 return;
689
690 case _OrthancPluginService_GetInstanceData:
691 *p.resultString = instance.GetBufferData();
692 return;
693
694 case _OrthancPluginService_HasInstanceMetadata:
695 AccessInstanceMetadataInternal(true, p, instance);
696 return;
697
698 case _OrthancPluginService_GetInstanceMetadata:
699 AccessInstanceMetadataInternal(false, p, instance);
700 return;
701
702 case _OrthancPluginService_GetInstanceJson:
703 case _OrthancPluginService_GetInstanceSimplifiedJson:
704 {
705 Json::StyledWriter writer;
706 std::string s;
707
708 if (service == _OrthancPluginService_GetInstanceJson)
709 {
710 s = writer.write(instance.GetJson());
711 }
712 else
713 {
714 Json::Value simplified;
715 SimplifyTags(simplified, instance.GetJson());
716 s = writer.write(simplified);
717 }
718
719 *p.resultStringToFree = CopyString(s);
720 return;
721 }
722
723 default:
724 throw OrthancException(ErrorCode_InternalError);
725 }
726 }
727
728
729 bool PluginsHttpHandler::InvokeService(_OrthancPluginService service,
730 const void* parameters)
731 {
732 switch (service)
733 {
734 case _OrthancPluginService_RegisterRestCallback:
735 RegisterRestCallback(parameters);
736 return true;
737
738 case _OrthancPluginService_RegisterOnStoredInstanceCallback:
739 RegisterOnStoredInstanceCallback(parameters);
740 return true;
741
742 case _OrthancPluginService_AnswerBuffer:
743 AnswerBuffer(parameters);
744 return true;
745
746 case _OrthancPluginService_CompressAndAnswerPngImage:
747 CompressAndAnswerPngImage(parameters);
748 return true;
749
750 case _OrthancPluginService_GetDicomForInstance:
751 GetDicomForInstance(parameters);
752 return true;
753
754 case _OrthancPluginService_RestApiGet:
755 RestApiGet(parameters);
756 return true;
757
758 case _OrthancPluginService_RestApiPost:
759 RestApiPostPut(true, parameters);
760 return true;
761
762 case _OrthancPluginService_RestApiDelete:
763 RestApiDelete(parameters);
764 return true;
765
766 case _OrthancPluginService_RestApiPut:
767 RestApiPostPut(false, parameters);
768 return true;
769
770 case _OrthancPluginService_Redirect:
771 Redirect(parameters);
772 return true;
773
774 case _OrthancPluginService_SendUnauthorized:
775 SendUnauthorized(parameters);
776 return true;
777
778 case _OrthancPluginService_SendMethodNotAllowed:
779 SendMethodNotAllowed(parameters);
780 return true;
781
782 case _OrthancPluginService_SendHttpStatusCode:
783 SendHttpStatusCode(parameters);
784 return true;
785
786 case _OrthancPluginService_SetCookie:
787 SetCookie(parameters);
788 return true;
789
790 case _OrthancPluginService_LookupPatient:
791 case _OrthancPluginService_LookupStudy:
792 case _OrthancPluginService_LookupStudyWithAccessionNumber:
793 case _OrthancPluginService_LookupSeries:
794 case _OrthancPluginService_LookupInstance:
795 LookupResource(service, parameters);
796 return true;
797
798 case _OrthancPluginService_GetInstanceRemoteAet:
799 case _OrthancPluginService_GetInstanceSize:
800 case _OrthancPluginService_GetInstanceData:
801 case _OrthancPluginService_GetInstanceJson:
802 case _OrthancPluginService_GetInstanceSimplifiedJson:
803 case _OrthancPluginService_HasInstanceMetadata:
804 case _OrthancPluginService_GetInstanceMetadata:
805 AccessDicomInstance(service, parameters);
806 return true;
807
808 default:
809 return false;
810 }
811 }
812
813
814 void PluginsHttpHandler::SetOrthancRestApi(OrthancRestApi& restApi)
815 {
816 pimpl_->restApi_ = &restApi;
817 }
818
819 }