comparison Plugins/Engine/OrthancPlugins.cpp @ 3387:a48d652f1500

new function OrthancPluginHttpClientChunkedBody(), new class OrthancPlugins::HttpClient
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 05 Jun 2019 17:17:48 +0200
parents f6374c36a671
children ad434967a68c
comparison
equal deleted inserted replaced
3386:af9432e46c07 3387:a48d652f1500
971 unsigned int size = params_.getMoveSize(driver); 971 unsigned int size = params_.getMoveSize(driver);
972 972
973 return new Driver(driver, size, params_.applyMove, params_.freeMove); 973 return new Driver(driver, size, params_.applyMove, params_.freeMove);
974 } 974 }
975 }; 975 };
976 976
977
978
979 class OrthancPlugins::ChunkedBody : public HttpClient::IChunkedBody
980 {
981 private:
982 const _OrthancPluginHttpClientChunkedBody& params_;
983 PluginsErrorDictionary& errorDictionary_;
984
985 public:
986 ChunkedBody(const _OrthancPluginHttpClientChunkedBody& params,
987 PluginsErrorDictionary& errorDictionary) :
988 params_(params),
989 errorDictionary_(errorDictionary)
990 {
991 }
992
993 virtual bool ReadNextChunk(std::string& chunk)
994 {
995 if (params_.bodyDone(params_.body))
996 {
997 return false;
998 }
999 else
1000 {
1001 size_t size = params_.bodyChunkSize(params_.body);
1002
1003 chunk.resize(size);
1004
1005 if (size != 0)
1006 {
1007 const void* data = params_.bodyChunkData(params_.body);
1008 memcpy(&chunk[0], data, size);
1009 }
1010
1011 OrthancPluginErrorCode error = params_.bodyNext(params_.body);
1012
1013 if (error != OrthancPluginErrorCode_Success)
1014 {
1015 errorDictionary_.LogError(error, true);
1016 throw OrthancException(static_cast<ErrorCode>(error));
1017 }
1018 else
1019 {
1020 return true;
1021 }
1022 }
1023 }
1024 };
977 1025
978 1026
979 OrthancPlugins::OrthancPlugins() 1027 OrthancPlugins::OrthancPlugins()
980 { 1028 {
981 /* Sanity check of the compiler */ 1029 /* Sanity check of the compiler */
2035 2083
2036 CopyToMemoryBuffer(*p.target, compressed.size() > 0 ? compressed.c_str() : NULL, compressed.size()); 2084 CopyToMemoryBuffer(*p.target, compressed.size() > 0 ? compressed.c_str() : NULL, compressed.size());
2037 } 2085 }
2038 2086
2039 2087
2040 void OrthancPlugins::CallHttpClient(const void* parameters) 2088 static void RunHttpClient(HttpClient& client,
2041 { 2089 const _OrthancPluginCallHttpClient2& parameters)
2042 const _OrthancPluginCallHttpClient& p = *reinterpret_cast<const _OrthancPluginCallHttpClient*>(parameters); 2090 {
2043 2091 client.SetUrl(parameters.url);
2044 HttpClient client; 2092 client.SetConvertHeadersToLowerCase(false);
2045 client.SetUrl(p.url); 2093
2046 2094 if (parameters.timeout != 0)
2047 if (p.username != NULL && 2095 {
2048 p.password != NULL) 2096 client.SetTimeout(parameters.timeout);
2049 { 2097 }
2050 client.SetCredentials(p.username, p.password); 2098
2051 } 2099 if (parameters.username != NULL &&
2052 2100 parameters.password != NULL)
2053 switch (p.method) 2101 {
2102 client.SetCredentials(parameters.username, parameters.password);
2103 }
2104
2105 if (parameters.certificateFile != NULL)
2106 {
2107 std::string certificate(parameters.certificateFile);
2108 std::string key, password;
2109
2110 if (parameters.certificateKeyFile)
2111 {
2112 key.assign(parameters.certificateKeyFile);
2113 }
2114
2115 if (parameters.certificateKeyPassword)
2116 {
2117 password.assign(parameters.certificateKeyPassword);
2118 }
2119
2120 client.SetClientCertificate(certificate, key, password);
2121 }
2122
2123 client.SetPkcs11Enabled(parameters.pkcs11 ? true : false);
2124
2125 for (uint32_t i = 0; i < parameters.headersCount; i++)
2126 {
2127 if (parameters.headersKeys[i] == NULL ||
2128 parameters.headersValues[i] == NULL)
2129 {
2130 throw OrthancException(ErrorCode_NullPointer);
2131 }
2132
2133 client.AddHeader(parameters.headersKeys[i], parameters.headersValues[i]);
2134 }
2135
2136 switch (parameters.method)
2054 { 2137 {
2055 case OrthancPluginHttpMethod_Get: 2138 case OrthancPluginHttpMethod_Get:
2056 client.SetMethod(HttpMethod_Get); 2139 client.SetMethod(HttpMethod_Get);
2057 break; 2140 break;
2058 2141
2059 case OrthancPluginHttpMethod_Post: 2142 case OrthancPluginHttpMethod_Post:
2060 client.SetMethod(HttpMethod_Post); 2143 client.SetMethod(HttpMethod_Post);
2061 client.GetBody().assign(p.body, p.bodySize);
2062 break; 2144 break;
2063 2145
2064 case OrthancPluginHttpMethod_Put: 2146 case OrthancPluginHttpMethod_Put:
2065 client.SetMethod(HttpMethod_Put); 2147 client.SetMethod(HttpMethod_Put);
2066 client.GetBody().assign(p.body, p.bodySize);
2067 break; 2148 break;
2068 2149
2069 case OrthancPluginHttpMethod_Delete: 2150 case OrthancPluginHttpMethod_Delete:
2070 client.SetMethod(HttpMethod_Delete); 2151 client.SetMethod(HttpMethod_Delete);
2071 break; 2152 break;
2072 2153
2073 default: 2154 default:
2074 throw OrthancException(ErrorCode_ParameterOutOfRange); 2155 throw OrthancException(ErrorCode_ParameterOutOfRange);
2075 } 2156 }
2076 2157
2077 std::string s;
2078 client.ApplyAndThrowException(s);
2079
2080 if (p.method != OrthancPluginHttpMethod_Delete)
2081 {
2082 CopyToMemoryBuffer(*p.target, s);
2083 }
2084 }
2085
2086
2087 void OrthancPlugins::CallHttpClient2(const void* parameters)
2088 {
2089 const _OrthancPluginCallHttpClient2& p = *reinterpret_cast<const _OrthancPluginCallHttpClient2*>(parameters);
2090
2091 HttpClient client;
2092 client.SetUrl(p.url);
2093 client.SetConvertHeadersToLowerCase(false);
2094
2095 if (p.timeout != 0)
2096 {
2097 client.SetTimeout(p.timeout);
2098 }
2099
2100 if (p.username != NULL &&
2101 p.password != NULL)
2102 {
2103 client.SetCredentials(p.username, p.password);
2104 }
2105
2106 if (p.certificateFile != NULL)
2107 {
2108 std::string certificate(p.certificateFile);
2109 std::string key, password;
2110
2111 if (p.certificateKeyFile)
2112 {
2113 key.assign(p.certificateKeyFile);
2114 }
2115
2116 if (p.certificateKeyPassword)
2117 {
2118 password.assign(p.certificateKeyPassword);
2119 }
2120
2121 client.SetClientCertificate(certificate, key, password);
2122 }
2123
2124 client.SetPkcs11Enabled(p.pkcs11 ? true : false);
2125
2126 for (uint32_t i = 0; i < p.headersCount; i++)
2127 {
2128 if (p.headersKeys[i] == NULL ||
2129 p.headersValues[i] == NULL)
2130 {
2131 throw OrthancException(ErrorCode_NullPointer);
2132 }
2133
2134 client.AddHeader(p.headersKeys[i], p.headersValues[i]);
2135 }
2136
2137 switch (p.method)
2138 {
2139 case OrthancPluginHttpMethod_Get:
2140 client.SetMethod(HttpMethod_Get);
2141 break;
2142
2143 case OrthancPluginHttpMethod_Post:
2144 client.SetMethod(HttpMethod_Post);
2145 client.GetBody().assign(p.body, p.bodySize);
2146 break;
2147
2148 case OrthancPluginHttpMethod_Put:
2149 client.SetMethod(HttpMethod_Put);
2150 client.GetBody().assign(p.body, p.bodySize);
2151 break;
2152
2153 case OrthancPluginHttpMethod_Delete:
2154 client.SetMethod(HttpMethod_Delete);
2155 break;
2156
2157 default:
2158 throw OrthancException(ErrorCode_ParameterOutOfRange);
2159 }
2160
2161 std::string body; 2158 std::string body;
2162 HttpClient::HttpHeaders headers; 2159 HttpClient::HttpHeaders headers;
2163 2160
2164 bool success = client.Apply(body, headers); 2161 bool success = client.Apply(body, headers);
2165 2162
2166 // The HTTP request has succeeded 2163 // The HTTP request has succeeded
2167 *p.httpStatus = static_cast<uint16_t>(client.GetLastStatus()); 2164 *parameters.httpStatus = static_cast<uint16_t>(client.GetLastStatus());
2168 2165
2169 if (!success) 2166 if (!success)
2170 { 2167 {
2171 HttpClient::ThrowException(client.GetLastStatus()); 2168 HttpClient::ThrowException(client.GetLastStatus());
2172 } 2169 }
2173 2170
2174 // Copy the HTTP headers of the answer, if the plugin requested them 2171 // Copy the HTTP headers of the answer, if the plugin requested them
2175 if (p.answerHeaders != NULL) 2172 if (parameters.answerHeaders != NULL)
2176 { 2173 {
2177 Json::Value json = Json::objectValue; 2174 Json::Value json = Json::objectValue;
2178 2175
2179 for (HttpClient::HttpHeaders::const_iterator 2176 for (HttpClient::HttpHeaders::const_iterator
2180 it = headers.begin(); it != headers.end(); ++it) 2177 it = headers.begin(); it != headers.end(); ++it)
2181 { 2178 {
2182 json[it->first] = it->second; 2179 json[it->first] = it->second;
2183 } 2180 }
2184 2181
2185 std::string s = json.toStyledString(); 2182 std::string s = json.toStyledString();
2186 CopyToMemoryBuffer(*p.answerHeaders, s); 2183 CopyToMemoryBuffer(*parameters.answerHeaders, s);
2187 } 2184 }
2188 2185
2189 // Copy the body of the answer if it makes sense 2186 // Copy the body of the answer if it makes sense
2190 if (p.method != OrthancPluginHttpMethod_Delete) 2187 if (parameters.method != OrthancPluginHttpMethod_Delete)
2191 { 2188 {
2192 CopyToMemoryBuffer(*p.answerBody, body); 2189 CopyToMemoryBuffer(*parameters.answerBody, body);
2193 } 2190 }
2191 }
2192
2193
2194 void OrthancPlugins::CallHttpClient(const void* parameters)
2195 {
2196 const _OrthancPluginCallHttpClient& p = *reinterpret_cast<const _OrthancPluginCallHttpClient*>(parameters);
2197
2198 _OrthancPluginCallHttpClient2 converted;
2199 memset(&converted, 0, sizeof(converted));
2200
2201 uint16_t httpStatus;
2202
2203 converted.answerBody = p.target;
2204 converted.answerHeaders = NULL;
2205 converted.httpStatus = &httpStatus;
2206 converted.method = p.method;
2207 converted.url = p.url;
2208 converted.headersCount = 0;
2209 converted.headersKeys = NULL;
2210 converted.headersValues = NULL;
2211 converted.body = p.body;
2212 converted.bodySize = p.bodySize;
2213 converted.username = p.username;
2214 converted.password = p.password;
2215 converted.timeout = 0; // Use default timeout
2216 converted.certificateFile = NULL;
2217 converted.certificateKeyFile = NULL;
2218 converted.certificateKeyPassword = NULL;
2219 converted.pkcs11 = false;
2220
2221 HttpClient client;
2222 RunHttpClient(client, converted);
2223 }
2224
2225
2226 void OrthancPlugins::CallHttpClient2(const void* parameters)
2227 {
2228 const _OrthancPluginCallHttpClient2& p = *reinterpret_cast<const _OrthancPluginCallHttpClient2*>(parameters);
2229
2230 HttpClient client;
2231
2232 if (p.method == OrthancPluginHttpMethod_Post ||
2233 p.method == OrthancPluginHttpMethod_Put)
2234 {
2235 client.GetBody().assign(p.body, p.bodySize);
2236 }
2237
2238 RunHttpClient(client, p);
2239 }
2240
2241
2242 void OrthancPlugins::HttpClientChunkedBody(const void* parameters)
2243 {
2244 const _OrthancPluginHttpClientChunkedBody& p =
2245 *reinterpret_cast<const _OrthancPluginHttpClientChunkedBody*>(parameters);
2246
2247 if (p.method != OrthancPluginHttpMethod_Post &&
2248 p.method != OrthancPluginHttpMethod_Put)
2249 {
2250 throw OrthancException(ErrorCode_ParameterOutOfRange,
2251 "This plugin service is only allowed for PUT and POST HTTP requests");
2252 }
2253
2254 ChunkedBody body(p, pimpl_->dictionary_);
2255
2256 HttpClient client;
2257 client.SetBody(body);
2258
2259 _OrthancPluginCallHttpClient2 converted;
2260 memset(&converted, 0, sizeof(converted));
2261
2262 converted.answerBody = p.answerBody;
2263 converted.answerHeaders = p.answerHeaders;
2264 converted.httpStatus = p.httpStatus;
2265 converted.method = p.method;
2266 converted.url = p.url;
2267 converted.headersCount = p.headersCount;
2268 converted.headersKeys = p.headersKeys;
2269 converted.headersValues = p.headersValues;
2270 converted.body = NULL;
2271 converted.bodySize = 0;
2272 converted.username = p.username;
2273 converted.password = p.password;
2274 converted.timeout = p.timeout;
2275 converted.certificateFile = p.certificateFile;
2276 converted.certificateKeyFile = p.certificateKeyFile;
2277 converted.certificateKeyPassword = p.certificateKeyPassword;
2278 converted.pkcs11 = p.pkcs11;
2279
2280 RunHttpClient(client, converted);
2194 } 2281 }
2195 2282
2196 2283
2197 void OrthancPlugins::CallPeerApi(const void* parameters) 2284 void OrthancPlugins::CallPeerApi(const void* parameters)
2198 { 2285 {
2870 2957
2871 case _OrthancPluginService_CallHttpClient2: 2958 case _OrthancPluginService_CallHttpClient2:
2872 CallHttpClient2(parameters); 2959 CallHttpClient2(parameters);
2873 return true; 2960 return true;
2874 2961
2962 case _OrthancPluginService_HttpClientChunkedBody:
2963 HttpClientChunkedBody(parameters);
2964 return true;
2965
2875 case _OrthancPluginService_ConvertPixelFormat: 2966 case _OrthancPluginService_ConvertPixelFormat:
2876 ConvertPixelFormat(parameters); 2967 ConvertPixelFormat(parameters);
2877 return true; 2968 return true;
2878 2969
2879 case _OrthancPluginService_GetFontsCount: 2970 case _OrthancPluginService_GetFontsCount: