Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkRESTClient.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include <mitkExceptionMacro.h>
14 #include <mitkRESTClient.h>
15 #include <mitkRESTUtil.h>
16 
17 #include <cpprest/filestream.h>
18 #include <cpprest/http_client.h>
19 
25 using file_buffer = concurrency::streams::file_buffer<uint8_t>;
26 using streambuf = concurrency::streams::streambuf<uint8_t>;
27 
29 {
30  m_ClientConfig.set_validate_certificates(false);
31 }
32 
34 
35 void mitk::RESTClient::CheckResponseContentType(web::http::http_response &response)
36 {
37  auto status = response.status_code();
38 
39  if (status_codes::OK != status)
40  {
41  MITK_WARN << "Status: " << status;
42  MITK_WARN << "Response: " << mitk::RESTUtil::convertToUtf8(response.to_string());
43  mitkThrow() << mitk::RESTUtil::convertToUtf8(response.to_string());
44  }
45 
46  auto requestContentType = response.headers().content_type();
47  MITK_DEBUG << "Content Type: " << mitk::RESTUtil::convertToUtf8(requestContentType);
48  MITK_DEBUG << "Body: " << mitk::RESTUtil::convertToUtf8(response.to_string());
49  if (requestContentType.find(U("json")) != std::wstring::npos)
50  {
51  MITK_DEBUG << "Caution! The given response content type was '" << mitk::RESTUtil::convertToUtf8(requestContentType)
52  << "' but contains 'json'. So we awesome the answer actually contains a JSON message.";
53  response.headers().set_content_type(U("application/json"));
54  }
55 }
56 
57 pplx::task<web::json::value> mitk::RESTClient::Get(const web::uri &uri,
58  const std::map<utility::string_t, utility::string_t> headers)
59 {
60  auto client = new http_client(uri, m_ClientConfig);
61  http_request request;
62 
63  for (auto param : headers)
64  {
65  request.headers().add(param.first, param.second);
66  }
67 
68  return client->request(request).then([=](pplx::task<web::http::http_response> responseTask) {
69  try
70  {
71  auto response = responseTask.get();
72 
73  CheckResponseContentType(response);
74 
75  return response.extract_json().get();
76  }
77  catch (const std::exception &e)
78  {
79  MITK_INFO << e.what();
80  mitkThrow() << "Getting response went wrong: " << e.what();
81  }
82  });
83 }
84 
85 pplx::task<web::json::value> mitk::RESTClient::Get(const web::uri &uri,
86  const utility::string_t &filePath,
87  const std::map<utility::string_t, utility::string_t> headers)
88 {
89  auto client = new http_client(uri, m_ClientConfig);
90  auto fileBuffer = std::make_shared<concurrency::streams::streambuf<uint8_t>>();
91  http_request request;
92 
93  for (auto param : headers)
94  {
95  request.headers().add(param.first, param.second);
96  }
97 
98  // Open file stream for the specified file path
99  return file_buffer::open(filePath, std::ios::out)
100  .then([=](streambuf outFile) -> pplx::task<http_response> {
101  *fileBuffer = outFile;
102  return client->request(methods::GET);
103  })
104  // Write the response body into the file buffer
105  .then([=](http_response response) -> pplx::task<size_t> {
106  auto status = response.status_code();
107 
108  if (status_codes::OK != status)
109  {
110  MITK_INFO << status;
111  MITK_INFO << mitk::RESTUtil::convertToUtf8(response.to_string());
112  mitkThrow() << mitk::RESTUtil::convertToUtf8(response.to_string());
113  }
114 
115  return response.body().read_to_end(*fileBuffer);
116  })
117  // Close the file buffer
118  .then([=](size_t) { return fileBuffer->close(); })
119  // Return empty JSON object
120  .then([=]() { return web::json::value(); });
121 }
122 
123 pplx::task<web::json::value> mitk::RESTClient::Put(const web::uri &uri, const web::json::value *content)
124 {
125  auto client = new http_client(uri, m_ClientConfig);
126  http_request request(methods::PUT);
127 
128  if (nullptr != content)
129  request.set_body(*content);
130 
131  return client->request(request).then([=](pplx::task<http_response> responseTask) {
132  try
133  {
134  auto response = responseTask.get();
135 
136  CheckResponseContentType(response);
137 
138  return response.extract_json().get();
139  }
140  catch (std::exception &e)
141  {
142  MITK_INFO << e.what();
143  mitkThrow() << "Getting response went wrong";
144  }
145  });
146 }
147 
148 pplx::task<web::json::value> mitk::RESTClient::Post(const web::uri &uri,
149  const std::vector<unsigned char> *content,
150  const std::map<utility::string_t, utility::string_t> headers)
151 {
152  auto request = InitRequest(headers);
153  request.set_method(methods::POST);
154 
155  if (nullptr != content)
156  request.set_body(*content);
157 
158  return ExecutePost(uri, request);
159 }
160 
161 pplx::task<web::json::value> mitk::RESTClient::Post(const web::uri &uri,
162  const web::json::value *content,
163  const std::map<utility::string_t, utility::string_t> headers)
164 {
165  auto request = InitRequest(headers);
166  request.set_method(methods::POST);
167 
168  if (nullptr != content)
169  request.set_body(*content);
170 
171  return ExecutePost(uri, request);
172 }
173 
174 http_request mitk::RESTClient::InitRequest(const std::map<utility::string_t, utility::string_t> headers)
175 {
176  http_request request;
177 
178  for (auto param : headers)
179  {
180  request.headers().add(param.first, param.second);
181  }
182  return request;
183 }
184 
185 pplx::task<web::json::value> mitk::RESTClient::ExecutePost(const web::uri &uri, http_request request)
186 {
187  auto client = new http_client(uri, m_ClientConfig);
188  return client->request(request).then([=](pplx::task<http_response> responseTask) {
189  try
190  {
191  auto response = responseTask.get();
192 
193  CheckResponseContentType(response);
194 
195  return response.extract_json().get();
196  }
197  catch (std::exception &e)
198  {
199  MITK_INFO << e.what();
200  mitkThrow() << "Getting response went wrong";
201  }
202  });
203 }
#define MITK_INFO
Definition: mitkLogMacros.h:18
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
web::http::http_request http_request
web::http::methods methods
pplx::task< web::json::value > Put(const web::uri &uri, const web::json::value *content)
Executes a HTTP PUT request with given uri and the content given as json.
concurrency::streams::file_buffer< uint8_t > file_buffer
#define OK
#define MITK_WARN
Definition: mitkLogMacros.h:19
pplx::task< web::json::value > Get(const web::uri &uri, const std::map< utility::string_t, utility::string_t > headers)
Executes a HTTP GET request with the given uri and returns a task waiting for a json object...
web::http::client::http_client http_client
#define mitkThrow()
web::http::http_response http_response
static std::string convertToUtf8(const utility::string_t &string)
Converts the given std::wstring into a std::string representation.
Definition: mitkRESTUtil.h:32
web::http::http_request http_request
web::http::status_codes status_codes
pplx::task< web::json::value > Post(const web::uri &uri, const web::json::value *content, const std::map< utility::string_t, utility::string_t > headers)
Executes a HTTP POST request with given uri and the content given as json.
concurrency::streams::streambuf< uint8_t > streambuf