diff 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
line wrap: on
line diff
--- a/Plugins/Engine/PluginsHttpHandler.cpp	Fri Jun 20 13:45:22 2014 +0200
+++ b/Plugins/Engine/PluginsHttpHandler.cpp	Fri Jun 20 14:55:24 2014 +0200
@@ -32,6 +32,7 @@
 
 #include "PluginsHttpHandler.h"
 
+#include "../../Core/ChunkedBuffer.h"
 #include "../../Core/OrthancException.h"
 #include "../../Core/Toolbox.h"
 #include "../../Core/HttpServer/HttpOutput.h"
@@ -45,30 +46,30 @@
   namespace
   {
     // Anonymous namespace to avoid clashes between compilation modules
-    class StringHttpOutput : public HttpOutput
+    class StringHttpOutput : public IHttpOutputStream
     {
     private:
-      std::string target_;
+      ChunkedBuffer buffer_;
 
     public:
-      const std::string& GetOutput() const
+      void GetOutput(std::string& output)
       {
-        return target_;
+        buffer_.Flatten(output);
+      }
+
+      virtual void OnHttpStatusReceived(HttpStatus status)
+      {
+        if (status != HttpStatus_200_Ok)
+        {
+          throw OrthancException(ErrorCode_BadRequest);
+        }
       }
 
       virtual void Send(bool isHeader, const void* buffer, size_t length)
       {
-        if (isHeader)
+        if (!isHeader)
         {
-          return;
-        }
-
-        size_t pos = target_.size();
-        target_.resize(pos + length);
-
-        if (length > 0)
-        {
-          memcpy(&target_[pos], buffer, length);
+          buffer_.AddChunk(reinterpret_cast<const char*>(buffer), length);
         }
       }
     };
@@ -225,6 +226,154 @@
   }
 
 
