@@ -168,7 +168,8 @@ class BackgroundTransportCurl {
168168
169169 CURL* curl () const { return curl_; }
170170 Response* response () const { return response_; }
171- void set_canceled (bool canceled) { canceled_ = true ; }
171+ void set_canceled (bool canceled) { canceled_ = canceled; }
172+ void set_timed_out (bool timed_out) { timed_out_ = timed_out; }
172173 ControllerCurl* controller () const { return controller_; }
173174 TransportCurl* transport_curl () const { return transport_curl_; }
174175
@@ -203,6 +204,8 @@ class BackgroundTransportCurl {
203204 void * complete_data_;
204205 // Whether the operation has been canceled.
205206 bool canceled_;
207+ // Whether the operation timed out.
208+ bool timed_out_;
206209};
207210
208211// The data common to both threads. This is used to communicate when the
@@ -358,7 +361,8 @@ BackgroundTransportCurl::BackgroundTransportCurl(
358361 transport_curl_(transport_curl),
359362 complete_(complete),
360363 complete_data_(complete_data),
361- canceled_(false ) {
364+ canceled_(false ),
365+ timed_out_(false ) {
362366 assert (curl_multi_);
363367 assert (curl_);
364368 assert (transport_curl);
@@ -389,15 +393,15 @@ BackgroundTransportCurl::~BackgroundTransportCurl() {
389393 request_header_ = nullptr ;
390394 }
391395
392- // If this is an asynchronous operation, MarkCanceled () or MarkCompleted()
396+ // If this is an asynchronous operation, MarkFailed () or MarkCompleted()
393397 // could end up attempting to tear down TransportCurl so we signal
394398 // completion here.
395399 if (transport_curl_->is_async ()) {
396400 transport_curl_->SignalTransferComplete ();
397401 CompleteOperation ();
398402 } else {
399403 // Synchronous operations need all data present in the response before
400- // Perform() returns so signal complete after MarkCanceled () or
404+ // Perform() returns so signal complete after MarkFailed () or
401405 // MarkCompleted().
402406 CompleteOperation ();
403407 transport_curl_->SignalTransferComplete ();
@@ -407,8 +411,13 @@ BackgroundTransportCurl::~BackgroundTransportCurl() {
407411void BackgroundTransportCurl::CompleteOperation () {
408412 if (complete_) complete_ (this , complete_data_);
409413 if (canceled_) {
410- request_->MarkCanceled ();
411- response_->MarkCanceled ();
414+ response_->set_status (rest::util::HttpNoContent);
415+ request_->MarkFailed ();
416+ response_->MarkFailed ();
417+ } else if (timed_out_) {
418+ response_->set_status (rest::util::HttpRequestTimeout);
419+ request_->MarkFailed ();
420+ response_->MarkFailed ();
412421 } else {
413422 request_->MarkCompleted ();
414423 response_->MarkCompleted ();
@@ -456,6 +465,8 @@ bool BackgroundTransportCurl::PerformBackground(Request* request) {
456465 " set http body read callback" );
457466 CheckOk (curl_easy_setopt (curl_, CURLOPT_READDATA, request),
458467 " set http body read callback data" );
468+ CheckOk (curl_easy_setopt (curl_, CURLOPT_TIMEOUT_MS, options.timeout_ms ),
469+ " set http timeout milliseconds" );
459470
460471 // SDK error in initialization stage is not recoverable.
461472 FIREBASE_ASSERT (err_code_ == CURLE_OK);
@@ -872,9 +883,16 @@ void CurlThread::ProcessRequests() {
872883 char * char_pointer;
873884 curl_easy_getinfo (handle, CURLINFO_PRIVATE, &char_pointer);
874885 curl_multi_remove_handle (curl_multi, handle);
886+ BackgroundTransportCurl* transport =
887+ reinterpret_cast <BackgroundTransportCurl*>(char_pointer);
888+
889+ // Determine if the request timed out.
890+ if (message->data .result == CURLE_OPERATION_TIMEDOUT) {
891+ transport->set_timed_out (true );
892+ }
875893
876894 // Mark the response complete.
877- delete reinterpret_cast <BackgroundTransportCurl*>(char_pointer) ;
895+ delete transport ;
878896 expected_running_handles--;
879897 break ;
880898 }
0 commit comments