Mercurial > hg > orthanc-authorization
comparison Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp @ 69:af44dce56328
new 'auth/user-profile' Rest API route
author | Alain Mazy <am@osimis.io> |
---|---|
date | Mon, 20 Feb 2023 11:56:14 +0100 |
parents | 1a13c4fbc9a1 |
children | 30fb3ce960d9 |
comparison
equal
deleted
inserted
replaced
68:1a13c4fbc9a1 | 69:af44dce56328 |
---|---|
1 /** | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | 2 * Orthanc - A Lightweight, RESTful DICOM Store |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | 3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
4 * Department, University Hospital of Liege, Belgium | 4 * Department, University Hospital of Liege, Belgium |
5 * Copyright (C) 2017-2023 Osimis S.A., Belgium | 5 * Copyright (C) 2017-2022 Osimis S.A., Belgium |
6 * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium | |
6 * | 7 * |
7 * This program is free software: you can redistribute it and/or | 8 * This program is free software: you can redistribute it and/or |
8 * modify it under the terms of the GNU General Public License as | 9 * modify it under the terms of the GNU General Public License as |
9 * published by the Free Software Foundation, either version 3 of the | 10 * published by the Free Software Foundation, either version 3 of the |
10 * License, or (at your option) any later version. | 11 * License, or (at your option) any later version. |
247 { | 248 { |
248 return CheckHttp(OrthancPluginRestApiGet(GetGlobalContext(), &buffer_, uri.c_str())); | 249 return CheckHttp(OrthancPluginRestApiGet(GetGlobalContext(), &buffer_, uri.c_str())); |
249 } | 250 } |
250 } | 251 } |
251 | 252 |
253 // helper class to convert std::map of headers to the plugin SDK C structure | |
254 class PluginHttpHeaders | |
255 { | |
256 std::vector<const char*> headersKeys_; | |
257 std::vector<const char*> headersValues_; | |
258 public: | |
259 | |
260 PluginHttpHeaders(const std::map<std::string, std::string>& httpHeaders) | |
261 { | |
262 for (std::map<std::string, std::string>::const_iterator | |
263 it = httpHeaders.begin(); it != httpHeaders.end(); it++) | |
264 { | |
265 headersKeys_.push_back(it->first.c_str()); | |
266 headersValues_.push_back(it->second.c_str()); | |
267 } | |
268 } | |
269 | |
270 const char* const* GetKeys() | |
271 { | |
272 return (headersKeys_.empty() ? NULL : &headersKeys_[0]); | |
273 } | |
274 | |
275 const char* const* GetValues() | |
276 { | |
277 return (headersValues_.empty() ? NULL : &headersValues_[0]); | |
278 } | |
279 | |
280 uint32_t GetSize() | |
281 { | |
282 return static_cast<uint32_t>(headersKeys_.size()); | |
283 } | |
284 }; | |
285 | |
252 bool MemoryBuffer::RestApiGet(const std::string& uri, | 286 bool MemoryBuffer::RestApiGet(const std::string& uri, |
253 const std::map<std::string, std::string>& httpHeaders, | 287 const std::map<std::string, std::string>& httpHeaders, |
254 bool applyPlugins) | 288 bool applyPlugins) |
255 { | 289 { |
256 Clear(); | 290 Clear(); |
257 | 291 |
258 std::vector<const char*> headersKeys; | 292 PluginHttpHeaders headers(httpHeaders); |
259 std::vector<const char*> headersValues; | |
260 | |
261 for (std::map<std::string, std::string>::const_iterator | |
262 it = httpHeaders.begin(); it != httpHeaders.end(); it++) | |
263 { | |
264 headersKeys.push_back(it->first.c_str()); | |
265 headersValues.push_back(it->second.c_str()); | |
266 } | |
267 | 293 |
268 return CheckHttp(OrthancPluginRestApiGet2( | 294 return CheckHttp(OrthancPluginRestApiGet2( |
269 GetGlobalContext(), &buffer_, uri.c_str(), httpHeaders.size(), | 295 GetGlobalContext(), &buffer_, uri.c_str(), |
270 (headersKeys.empty() ? NULL : &headersKeys[0]), | 296 headers.GetSize(), |
271 (headersValues.empty() ? NULL : &headersValues[0]), applyPlugins)); | 297 headers.GetKeys(), |
298 headers.GetValues(), applyPlugins)); | |
272 } | 299 } |
273 | 300 |
274 bool MemoryBuffer::RestApiPost(const std::string& uri, | 301 bool MemoryBuffer::RestApiPost(const std::string& uri, |
275 const void* body, | 302 const void* body, |
276 size_t bodySize, | 303 size_t bodySize, |
289 { | 316 { |
290 return CheckHttp(OrthancPluginRestApiPost(GetGlobalContext(), &buffer_, uri.c_str(), b, bodySize)); | 317 return CheckHttp(OrthancPluginRestApiPost(GetGlobalContext(), &buffer_, uri.c_str(), b, bodySize)); |
291 } | 318 } |
292 } | 319 } |
293 | 320 |
321 #if HAS_ORTHANC_PLUGIN_GENERIC_CALL_REST_API == 1 | |
322 | |
323 bool MemoryBuffer::RestApiPost(const std::string& uri, | |
324 const void* body, | |
325 size_t bodySize, | |
326 const std::map<std::string, std::string>& httpHeaders, | |
327 bool applyPlugins) | |
328 { | |
329 MemoryBuffer answerHeaders; | |
330 uint16_t httpStatus; | |
331 | |
332 PluginHttpHeaders headers(httpHeaders); | |
333 | |
334 return CheckHttp(OrthancPluginCallRestApi(GetGlobalContext(), | |
335 &buffer_, | |
336 *answerHeaders, | |
337 &httpStatus, | |
338 OrthancPluginHttpMethod_Post, | |
339 uri.c_str(), | |
340 headers.GetSize(), headers.GetKeys(), headers.GetValues(), | |
341 body, bodySize, | |
342 applyPlugins)); | |
343 } | |
344 | |
345 | |
346 bool MemoryBuffer::RestApiPost(const std::string& uri, | |
347 const Json::Value& body, | |
348 const std::map<std::string, std::string>& httpHeaders, | |
349 bool applyPlugins) | |
350 { | |
351 std::string s; | |
352 WriteFastJson(s, body); | |
353 return RestApiPost(uri, s.c_str(), s.size(), httpHeaders, applyPlugins); | |
354 } | |
355 #endif | |
294 | 356 |
295 bool MemoryBuffer::RestApiPut(const std::string& uri, | 357 bool MemoryBuffer::RestApiPut(const std::string& uri, |
296 const void* body, | 358 const void* body, |
297 size_t bodySize, | 359 size_t bodySize, |
298 bool applyPlugins) | 360 bool applyPlugins) |
508 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | 570 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); |
509 } | 571 } |
510 } | 572 } |
511 | 573 |
512 | 574 |
575 void OrthancString::ToJsonWithoutComments(Json::Value& target) const | |
576 { | |
577 if (str_ == NULL) | |
578 { | |
579 LogError("Cannot convert an empty memory buffer to JSON"); | |
580 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
581 } | |
582 | |
583 if (!ReadJsonWithoutComments(target, str_)) | |
584 { | |
585 LogError("Cannot convert some memory buffer to JSON"); | |
586 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); | |
587 } | |
588 } | |
589 | |
590 | |
513 void MemoryBuffer::DicomToJson(Json::Value& target, | 591 void MemoryBuffer::DicomToJson(Json::Value& target, |
514 OrthancPluginDicomToJsonFormat format, | 592 OrthancPluginDicomToJsonFormat format, |
515 OrthancPluginDicomToJsonFlags flags, | 593 OrthancPluginDicomToJsonFlags flags, |
516 uint32_t maxStringLength) | 594 uint32_t maxStringLength) |
517 { | 595 { |
537 const std::string& body, | 615 const std::string& body, |
538 const std::string& username, | 616 const std::string& username, |
539 const std::string& password) | 617 const std::string& password) |
540 { | 618 { |
541 Clear(); | 619 Clear(); |
620 | |
621 if (body.size() > 0xffffffffu) | |
622 { | |
623 LogError("Cannot handle body size > 4GB"); | |
624 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
625 } | |
626 | |
542 return CheckHttp(OrthancPluginHttpPost(GetGlobalContext(), &buffer_, url.c_str(), | 627 return CheckHttp(OrthancPluginHttpPost(GetGlobalContext(), &buffer_, url.c_str(), |
543 body.c_str(), body.size(), | 628 body.c_str(), body.size(), |
544 username.empty() ? NULL : username.c_str(), | 629 username.empty() ? NULL : username.c_str(), |
545 password.empty() ? NULL : password.c_str())); | 630 password.empty() ? NULL : password.c_str())); |
546 } | 631 } |
550 const std::string& body, | 635 const std::string& body, |
551 const std::string& username, | 636 const std::string& username, |
552 const std::string& password) | 637 const std::string& password) |
553 { | 638 { |
554 Clear(); | 639 Clear(); |
640 | |
641 if (body.size() > 0xffffffffu) | |
642 { | |
643 LogError("Cannot handle body size > 4GB"); | |
644 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
645 } | |
646 | |
555 return CheckHttp(OrthancPluginHttpPut(GetGlobalContext(), &buffer_, url.c_str(), | 647 return CheckHttp(OrthancPluginHttpPut(GetGlobalContext(), &buffer_, url.c_str(), |
556 body.empty() ? NULL : body.c_str(), | 648 body.empty() ? NULL : body.c_str(), |
557 body.size(), | 649 body.size(), |
558 username.empty() ? NULL : username.c_str(), | 650 username.empty() ? NULL : username.c_str(), |
559 password.empty() ? NULL : password.c_str())); | 651 password.empty() ? NULL : password.c_str())); |
628 { | 720 { |
629 LogError("Cannot access the Orthanc configuration"); | 721 LogError("Cannot access the Orthanc configuration"); |
630 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | 722 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); |
631 } | 723 } |
632 | 724 |
633 str.ToJson(configuration_); | 725 str.ToJsonWithoutComments(configuration_); |
634 | 726 |
635 if (configuration_.type() != Json::objectValue) | 727 if (configuration_.type() != Json::objectValue) |
636 { | 728 { |
637 LogError("Unable to read the Orthanc configuration"); | 729 LogError("Unable to read the Orthanc configuration"); |
638 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | 730 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); |
1424 } | 1516 } |
1425 return true; | 1517 return true; |
1426 } | 1518 } |
1427 } | 1519 } |
1428 | 1520 |
1521 #if HAS_ORTHANC_PLUGIN_GENERIC_CALL_REST_API == 1 | |
1522 bool RestApiPost(Json::Value& result, | |
1523 const std::string& uri, | |
1524 const Json::Value& body, | |
1525 const std::map<std::string, std::string>& httpHeaders, | |
1526 bool applyPlugins) | |
1527 { | |
1528 MemoryBuffer answer; | |
1529 | |
1530 if (!answer.RestApiPost(uri, body, httpHeaders, applyPlugins)) | |
1531 { | |
1532 return false; | |
1533 } | |
1534 else | |
1535 { | |
1536 if (!answer.IsEmpty()) | |
1537 { | |
1538 answer.ToJson(result); | |
1539 } | |
1540 return true; | |
1541 } | |
1542 } | |
1543 #endif | |
1544 | |
1429 | 1545 |
1430 bool RestApiPost(Json::Value& result, | 1546 bool RestApiPost(Json::Value& result, |
1431 const std::string& uri, | 1547 const std::string& uri, |
1432 const Json::Value& body, | 1548 const Json::Value& body, |
1433 bool applyPlugins) | 1549 bool applyPlugins) |
1513 boost::lexical_cast<std::string>(minor) + "." + | 1629 boost::lexical_cast<std::string>(minor) + "." + |
1514 boost::lexical_cast<std::string>(revision) + | 1630 boost::lexical_cast<std::string>(revision) + |
1515 " is required)"); | 1631 " is required)"); |
1516 } | 1632 } |
1517 | 1633 |
1518 | 1634 bool CheckMinimalVersion(const char* version, |
1519 bool CheckMinimalOrthancVersion(unsigned int major, | 1635 unsigned int major, |
1520 unsigned int minor, | 1636 unsigned int minor, |
1521 unsigned int revision) | 1637 unsigned int revision) |
1522 { | 1638 { |
1523 if (!HasGlobalContext()) | 1639 if (!strcmp(version, "mainline")) |
1524 { | |
1525 LogError("Bad Orthanc context in the plugin"); | |
1526 return false; | |
1527 } | |
1528 | |
1529 if (!strcmp(GetGlobalContext()->orthancVersion, "mainline")) | |
1530 { | 1640 { |
1531 // Assume compatibility with the mainline | 1641 // Assume compatibility with the mainline |
1532 return true; | 1642 return true; |
1533 } | 1643 } |
1534 | 1644 |
1535 // Parse the version of the Orthanc core | 1645 // Parse the version |
1536 int aa, bb, cc; | 1646 int aa, bb, cc; |
1537 if ( | 1647 if ( |
1538 #ifdef _MSC_VER | 1648 #ifdef _MSC_VER |
1539 sscanf_s | 1649 sscanf_s |
1540 #else | 1650 #else |
1541 sscanf | 1651 sscanf |
1542 #endif | 1652 #endif |
1543 (GetGlobalContext()->orthancVersion, "%4d.%4d.%4d", &aa, &bb, &cc) != 3 || | 1653 (version, "%4d.%4d.%4d", &aa, &bb, &cc) != 3 || |
1544 aa < 0 || | 1654 aa < 0 || |
1545 bb < 0 || | 1655 bb < 0 || |
1546 cc < 0) | 1656 cc < 0) |
1547 { | 1657 { |
1548 return false; | 1658 return false; |
1562 if (a < major) | 1672 if (a < major) |
1563 { | 1673 { |
1564 return false; | 1674 return false; |
1565 } | 1675 } |
1566 | 1676 |
1567 | |
1568 // Check the minor version number | 1677 // Check the minor version number |
1569 assert(a == major); | 1678 assert(a == major); |
1570 | 1679 |
1571 if (b > minor) | 1680 if (b > minor) |
1572 { | 1681 { |
1587 } | 1696 } |
1588 else | 1697 else |
1589 { | 1698 { |
1590 return false; | 1699 return false; |
1591 } | 1700 } |
1701 } | |
1702 | |
1703 | |
1704 bool CheckMinimalOrthancVersion(unsigned int major, | |
1705 unsigned int minor, | |
1706 unsigned int revision) | |
1707 { | |
1708 if (!HasGlobalContext()) | |
1709 { | |
1710 LogError("Bad Orthanc context in the plugin"); | |
1711 return false; | |
1712 } | |
1713 | |
1714 return CheckMinimalVersion(GetGlobalContext()->orthancVersion, | |
1715 major, minor, revision); | |
1592 } | 1716 } |
1593 | 1717 |
1594 | 1718 |
1595 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 0) | 1719 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 0) |
1596 const char* AutodetectMimeType(const std::string& path) | 1720 const char* AutodetectMimeType(const std::string& path) |
1759 } | 1883 } |
1760 | 1884 |
1761 | 1885 |
1762 bool OrthancPeers::DoGet(MemoryBuffer& target, | 1886 bool OrthancPeers::DoGet(MemoryBuffer& target, |
1763 size_t index, | 1887 size_t index, |
1764 const std::string& uri) const | 1888 const std::string& uri, |
1889 const std::map<std::string, std::string>& headers) const | |
1765 { | 1890 { |
1766 if (index >= index_.size()) | 1891 if (index >= index_.size()) |
1767 { | 1892 { |
1768 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | 1893 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); |
1769 } | 1894 } |
1770 | 1895 |
1771 OrthancPlugins::MemoryBuffer answer; | 1896 OrthancPlugins::MemoryBuffer answer; |
1772 uint16_t status; | 1897 uint16_t status; |
1898 PluginHttpHeaders pluginHeaders(headers); | |
1899 | |
1773 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | 1900 OrthancPluginErrorCode code = OrthancPluginCallPeerApi |
1774 (GetGlobalContext(), *answer, NULL, &status, peers_, | 1901 (GetGlobalContext(), *answer, NULL, &status, peers_, |
1775 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Get, uri.c_str(), | 1902 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Get, uri.c_str(), |
1776 0, NULL, NULL, NULL, 0, timeout_); | 1903 pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), NULL, 0, timeout_); |
1777 | 1904 |
1778 if (code == OrthancPluginErrorCode_Success) | 1905 if (code == OrthancPluginErrorCode_Success) |
1779 { | 1906 { |
1780 target.Swap(answer); | 1907 target.Swap(answer); |
1781 return (status == 200); | 1908 return (status == 200); |
1787 } | 1914 } |
1788 | 1915 |
1789 | 1916 |
1790 bool OrthancPeers::DoGet(MemoryBuffer& target, | 1917 bool OrthancPeers::DoGet(MemoryBuffer& target, |
1791 const std::string& name, | 1918 const std::string& name, |
1792 const std::string& uri) const | 1919 const std::string& uri, |
1920 const std::map<std::string, std::string>& headers) const | |
1793 { | 1921 { |
1794 size_t index; | 1922 size_t index; |
1795 return (LookupName(index, name) && | 1923 return (LookupName(index, name) && |
1796 DoGet(target, index, uri)); | 1924 DoGet(target, index, uri, headers)); |
1797 } | 1925 } |
1798 | 1926 |
1799 | 1927 |
1800 bool OrthancPeers::DoGet(Json::Value& target, | 1928 bool OrthancPeers::DoGet(Json::Value& target, |
1801 size_t index, | 1929 size_t index, |
1802 const std::string& uri) const | 1930 const std::string& uri, |
1931 const std::map<std::string, std::string>& headers) const | |
1803 { | 1932 { |
1804 MemoryBuffer buffer; | 1933 MemoryBuffer buffer; |
1805 | 1934 |
1806 if (DoGet(buffer, index, uri)) | 1935 if (DoGet(buffer, index, uri, headers)) |
1807 { | 1936 { |
1808 buffer.ToJson(target); | 1937 buffer.ToJson(target); |
1809 return true; | 1938 return true; |
1810 } | 1939 } |
1811 else | 1940 else |
1815 } | 1944 } |
1816 | 1945 |
1817 | 1946 |
1818 bool OrthancPeers::DoGet(Json::Value& target, | 1947 bool OrthancPeers::DoGet(Json::Value& target, |
1819 const std::string& name, | 1948 const std::string& name, |
1820 const std::string& uri) const | 1949 const std::string& uri, |
1950 const std::map<std::string, std::string>& headers) const | |
1821 { | 1951 { |
1822 MemoryBuffer buffer; | 1952 MemoryBuffer buffer; |
1823 | 1953 |
1824 if (DoGet(buffer, name, uri)) | 1954 if (DoGet(buffer, name, uri, headers)) |
1825 { | 1955 { |
1826 buffer.ToJson(target); | 1956 buffer.ToJson(target); |
1827 return true; | 1957 return true; |
1828 } | 1958 } |
1829 else | 1959 else |
1834 | 1964 |
1835 | 1965 |
1836 bool OrthancPeers::DoPost(MemoryBuffer& target, | 1966 bool OrthancPeers::DoPost(MemoryBuffer& target, |
1837 const std::string& name, | 1967 const std::string& name, |
1838 const std::string& uri, | 1968 const std::string& uri, |
1839 const std::string& body) const | 1969 const std::string& body, |
1970 const std::map<std::string, std::string>& headers) const | |
1840 { | 1971 { |
1841 size_t index; | 1972 size_t index; |
1842 return (LookupName(index, name) && | 1973 return (LookupName(index, name) && |
1843 DoPost(target, index, uri, body)); | 1974 DoPost(target, index, uri, body, headers)); |
1844 } | 1975 } |
1845 | 1976 |
1846 | 1977 |
1847 bool OrthancPeers::DoPost(Json::Value& target, | 1978 bool OrthancPeers::DoPost(Json::Value& target, |
1848 size_t index, | 1979 size_t index, |
1849 const std::string& uri, | 1980 const std::string& uri, |
1850 const std::string& body) const | 1981 const std::string& body, |
1982 const std::map<std::string, std::string>& headers) const | |
1851 { | 1983 { |
1852 MemoryBuffer buffer; | 1984 MemoryBuffer buffer; |
1853 | 1985 |
1854 if (DoPost(buffer, index, uri, body)) | 1986 if (DoPost(buffer, index, uri, body, headers)) |
1855 { | 1987 { |
1856 buffer.ToJson(target); | 1988 buffer.ToJson(target); |
1857 return true; | 1989 return true; |
1858 } | 1990 } |
1859 else | 1991 else |
1864 | 1996 |
1865 | 1997 |
1866 bool OrthancPeers::DoPost(Json::Value& target, | 1998 bool OrthancPeers::DoPost(Json::Value& target, |
1867 const std::string& name, | 1999 const std::string& name, |
1868 const std::string& uri, | 2000 const std::string& uri, |
1869 const std::string& body) const | 2001 const std::string& body, |
2002 const std::map<std::string, std::string>& headers) const | |
1870 { | 2003 { |
1871 MemoryBuffer buffer; | 2004 MemoryBuffer buffer; |
1872 | 2005 |
1873 if (DoPost(buffer, name, uri, body)) | 2006 if (DoPost(buffer, name, uri, body, headers)) |
1874 { | 2007 { |
1875 buffer.ToJson(target); | 2008 buffer.ToJson(target); |
1876 return true; | 2009 return true; |
1877 } | 2010 } |
1878 else | 2011 else |
1883 | 2016 |
1884 | 2017 |
1885 bool OrthancPeers::DoPost(MemoryBuffer& target, | 2018 bool OrthancPeers::DoPost(MemoryBuffer& target, |
1886 size_t index, | 2019 size_t index, |
1887 const std::string& uri, | 2020 const std::string& uri, |
1888 const std::string& body) const | 2021 const std::string& body, |
2022 const std::map<std::string, std::string>& headers) const | |
1889 { | 2023 { |
1890 if (index >= index_.size()) | 2024 if (index >= index_.size()) |
1891 { | 2025 { |
1892 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | 2026 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); |
2027 } | |
2028 | |
2029 if (body.size() > 0xffffffffu) | |
2030 { | |
2031 LogError("Cannot handle body size > 4GB"); | |
2032 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
1893 } | 2033 } |
1894 | 2034 |
1895 OrthancPlugins::MemoryBuffer answer; | 2035 OrthancPlugins::MemoryBuffer answer; |
1896 uint16_t status; | 2036 uint16_t status; |
2037 PluginHttpHeaders pluginHeaders(headers); | |
2038 | |
1897 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | 2039 OrthancPluginErrorCode code = OrthancPluginCallPeerApi |
1898 (GetGlobalContext(), *answer, NULL, &status, peers_, | 2040 (GetGlobalContext(), *answer, NULL, &status, peers_, |
1899 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Post, uri.c_str(), | 2041 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Post, uri.c_str(), |
1900 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); | 2042 pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), body.empty() ? NULL : body.c_str(), body.size(), timeout_); |
1901 | 2043 |
1902 if (code == OrthancPluginErrorCode_Success) | 2044 if (code == OrthancPluginErrorCode_Success) |
1903 { | 2045 { |
1904 target.Swap(answer); | 2046 target.Swap(answer); |
1905 return (status == 200); | 2047 return (status == 200); |
1911 } | 2053 } |
1912 | 2054 |
1913 | 2055 |
1914 bool OrthancPeers::DoPut(size_t index, | 2056 bool OrthancPeers::DoPut(size_t index, |
1915 const std::string& uri, | 2057 const std::string& uri, |
1916 const std::string& body) const | 2058 const std::string& body, |
2059 const std::map<std::string, std::string>& headers) const | |
1917 { | 2060 { |
1918 if (index >= index_.size()) | 2061 if (index >= index_.size()) |
1919 { | 2062 { |
1920 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | 2063 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); |
2064 } | |
2065 | |
2066 if (body.size() > 0xffffffffu) | |
2067 { | |
2068 LogError("Cannot handle body size > 4GB"); | |
2069 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
1921 } | 2070 } |
1922 | 2071 |
1923 OrthancPlugins::MemoryBuffer answer; | 2072 OrthancPlugins::MemoryBuffer answer; |
1924 uint16_t status; | 2073 uint16_t status; |
2074 PluginHttpHeaders pluginHeaders(headers); | |
2075 | |
1925 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | 2076 OrthancPluginErrorCode code = OrthancPluginCallPeerApi |
1926 (GetGlobalContext(), *answer, NULL, &status, peers_, | 2077 (GetGlobalContext(), *answer, NULL, &status, peers_, |
1927 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Put, uri.c_str(), | 2078 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Put, uri.c_str(), |
1928 0, NULL, NULL, body.empty() ? NULL : body.c_str(), body.size(), timeout_); | 2079 pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), body.empty() ? NULL : body.c_str(), body.size(), timeout_); |
1929 | 2080 |
1930 if (code == OrthancPluginErrorCode_Success) | 2081 if (code == OrthancPluginErrorCode_Success) |
1931 { | 2082 { |
1932 return (status == 200); | 2083 return (status == 200); |
1933 } | 2084 } |
1938 } | 2089 } |
1939 | 2090 |
1940 | 2091 |
1941 bool OrthancPeers::DoPut(const std::string& name, | 2092 bool OrthancPeers::DoPut(const std::string& name, |
1942 const std::string& uri, | 2093 const std::string& uri, |
1943 const std::string& body) const | 2094 const std::string& body, |
2095 const std::map<std::string, std::string>& headers) const | |
1944 { | 2096 { |
1945 size_t index; | 2097 size_t index; |
1946 return (LookupName(index, name) && | 2098 return (LookupName(index, name) && |
1947 DoPut(index, uri, body)); | 2099 DoPut(index, uri, body, headers)); |
1948 } | 2100 } |
1949 | 2101 |
1950 | 2102 |
1951 bool OrthancPeers::DoDelete(size_t index, | 2103 bool OrthancPeers::DoDelete(size_t index, |
1952 const std::string& uri) const | 2104 const std::string& uri, |
2105 const std::map<std::string, std::string>& headers) const | |
1953 { | 2106 { |
1954 if (index >= index_.size()) | 2107 if (index >= index_.size()) |
1955 { | 2108 { |
1956 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); | 2109 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); |
1957 } | 2110 } |
1958 | 2111 |
1959 OrthancPlugins::MemoryBuffer answer; | 2112 OrthancPlugins::MemoryBuffer answer; |
1960 uint16_t status; | 2113 uint16_t status; |
2114 PluginHttpHeaders pluginHeaders(headers); | |
2115 | |
1961 OrthancPluginErrorCode code = OrthancPluginCallPeerApi | 2116 OrthancPluginErrorCode code = OrthancPluginCallPeerApi |
1962 (GetGlobalContext(), *answer, NULL, &status, peers_, | 2117 (GetGlobalContext(), *answer, NULL, &status, peers_, |
1963 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Delete, uri.c_str(), | 2118 static_cast<uint32_t>(index), OrthancPluginHttpMethod_Delete, uri.c_str(), |
1964 0, NULL, NULL, NULL, 0, timeout_); | 2119 pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), NULL, 0, timeout_); |
1965 | 2120 |
1966 if (code == OrthancPluginErrorCode_Success) | 2121 if (code == OrthancPluginErrorCode_Success) |
1967 { | 2122 { |
1968 return (status == 200); | 2123 return (status == 200); |
1969 } | 2124 } |
1973 } | 2128 } |
1974 } | 2129 } |
1975 | 2130 |
1976 | 2131 |
1977 bool OrthancPeers::DoDelete(const std::string& name, | 2132 bool OrthancPeers::DoDelete(const std::string& name, |
1978 const std::string& uri) const | 2133 const std::string& uri, |
2134 const std::map<std::string, std::string>& headers) const | |
1979 { | 2135 { |
1980 size_t index; | 2136 size_t index; |
1981 return (LookupName(index, name) && | 2137 return (LookupName(index, name) && |
1982 DoDelete(index, uri)); | 2138 DoDelete(index, uri, headers)); |
1983 } | 2139 } |
1984 #endif | 2140 #endif |
1985 | 2141 |
1986 | 2142 |
1987 | 2143 |
2014 return 0; | 2170 return 0; |
2015 } | 2171 } |
2016 } | 2172 } |
2017 | 2173 |
2018 | 2174 |
2175 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 11, 3) | |
2176 static OrthancPluginErrorCode CopyStringToMemoryBuffer(OrthancPluginMemoryBuffer* target, | |
2177 const std::string& source) | |
2178 { | |
2179 if (OrthancPluginCreateMemoryBuffer(globalContext_, target, source.size()) != OrthancPluginErrorCode_Success) | |
2180 { | |
2181 return OrthancPluginErrorCode_NotEnoughMemory; | |
2182 } | |
2183 else | |
2184 { | |
2185 if (!source.empty()) | |
2186 { | |
2187 memcpy(target->data, source.c_str(), source.size()); | |
2188 } | |
2189 | |
2190 return OrthancPluginErrorCode_Success; | |
2191 } | |
2192 } | |
2193 #endif | |
2194 | |
2195 | |
2196 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 11, 3) | |
2197 OrthancPluginErrorCode OrthancJob::CallbackGetContent(OrthancPluginMemoryBuffer* target, | |
2198 void* job) | |
2199 { | |
2200 assert(job != NULL); | |
2201 OrthancJob& that = *reinterpret_cast<OrthancJob*>(job); | |
2202 return CopyStringToMemoryBuffer(target, that.content_); | |
2203 } | |
2204 #else | |
2019 const char* OrthancJob::CallbackGetContent(void* job) | 2205 const char* OrthancJob::CallbackGetContent(void* job) |
2020 { | 2206 { |
2021 assert(job != NULL); | 2207 assert(job != NULL); |
2022 | 2208 |
2023 try | 2209 try |
2027 catch (...) | 2213 catch (...) |
2028 { | 2214 { |
2029 return 0; | 2215 return 0; |
2030 } | 2216 } |
2031 } | 2217 } |
2032 | 2218 #endif |
2033 | 2219 |
2220 | |
2221 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 11, 3) | |
2222 int32_t OrthancJob::CallbackGetSerialized(OrthancPluginMemoryBuffer* target, | |
2223 void* job) | |
2224 { | |
2225 assert(job != NULL); | |
2226 OrthancJob& that = *reinterpret_cast<OrthancJob*>(job); | |
2227 | |
2228 if (that.hasSerialized_) | |
2229 { | |
2230 if (CopyStringToMemoryBuffer(target, that.serialized_) == OrthancPluginErrorCode_Success) | |
2231 { | |
2232 return 1; | |
2233 } | |
2234 else | |
2235 { | |
2236 return -1; | |
2237 } | |
2238 } | |
2239 else | |
2240 { | |
2241 return 0; | |
2242 } | |
2243 } | |
2244 #else | |
2034 const char* OrthancJob::CallbackGetSerialized(void* job) | 2245 const char* OrthancJob::CallbackGetSerialized(void* job) |
2035 { | 2246 { |
2036 assert(job != NULL); | 2247 assert(job != NULL); |
2037 | 2248 |
2038 try | 2249 try |
2051 catch (...) | 2262 catch (...) |
2052 { | 2263 { |
2053 return 0; | 2264 return 0; |
2054 } | 2265 } |
2055 } | 2266 } |
2267 #endif | |
2056 | 2268 |
2057 | 2269 |
2058 OrthancPluginJobStepStatus OrthancJob::CallbackStep(void* job) | 2270 OrthancPluginJobStepStatus OrthancJob::CallbackStep(void* job) |
2059 { | 2271 { |
2060 assert(job != NULL); | 2272 assert(job != NULL); |
2182 if (job == NULL) | 2394 if (job == NULL) |
2183 { | 2395 { |
2184 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_NullPointer); | 2396 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_NullPointer); |
2185 } | 2397 } |
2186 | 2398 |
2187 OrthancPluginJob* orthanc = OrthancPluginCreateJob( | 2399 OrthancPluginJob* orthanc = |
2188 GetGlobalContext(), job, CallbackFinalize, job->jobType_.c_str(), | 2400 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 11, 3) |
2189 CallbackGetProgress, CallbackGetContent, CallbackGetSerialized, | 2401 OrthancPluginCreateJob2 |
2190 CallbackStep, CallbackStop, CallbackReset); | 2402 #else |
2403 OrthancPluginCreateJob | |
2404 #endif | |
2405 (GetGlobalContext(), job, CallbackFinalize, job->jobType_.c_str(), | |
2406 CallbackGetProgress, CallbackGetContent, CallbackGetSerialized, | |
2407 CallbackStep, CallbackStop, CallbackReset); | |
2191 | 2408 |
2192 if (orthanc == NULL) | 2409 if (orthanc == NULL) |
2193 { | 2410 { |
2194 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); | 2411 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_Plugin); |
2195 } | 2412 } |
2481 { | 2698 { |
2482 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | 2699 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); |
2483 } | 2700 } |
2484 catch (...) | 2701 catch (...) |
2485 { | 2702 { |
2486 return OrthancPluginErrorCode_InternalError; | 2703 return OrthancPluginErrorCode_Plugin; |
2487 } | 2704 } |
2488 } | 2705 } |
2489 } | 2706 } |
2490 }; | 2707 }; |
2491 | 2708 |
2567 } | 2784 } |
2568 | 2785 |
2569 | 2786 |
2570 void HttpClient::ClearCredentials() | 2787 void HttpClient::ClearCredentials() |
2571 { | 2788 { |
2572 username_.empty(); | 2789 username_.clear(); |
2573 password_.empty(); | 2790 password_.clear(); |
2574 } | 2791 } |
2575 | 2792 |
2576 | 2793 |
2577 void HttpClient::SetCertificate(const std::string& certificateFile, | 2794 void HttpClient::SetCertificate(const std::string& certificateFile, |
2578 const std::string& keyFile, | 2795 const std::string& keyFile, |
2881 { | 3098 { |
2882 HeadersWrapper headers(headers_); | 3099 HeadersWrapper headers(headers_); |
2883 | 3100 |
2884 MemoryBuffer answerBodyBuffer, answerHeadersBuffer; | 3101 MemoryBuffer answerBodyBuffer, answerHeadersBuffer; |
2885 | 3102 |
3103 if (body.size() > 0xffffffffu) | |
3104 { | |
3105 LogError("Cannot handle body size > 4GB"); | |
3106 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
3107 } | |
3108 | |
2886 OrthancPluginErrorCode error = OrthancPluginHttpClient( | 3109 OrthancPluginErrorCode error = OrthancPluginHttpClient( |
2887 GetGlobalContext(), | 3110 GetGlobalContext(), |
2888 *answerBodyBuffer, | 3111 *answerBodyBuffer, |
2889 *answerHeadersBuffer, | 3112 *answerHeadersBuffer, |
2890 &httpStatus, | 3113 &httpStatus, |
3497 result->toFree_ = true; | 3720 result->toFree_ = true; |
3498 return result.release(); | 3721 return result.release(); |
3499 } | 3722 } |
3500 } | 3723 } |
3501 #endif | 3724 #endif |
3725 | |
3726 | |
3727 #if HAS_ORTHANC_PLUGIN_WEBDAV == 1 | |
3728 static std::vector<std::string> WebDavConvertPath(uint32_t pathSize, | |
3729 const char* const* pathItems) | |
3730 { | |
3731 std::vector<std::string> result(pathSize); | |
3732 | |
3733 for (uint32_t i = 0; i < pathSize; i++) | |
3734 { | |
3735 result[i] = pathItems[i]; | |
3736 } | |
3737 | |
3738 return result; | |
3739 } | |
3740 #endif | |
3741 | |
3742 | |
3743 #if HAS_ORTHANC_PLUGIN_WEBDAV == 1 | |
3744 static OrthancPluginErrorCode WebDavIsExistingFolder(uint8_t* isExisting, | |
3745 uint32_t pathSize, | |
3746 const char* const* pathItems, | |
3747 void* payload) | |
3748 { | |
3749 IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); | |
3750 | |
3751 try | |
3752 { | |
3753 *isExisting = (that.IsExistingFolder(WebDavConvertPath(pathSize, pathItems)) ? 1 : 0); | |
3754 return OrthancPluginErrorCode_Success; | |
3755 } | |
3756 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
3757 { | |
3758 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
3759 } | |
3760 catch (...) | |
3761 { | |
3762 return OrthancPluginErrorCode_Plugin; | |
3763 } | |
3764 } | |
3765 #endif | |
3766 | |
3767 | |
3768 #if HAS_ORTHANC_PLUGIN_WEBDAV == 1 | |
3769 static OrthancPluginErrorCode WebDavListFolder(uint8_t* isExisting, | |
3770 OrthancPluginWebDavCollection* collection, | |
3771 OrthancPluginWebDavAddFile addFile, | |
3772 OrthancPluginWebDavAddFolder addFolder, | |
3773 uint32_t pathSize, | |
3774 const char* const* pathItems, | |
3775 void* payload) | |
3776 { | |
3777 IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); | |
3778 | |
3779 try | |
3780 { | |
3781 std::list<IWebDavCollection::FileInfo> files; | |
3782 std::list<IWebDavCollection::FolderInfo> subfolders; | |
3783 | |
3784 if (!that.ListFolder(files, subfolders, WebDavConvertPath(pathSize, pathItems))) | |
3785 { | |
3786 *isExisting = 0; | |
3787 } | |
3788 else | |
3789 { | |
3790 *isExisting = 1; | |
3791 | |
3792 for (std::list<IWebDavCollection::FileInfo>::const_iterator | |
3793 it = files.begin(); it != files.end(); ++it) | |
3794 { | |
3795 OrthancPluginErrorCode code = addFile( | |
3796 collection, it->GetName().c_str(), it->GetContentSize(), | |
3797 it->GetMimeType().c_str(), it->GetDateTime().c_str()); | |
3798 | |
3799 if (code != OrthancPluginErrorCode_Success) | |
3800 { | |
3801 return code; | |
3802 } | |
3803 } | |
3804 | |
3805 for (std::list<IWebDavCollection::FolderInfo>::const_iterator it = | |
3806 subfolders.begin(); it != subfolders.end(); ++it) | |
3807 { | |
3808 OrthancPluginErrorCode code = addFolder( | |
3809 collection, it->GetName().c_str(), it->GetDateTime().c_str()); | |
3810 | |
3811 if (code != OrthancPluginErrorCode_Success) | |
3812 { | |
3813 return code; | |
3814 } | |
3815 } | |
3816 } | |
3817 | |
3818 return OrthancPluginErrorCode_Success; | |
3819 } | |
3820 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
3821 { | |
3822 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
3823 } | |
3824 catch (...) | |
3825 { | |
3826 return OrthancPluginErrorCode_Plugin; | |
3827 } | |
3828 } | |
3829 #endif | |
3830 | |
3831 | |
3832 #if HAS_ORTHANC_PLUGIN_WEBDAV == 1 | |
3833 static OrthancPluginErrorCode WebDavRetrieveFile(OrthancPluginWebDavCollection* collection, | |
3834 OrthancPluginWebDavRetrieveFile retrieveFile, | |
3835 uint32_t pathSize, | |
3836 const char* const* pathItems, | |
3837 void* payload) | |
3838 { | |
3839 IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); | |
3840 | |
3841 try | |
3842 { | |
3843 std::string content, mime, dateTime; | |
3844 | |
3845 if (that.GetFile(content, mime, dateTime, WebDavConvertPath(pathSize, pathItems))) | |
3846 { | |
3847 return retrieveFile(collection, content.empty() ? NULL : content.c_str(), | |
3848 content.size(), mime.c_str(), dateTime.c_str()); | |
3849 } | |
3850 else | |
3851 { | |
3852 // Inexisting file | |
3853 return OrthancPluginErrorCode_Success; | |
3854 } | |
3855 } | |
3856 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
3857 { | |
3858 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
3859 } | |
3860 catch (...) | |
3861 { | |
3862 return OrthancPluginErrorCode_InternalError; | |
3863 } | |
3864 } | |
3865 #endif | |
3866 | |
3867 | |
3868 #if HAS_ORTHANC_PLUGIN_WEBDAV == 1 | |
3869 static OrthancPluginErrorCode WebDavStoreFileCallback(uint8_t* isReadOnly, /* out */ | |
3870 uint32_t pathSize, | |
3871 const char* const* pathItems, | |
3872 const void* data, | |
3873 uint64_t size, | |
3874 void* payload) | |
3875 { | |
3876 IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); | |
3877 | |
3878 try | |
3879 { | |
3880 if (static_cast<uint64_t>(static_cast<size_t>(size)) != size) | |
3881 { | |
3882 ORTHANC_PLUGINS_THROW_EXCEPTION(NotEnoughMemory); | |
3883 } | |
3884 | |
3885 *isReadOnly = (that.StoreFile(WebDavConvertPath(pathSize, pathItems), data, | |
3886 static_cast<size_t>(size)) ? 1 : 0); | |
3887 return OrthancPluginErrorCode_Success; | |
3888 } | |
3889 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
3890 { | |
3891 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
3892 } | |
3893 catch (...) | |
3894 { | |
3895 return OrthancPluginErrorCode_InternalError; | |
3896 } | |
3897 } | |
3898 #endif | |
3899 | |
3900 | |
3901 #if HAS_ORTHANC_PLUGIN_WEBDAV == 1 | |
3902 static OrthancPluginErrorCode WebDavCreateFolderCallback(uint8_t* isReadOnly, /* out */ | |
3903 uint32_t pathSize, | |
3904 const char* const* pathItems, | |
3905 void* payload) | |
3906 { | |
3907 IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); | |
3908 | |
3909 try | |
3910 { | |
3911 *isReadOnly = (that.CreateFolder(WebDavConvertPath(pathSize, pathItems)) ? 1 : 0); | |
3912 return OrthancPluginErrorCode_Success; | |
3913 } | |
3914 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
3915 { | |
3916 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
3917 } | |
3918 catch (...) | |
3919 { | |
3920 return OrthancPluginErrorCode_InternalError; | |
3921 } | |
3922 } | |
3923 #endif | |
3924 | |
3925 | |
3926 #if HAS_ORTHANC_PLUGIN_WEBDAV == 1 | |
3927 static OrthancPluginErrorCode WebDavDeleteItemCallback(uint8_t* isReadOnly, /* out */ | |
3928 uint32_t pathSize, | |
3929 const char* const* pathItems, | |
3930 void* payload) | |
3931 { | |
3932 IWebDavCollection& that = *reinterpret_cast<IWebDavCollection*>(payload); | |
3933 | |
3934 try | |
3935 { | |
3936 *isReadOnly = (that.DeleteItem(WebDavConvertPath(pathSize, pathItems)) ? 1 : 0); | |
3937 return OrthancPluginErrorCode_Success; | |
3938 } | |
3939 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
3940 { | |
3941 return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); | |
3942 } | |
3943 catch (...) | |
3944 { | |
3945 return OrthancPluginErrorCode_InternalError; | |
3946 } | |
3947 } | |
3948 #endif | |
3949 | |
3950 | |
3951 #if HAS_ORTHANC_PLUGIN_WEBDAV == 1 | |
3952 void IWebDavCollection::Register(const std::string& uri, | |
3953 IWebDavCollection& collection) | |
3954 { | |
3955 OrthancPluginErrorCode code = OrthancPluginRegisterWebDavCollection( | |
3956 GetGlobalContext(), uri.c_str(), WebDavIsExistingFolder, WebDavListFolder, WebDavRetrieveFile, | |
3957 WebDavStoreFileCallback, WebDavCreateFolderCallback, WebDavDeleteItemCallback, &collection); | |
3958 | |
3959 if (code != OrthancPluginErrorCode_Success) | |
3960 { | |
3961 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); | |
3962 } | |
3963 } | |
3964 #endif | |
3965 | |
3966 void GetHttpHeaders(std::map<std::string, std::string>& result, const OrthancPluginHttpRequest* request) | |
3967 { | |
3968 result.clear(); | |
3969 | |
3970 for (uint32_t i = 0; i < request->headersCount; ++i) | |
3971 { | |
3972 result[request->headersKeys[i]] = request->headersValues[i]; | |
3973 } | |
3974 } | |
3502 } | 3975 } |