+  static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
+                                 const void* data,
+                                 size_t size)
+  {
+    target.size = size;
+
+    if (size == 0)
+    {
+      target.data = NULL;
+    }
+    else
+    {
+      target.data = malloc(size);
+      if (target.data != NULL)
+      {
+        memcpy(target.data, data, size);
+      }
+      else
+      {
+        throw OrthancException(ErrorCode_NotEnoughMemory);
+      }
+    }
+  }
+
+
+  static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
+                                 const std::string& str)
+  {
+    if (str.size() == 0)
+    {
+      target.size = 0;
+      target.data = NULL;
+    }
+    else
+    {
+      CopyToMemoryBuffer(target, str.c_str(), str.size());
+    }
+  }
+
+
+  void PluginsHttpHandler::RegisterRestCallback(const void* parameters)
+  {
+    const _OrthancPluginRestCallback& p = 
+      *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters);
+
+    LOG(INFO) << "Plugin has registered a REST callback on: " << p.pathRegularExpression;
+    pimpl_->callbacks_.push_back(std::make_pair(new boost::regex(p.pathRegularExpression), p.callback));
+  }
+
+
+
+  void PluginsHttpHandler::AnswerBuffer(const void* parameters)
+  {
+    const _OrthancPluginAnswerBuffer& p = 
+      *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters);
+
+    HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
+    translatedOutput->AnswerBufferWithContentType(p.answer, p.answerSize, p.mimeType);
+  }
+
+
+  void PluginsHttpHandler::CompressAndAnswerPngImage(const void* parameters)
+  {
+    const _OrthancPluginCompressAndAnswerPngImage& p = 
+      *reinterpret_cast<const _OrthancPluginCompressAndAnswerPngImage*>(parameters);
+
+    HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
+
+    PixelFormat format;
+    switch (p.format)
+    {
+      case OrthancPluginPixelFormat_Grayscale8:  
+        format = PixelFormat_Grayscale8;
+        break;
+
+      case OrthancPluginPixelFormat_Grayscale16:  
+        format = PixelFormat_Grayscale16;
+        break;
+
+      case OrthancPluginPixelFormat_SignedGrayscale16:  
+        format = PixelFormat_SignedGrayscale16;
+        break;
+
+      case OrthancPluginPixelFormat_RGB24:  
+        format = PixelFormat_RGB24;
+        break;
+
+      case OrthancPluginPixelFormat_RGBA32:  
+        format = PixelFormat_RGBA32;
+        break;
+
+      default:
+        throw OrthancException(ErrorCode_ParameterOutOfRange);
+    }
+
+    ImageAccessor accessor;
+    accessor.AssignReadOnly(format, p.width, p.height, p.pitch, p.buffer);
+
+    PngWriter writer;
+    std::string png;
+    writer.WriteToMemory(png, accessor);
+
+    translatedOutput->AnswerBufferWithContentType(png, "image/png");
+  }
+
+
+  void PluginsHttpHandler::GetDicomForInstance(const void* parameters)
+  {
+    const _OrthancPluginGetDicomForInstance& p = 
+      *reinterpret_cast<const _OrthancPluginGetDicomForInstance*>(parameters);
+
+    std::string dicom;
+    pimpl_->context_.ReadFile(dicom, p.instanceId, FileContentType_Dicom);
+    CopyToMemoryBuffer(*p.target, dicom);
+  }
+
+
+  void PluginsHttpHandler::RestApiGet(const void* parameters)
+  {
+    const _OrthancPluginRestApiGet& p = 
+      *reinterpret_cast<const _OrthancPluginRestApiGet*>(parameters);
+        
+    HttpHandler::Arguments headers;  // No HTTP header
+    std::string body;  // No body for a GET request
+
+    UriComponents uri;
+    HttpHandler::Arguments getArguments;
+    HttpHandler::ParseGetQuery(uri, getArguments, p.uri);
+
+    StringHttpOutput stream;
+    HttpOutput http(stream);
+
+    LOG(INFO) << "Plugin making REST call on URI " << p.uri;
+
+    if (pimpl_->restApi_ != NULL &&
+        pimpl_->restApi_->Handle(http, HttpMethod_Get, uri, headers, getArguments, body))
+    {
+      std::string result;
+      stream.GetOutput(result);
+      CopyToMemoryBuffer(*p.target, result);
+    }
+    else
+    {
+      throw OrthancException(ErrorCode_BadRequest);
+    }
+  }
+
+
   bool PluginsHttpHandler::InvokeService(_OrthancPluginService service,
                                          const void* parameters)
   {
@@ -232,99 +381,31 @@
     {
       case _OrthancPluginService_RegisterRestCallback:
       {
-        const _OrthancPluginRestCallback& p = 
-          *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters);
-
-        LOG(INFO) << "Plugin has registered a REST callback on: " << p.pathRegularExpression;
-        pimpl_->callbacks_.push_back(std::make_pair(new boost::regex(p.pathRegularExpression), p.callback));
-
+        RegisterRestCallback(parameters);
         return true;
       }
 
       case _OrthancPluginService_AnswerBuffer:
       {
-        const _OrthancPluginAnswerBuffer& p = 
-          *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters);
-
-        HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
-        translatedOutput->AnswerBufferWithContentType(p.answer, p.answerSize, p.mimeType);
-
+        AnswerBuffer(parameters);
         return true;
       }
 
       case _OrthancPluginService_CompressAndAnswerPngImage:
       {
-        const _OrthancPluginCompressAndAnswerPngImage& p = 
-          *reinterpret_cast<const _OrthancPluginCompressAndAnswerPngImage*>(parameters);
-
-        HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
-
-        PixelFormat format;
-        switch (p.format)
-        {
-          case OrthancPluginPixelFormat_Grayscale8:  
-            format = PixelFormat_Grayscale8;
-            break;
-
-          case OrthancPluginPixelFormat_Grayscale16:  
-            format = PixelFormat_Grayscale16;
-            break;
-
-          case OrthancPluginPixelFormat_SignedGrayscale16:  
-            format = PixelFormat_SignedGrayscale16;
-            break;
-
-          case OrthancPluginPixelFormat_RGB24:  
-            format = PixelFormat_RGB24;
-            break;
-
-          case OrthancPluginPixelFormat_RGBA32:  
-            format = PixelFormat_RGBA32;
-            break;
-
-          default:
-            throw OrthancException(ErrorCode_ParameterOutOfRange);
-        }
-
-        ImageAccessor accessor;
-        accessor.AssignReadOnly(format, p.width, p.height, p.pitch, p.buffer);
-
-        PngWriter writer;
-        std::string png;
-        writer.WriteToMemory(png, accessor);
-
-        translatedOutput->AnswerBufferWithContentType(png, "image/png");
-
+        CompressAndAnswerPngImage(parameters);
         return true;
       }
 
       case _OrthancPluginService_GetDicomForInstance:
       {
-        const _OrthancPluginGetDicomForInstance& p = 
-          *reinterpret_cast<const _OrthancPluginGetDicomForInstance*>(parameters);
-
-        std::string dicom;
-        pimpl_->context_.ReadFile(dicom, p.instanceId, FileContentType_Dicom);
-
-        p.target->size = dicom.size();
+        GetDicomForInstance(parameters);
+        return true;
+      }
 
-        if (dicom.size() == 0)
-        {
-          p.target->data = NULL;
-        }
-        else
-        {
-          p.target->data = malloc(dicom.size());
-          if (p.target->data != NULL)
-          {
-            memcpy(p.target->data, &dicom[0], dicom.size());
-          }
-          else
-          {
-            return false;
-          }
-        }
-
+      case _OrthancPluginService_RestApiGet:
+      {
+        RestApiGet(parameters);
         return true;
       }