# HG changeset patch # User Sebastien Jodogne # Date 1413290878 -7200 # Node ID b17b6bd59747cbf5ff218dc629c34dc9adf2d11b # Parent 4e9d517503aeec074c6950fd7c0608e5480077cb timeouts for HTTP and DICOM diff -r 4e9d517503ae -r b17b6bd59747 Core/HttpClient.cpp --- a/Core/HttpClient.cpp Fri Oct 10 09:13:48 2014 +0200 +++ b/Core/HttpClient.cpp Tue Oct 14 14:47:58 2014 +0200 @@ -109,6 +109,7 @@ method_ = HttpMethod_Get; lastStatus_ = HttpStatus_200_Ok; isVerbose_ = false; + timeout_ = 0; } @@ -171,6 +172,18 @@ CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POSTFIELDS, NULL)); CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POSTFIELDSIZE, 0)); + // Set timeouts + if (timeout_ <= 0) + { + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_TIMEOUT, 10)); /* default: 10 seconds */ + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_CONNECTTIMEOUT, 10)); /* default: 10 seconds */ + } + else + { + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_TIMEOUT, timeout_)); + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_CONNECTTIMEOUT, timeout_)); + } + if (credentials_.size() != 0) { CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_USERPWD, credentials_.c_str())); diff -r 4e9d517503ae -r b17b6bd59747 Core/HttpClient.h --- a/Core/HttpClient.h Fri Oct 10 09:13:48 2014 +0200 +++ b/Core/HttpClient.h Tue Oct 14 14:47:58 2014 +0200 @@ -52,6 +52,7 @@ HttpStatus lastStatus_; std::string postData_; bool isVerbose_; + long timeout_; void Setup(); @@ -89,6 +90,16 @@ return method_; } + void SetTimeout(long seconds) + { + timeout_ = seconds; + } + + long GetTimeout() const + { + return timeout_; + } + void SetPostData(const std::string& data) { postData_ = data; diff -r 4e9d517503ae -r b17b6bd59747 OrthancServer/DicomProtocol/DicomUserConnection.cpp --- a/OrthancServer/DicomProtocol/DicomUserConnection.cpp Fri Oct 10 09:13:48 2014 +0200 +++ b/OrthancServer/DicomProtocol/DicomUserConnection.cpp Tue Oct 14 14:47:58 2014 +0200 @@ -135,6 +135,8 @@ struct DicomUserConnection::PImpl { // Connection state + uint32_t dimseTimeout_; + uint32_t acseTimeout_; T_ASC_Network* net_; T_ASC_Parameters* params_; T_ASC_Association* assoc_; @@ -325,7 +327,7 @@ DcmDataset* statusDetail = NULL; Check(DIMSE_storeUser(assoc_, presID, &req, NULL, dcmff.getDataset(), /*progressCallback*/ NULL, NULL, - /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ 0, + /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ dimseTimeout_, &rsp, &statusDetail, NULL)); if (statusDetail != NULL) @@ -466,7 +468,8 @@ DcmDataset* statusDetail = NULL; OFCondition cond = DIMSE_findUser(pimpl_->assoc_, presID, &request, dataset.get(), FindCallback, &result, - /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ 0, + /*opt_blockMode*/ DIMSE_BLOCKING, + /*opt_dimse_timeout*/ pimpl_->dimseTimeout_, &response, &statusDetail); if (statusDetail) @@ -559,7 +562,8 @@ DcmDataset* responseIdentifiers = NULL; OFCondition cond = DIMSE_moveUser(pimpl_->assoc_, presID, &request, dataset.get(), NULL, NULL, - /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ 0, + /*opt_blockMode*/ DIMSE_BLOCKING, + /*opt_dimse_timeout*/ pimpl_->dimseTimeout_, pimpl_->net_, NULL, NULL, &response, &statusDetail, &responseIdentifiers); @@ -616,6 +620,7 @@ distantPort_ = 104; manufacturer_ = ModalityManufacturer_Generic; + SetTimeout(10); pimpl_->net_ = NULL; pimpl_->params_ = NULL; pimpl_->assoc_ = NULL; @@ -722,7 +727,7 @@ << GetDistantHost() << ":" << GetDistantPort() << " (manufacturer: " << EnumerationToString(GetDistantManufacturer()) << ")"; - Check(ASC_initializeNetwork(NET_REQUESTOR, 0, /*opt_acse_timeout*/ 30, &pimpl_->net_)); + Check(ASC_initializeNetwork(NET_REQUESTOR, 0, /*opt_acse_timeout*/ pimpl_->acseTimeout_, &pimpl_->net_)); Check(ASC_createAssociationParameters(&pimpl_->params_, /*opt_maxReceivePDULength*/ ASC_DEFAULTMAXPDU)); // Set this application's title and the called application's title in the params @@ -818,7 +823,8 @@ CheckIsOpen(); DIC_US status; Check(DIMSE_echoUser(pimpl_->assoc_, pimpl_->assoc_->nextMsgID++, - /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ 0, + /*opt_blockMode*/ DIMSE_BLOCKING, + /*opt_dimse_timeout*/ pimpl_->dimseTimeout_, &status, NULL)); return status == STATUS_Success; } @@ -865,9 +871,29 @@ Move(targetAet, map); } - void DicomUserConnection::SetConnectionTimeout(uint32_t seconds) + + void DicomUserConnection::SetTimeout(uint32_t seconds) { + if (seconds <= 0) + { + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + dcmConnectionTimeout.set(seconds); + pimpl_->dimseTimeout_ = seconds; + pimpl_->acseTimeout_ = 10; + } + + + void DicomUserConnection::DisableTimeout() + { + /** + * Global timeout (seconds) for connecting to remote hosts. + * Default value is -1 which selects infinite timeout, i.e. blocking connect(). + */ + dcmConnectionTimeout.set(-1); + pimpl_->dimseTimeout_ = 0; + pimpl_->acseTimeout_ = 10; } diff -r 4e9d517503ae -r b17b6bd59747 OrthancServer/DicomProtocol/DicomUserConnection.h --- a/OrthancServer/DicomProtocol/DicomUserConnection.h Fri Oct 10 09:13:48 2014 +0200 +++ b/OrthancServer/DicomProtocol/DicomUserConnection.h Tue Oct 14 14:47:58 2014 +0200 @@ -177,6 +177,8 @@ const std::string& seriesUid, const std::string& instanceUid); - static void SetConnectionTimeout(uint32_t seconds); + void SetTimeout(uint32_t seconds); + + void DisableTimeout(); }; }