# HG changeset patch # User Sebastien Jodogne # Date 1561457703 -7200 # Node ID d30668b1a44afe0527cad1260dad56ec3371d1f0 # Parent 52da6e9335dd4494e0a3e5cb1ec82d048e39ed93 commenting new functions in SDK diff -r 52da6e9335dd -r d30668b1a44a Plugins/Include/orthanc/OrthancCPlugin.h --- a/Plugins/Include/orthanc/OrthancCPlugin.h Tue Jun 25 10:51:01 2019 +0200 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Tue Jun 25 12:15:03 2019 +0200 @@ -25,6 +25,7 @@ * - Possibly register a callback to filter incoming HTTP requests using OrthancPluginRegisterIncomingHttpRequestFilter2(). * - Possibly register a callback to unserialize jobs using OrthancPluginRegisterJobsUnserializer(). * - Possibly register a callback to refresh its metrics using OrthancPluginRegisterRefreshMetricsCallback(). + * - Possibly register a callback to answer chunked HTTP transfers using ::OrthancPluginRegisterChunkedRestCallback(). * -# void OrthancPluginFinalize(): * This function is invoked by Orthanc during its shutdown. The plugin * must free all its memory. @@ -4055,6 +4056,7 @@ * @param username The username (can be NULL if no password protection). * @param password The password (can be NULL if no password protection). * @return 0 if success, or the error code if failure. + * @ingroup Toolbox **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginHttpGet( OrthancPluginContext* context, @@ -4092,6 +4094,7 @@ * @param username The username (can be NULL if no password protection). * @param password The password (can be NULL if no password protection). * @return 0 if success, or the error code if failure. + * @ingroup Toolbox **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginHttpPost( OrthancPluginContext* context, @@ -4133,6 +4136,7 @@ * @param username The username (can be NULL if no password protection). * @param password The password (can be NULL if no password protection). * @return 0 if success, or the error code if failure. + * @ingroup Toolbox **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginHttpPut( OrthancPluginContext* context, @@ -4170,6 +4174,7 @@ * @param username The username (can be NULL if no password protection). * @param password The password (can be NULL if no password protection). * @return 0 if success, or the error code if failure. + * @ingroup Toolbox **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginHttpDelete( OrthancPluginContext* context, @@ -5539,6 +5544,7 @@ * @param pkcs11 Enable PKCS#11 client authentication for hardware security modules and smart cards. * @return 0 if success, or the error code if failure. * @see OrthancPluginCallPeerApi() + * @ingroup Toolbox **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginHttpClient( OrthancPluginContext* context, @@ -6801,36 +6807,114 @@ - - - - - - - - - - - - - typedef OrthancPluginErrorCode (*OrthancPluginChunkedClientAnswerAddHeader) (void* answer, - const char* key, - const char* value); - - typedef OrthancPluginErrorCode (*OrthancPluginChunkedClientAnswerAddChunk) (void* answer, - const void* data, - uint32_t size); - + /** + * @brief Callback executed when a HTTP header is received during a chunked transfer. + * + * Signature of a callback function that is called by Orthanc acting + * as a HTTP client during a chunked HTTP transfer, as soon as it + * receives one HTTP header from the answer of the remote HTTP + * server. + * + * @see OrthancPluginChunkedHttpClient() + * @param answer The user payload, as provided by the calling plugin. + * @param key The key of the HTTP header. + * @param value The value of the HTTP header. + * @return 0 if success, or the error code if failure. + * @ingroup Toolbox + **/ + typedef OrthancPluginErrorCode (*OrthancPluginChunkedClientAnswerAddHeader) ( + void* answer, + const char* key, + const char* value); + + + /** + * @brief Callback executed when an answer chunk is received during a chunked transfer. + * + * Signature of a callback function that is called by Orthanc acting + * as a HTTP client during a chunked HTTP transfer, as soon as it + * receives one data chunk from the answer of the remote HTTP + * server. + * + * @see OrthancPluginChunkedHttpClient() + * @param answer The user payload, as provided by the calling plugin. + * @param data The content of the data chunk. + * @param size The size of the data chunk. + * @return 0 if success, or the error code if failure. + * @ingroup Toolbox + **/ + typedef OrthancPluginErrorCode (*OrthancPluginChunkedClientAnswerAddChunk) ( + void* answer, + const void* data, + uint32_t size); + + + /** + * @brief Callback to know whether the request body is entirely read during a chunked transfer + * + * Signature of a callback function that is called by Orthanc acting + * as a HTTP client during a chunked HTTP transfer, while reading + * the body of a POST or PUT request. The plugin must answer "1" as + * soon as the body is entirely read: The "request" data structure + * must act as an iterator. + * + * @see OrthancPluginChunkedHttpClient() + * @param request The user payload, as provided by the calling plugin. + * @return "1" if the body is over, or "0" if there is still data to be read. + * @ingroup Toolbox + **/ typedef uint8_t (*OrthancPluginChunkedClientRequestIsDone) (void* request); + + /** + * @brief Callback to advance in the request body during a chunked transfer + * + * Signature of a callback function that is called by Orthanc acting + * as a HTTP client during a chunked HTTP transfer, while reading + * the body of a POST or PUT request. This function asks the plugin + * to advance to the next chunk of data of the request body: The + * "request" data structure must act as an iterator. + * + * @see OrthancPluginChunkedHttpClient() + * @param request The user payload, as provided by the calling plugin. + * @return 0 if success, or the error code if failure. + * @ingroup Toolbox + **/ typedef OrthancPluginErrorCode (*OrthancPluginChunkedClientRequestNext) (void* request); + + /** + * @brief Callback to read the current chunk of the request body during a chunked transfer + * + * Signature of a callback function that is called by Orthanc acting + * as a HTTP client during a chunked HTTP transfer, while reading + * the body of a POST or PUT request. The plugin must provide the + * content of the current chunk of data of the request body. + * + * @see OrthancPluginChunkedHttpClient() + * @param request The user payload, as provided by the calling plugin. + * @return The content of the current request chunk. + * @ingroup Toolbox + **/ typedef const void* (*OrthancPluginChunkedClientRequestGetChunkData) (void* request); + + /** + * @brief Callback to read the size of the current request chunk during a chunked transfer + * + * Signature of a callback function that is called by Orthanc acting + * as a HTTP client during a chunked HTTP transfer, while reading + * the body of a POST or PUT request. The plugin must provide the + * size of the current chunk of data of the request body. + * + * @see OrthancPluginChunkedHttpClient() + * @param request The user payload, as provided by the calling plugin. + * @return The size of the current request chunk. + * @ingroup Toolbox + **/ typedef uint32_t (*OrthancPluginChunkedClientRequestGetChunkSize) (void* request); - typedef struct { void* answer; @@ -6856,6 +6940,57 @@ uint8_t pkcs11; } _OrthancPluginChunkedHttpClient; + + /** + * @brief Issue a HTTP call, using chunked HTTP transfers. + * + * Make a HTTP call to the given URL using chunked HTTP + * transfers. The request body is provided as an iterator over data + * chunks. The answer is provided as a sequence of function calls + * with the individual HTTP headers and answer chunks. + * + * Contrarily to OrthancPluginHttpClient() that entirely stores the + * request body and the answer body in memory buffers, this function + * uses chunked HTTP transfers. This results in a lower memory + * consumption. Pay attention to the fact that Orthanc servers with + * version <= 1.5.6 do not support chunked transfers: You must use + * OrthancPluginHttpClient() if contacting such older servers. + * + * The HTTP request will be done accordingly to the global + * configuration of Orthanc (in particular, the options "HttpProxy", + * "HttpTimeout", "HttpsVerifyPeers", "HttpsCACertificates", and + * "Pkcs11" will be taken into account). + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param answer The user payload for the answer body. It will be provided to the callbacks for the answer. + * @param answerAddChunk Callback function to report a data chunk from the answer body. + * @param answerAddHeader Callback function to report an HTTP header sent by the remote server. + * @param httpStatus The HTTP status after the execution of the request (out argument). + * @param method HTTP method to be used. + * @param url The URL of interest. + * @param headersCount The number of HTTP headers. + * @param headersKeys Array containing the keys of the HTTP headers (can be NULL if no header). + * @param headersValues Array containing the values of the HTTP headers (can be NULL if no header). + * @param request The user payload containing the request body, and acting as an iterator. + * It will be provided to the callbacks for the request. + * @param requestIsDone Callback function to tell whether the request body is entirely read. + * @param requestChunkData Callback function to get the content of the current data chunk of the request body. + * @param requestChunkSize Callback function to get the size of the current data chunk of the request body. + * @param requestNext Callback function to advance to the next data chunk of the request body. + * @param username The username (can be NULL if no password protection). + * @param password The password (can be NULL if no password protection). + * @param timeout Timeout in seconds (0 for default timeout). + * @param certificateFile Path to the client certificate for HTTPS, in PEM format + * (can be NULL if no client certificate or if not using HTTPS). + * @param certificateKeyFile Path to the key of the client certificate for HTTPS, in PEM format + * (can be NULL if no client certificate or if not using HTTPS). + * @param certificateKeyPassword Password to unlock the key of the client certificate + * (can be NULL if no client certificate or if not using HTTPS). + * @param pkcs11 Enable PKCS#11 client authentication for hardware security modules and smart cards. + * @return 0 if success, or the error code if failure. + * @see OrthancPluginHttpClient() + * @ingroup Toolbox + **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginChunkedHttpClient( OrthancPluginContext* context, void* answer, @@ -6913,23 +7048,86 @@ + /** + * @brief Opaque structure that reads the content of a HTTP request body during a chunked HTTP transfer. + * @ingroup Callback + **/ typedef struct _OrthancPluginServerChunkedRequestReader_t OrthancPluginServerChunkedRequestReader; - /* POST and PUT must share the same reader */ + + + /** + * @brief Callback to create a reader to handle incoming chunked HTTP transfers. + * + * Signature of a callback function that is called by Orthanc acting + * as a HTTP server that supports chunked HTTP transfers. This + * callback is only invoked if the HTTP method is POST or PUT. The + * callback must create an user-specific "reader" object that will + * be fed with the body of the incoming body. + * + * @see OrthancPluginRegisterChunkedRestCallback() + * @param reader Memory location that must be filled with the newly-created reader. + * @param url The URI that is accessed. + * @param request The body of the HTTP request. Note that "body" and "bodySize" are not used. + * @return 0 if success, or the error code if failure. + **/ typedef OrthancPluginErrorCode (*OrthancPluginServerChunkedRequestReaderFactory) ( - OrthancPluginServerChunkedRequestReader** reader, /* out, for POST/PUT only */ + OrthancPluginServerChunkedRequestReader** reader, const char* url, - const OrthancPluginHttpRequest* request); /* body and bodySize are not used */ - + const OrthancPluginHttpRequest* request); + + + /** + * @brief Callback invoked whenever a new data chunk is available during a chunked transfer. + * + * Signature of a callback function that is called by Orthanc acting + * as a HTTP server that supports chunked HTTP transfers. This callback + * is invoked as soon as a new data chunk is available for the request body. + * + * @see OrthancPluginRegisterChunkedRestCallback() + * @param reader The user payload, as created by the OrthancPluginServerChunkedRequestReaderFactory() callback. + * @param data The content of the data chunk. + * @param size The size of the data chunk. + * @return 0 if success, or the error code if failure. + **/ typedef OrthancPluginErrorCode (*OrthancPluginServerChunkedRequestReaderAddChunk) ( OrthancPluginServerChunkedRequestReader* reader, const void* data, uint32_t size); + + /** + * @brief Callback invoked whenever the request body is entirely received. + * + * Signature of a callback function that is called by Orthanc acting + * as a HTTP server that supports chunked HTTP transfers. This + * callback is invoked as soon as the full body of the HTTP request + * is available. The plugin can then send its answer thanks to the + * provided "output" object. + * + * @see OrthancPluginRegisterChunkedRestCallback() + * @param reader The user payload, as created by the OrthancPluginServerChunkedRequestReaderFactory() callback. + * @param output The HTTP connection to the client application. + * @return 0 if success, or the error code if failure. + **/ typedef OrthancPluginErrorCode (*OrthancPluginServerChunkedRequestReaderExecute) ( OrthancPluginServerChunkedRequestReader* reader, OrthancPluginRestOutput* output); + + /** + * @brief Callback invoked to release the resources associated with an incoming HTTP chunked transfer. + * + * Signature of a callback function that is called by Orthanc acting + * as a HTTP server that supports chunked HTTP transfers. This + * callback is invoked to release all the resources allocated by the + * given reader. Note that this function might be invoked even if + * the entire body was not read, to deal with client error or + * disconnection. + * + * @see OrthancPluginRegisterChunkedRestCallback() + * @param reader The user payload, as created by the OrthancPluginServerChunkedRequestReaderFactory() callback. + **/ typedef void (*OrthancPluginServerChunkedRequestReaderFinalize) ( OrthancPluginServerChunkedRequestReader* reader); @@ -6945,6 +7143,36 @@ OrthancPluginServerChunkedRequestReaderFinalize finalize; } _OrthancPluginChunkedRestCallback; + + /** + * @brief Register a REST callback to handle chunked HTTP transfers. + * + * This function registers a REST callback against a regular + * expression for a URI. This function must be called during the + * initialization of the plugin, i.e. inside the + * OrthancPluginInitialize() public function. + * + * Contrarily to OrthancPluginRegisterRestCallback(), the callbacks + * will NOT be invoked in mutual exclusion, so it is up to the + * plugin to implement the required locking mechanisms. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param pathRegularExpression Regular expression for the URI. May contain groups. + * @param getHandler The callback function to handle REST calls using the GET HTTP method. + * @param postHandler The callback function to handle REST calls using the GET POST method. + * @param deleteHandler The callback function to handle REST calls using the GET DELETE method. + * @param putHandler The callback function to handle REST calls using the GET PUT method. + * @param addChunk The callback invoked when a new chunk is available for the request body of a POST or PUT call. + * @param execute The callback invoked once the entire body of a POST or PUT call is read. + * @param finalize The callback invoked to release the resources associated with a POST or PUT call. + * @see OrthancPluginRegisterRestCallbackNoLock() + * + * @note + * The regular expression is case sensitive and must follow the + * [Perl syntax](https://www.boost.org/doc/libs/1_67_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html). + * + * @ingroup Callbacks + **/ ORTHANC_PLUGIN_INLINE void OrthancPluginRegisterChunkedRestCallback( OrthancPluginContext* context, const char* pathRegularExpression, @@ -6981,11 +7209,26 @@ const char* privateCreator; } _OrthancPluginGetTagName; + /** + * @brief Returns the symbolic name of a DICOM tag. + * + * This function makes a lookup to the dictionary of DICOM tags that + * are known to Orthanc, and returns the symbolic name of a DICOM tag. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param group The group of the tag. + * @param element The element of the tag. + * @param privateCreator For private tags, the name of the private creator (can be NULL). + * @return NULL in the case of an error, or a newly allocated string + * containing the path. This string must be freed by + * OrthancPluginFreeString(). + * @ingroup Toolbox + **/ ORTHANC_PLUGIN_INLINE char* OrthancPluginGetTagName( OrthancPluginContext* context, uint16_t group, uint16_t element, - const char* privateCreator /* can be NULL */) + const char* privateCreator) { char* result;