Unverified Commit 43d036e7 authored by Ryan Winograd's avatar Ryan Winograd Committed by Daniel Stenberg
Browse files

progress: Track total times following redirects

Update the progress timers `t_nslookup`, `t_connect`, `t_appconnect`,
`t_pretransfer`, and `t_starttransfer` to track the total times for
these activities when a redirect is followed. Previously, only the times
for the most recent request would be tracked.

Related changes:

  - Rename `Curl_pgrsResetTimesSizes` to `Curl_pgrsResetTransferSizes`
    now that the function only resets transfer sizes and no longer
    modifies any of the progress timers.

  - Add a bool to the `Progress` struct that is used to prevent
    double-counting `t_starttransfer` times.

Added test case 1399.

Fixes #522 and Known Bug 1.8
Closes #1602
Reported-by: joshhe on github
parent 0969901e
Loading
Loading
Loading
Loading
+0 −7
Original line number Original line Diff line number Diff line
@@ -18,7 +18,6 @@ problems may have been fixed or changed somewhat since this was written!
 1.4 multipart formposts file name encoding
 1.4 multipart formposts file name encoding
 1.5 Expect-100 meets 417
 1.5 Expect-100 meets 417
 1.6 Unnecessary close when 401 received waiting for 100
 1.6 Unnecessary close when 401 received waiting for 100
 1.8 DNS timing is wrong for HTTP redirects
 1.9 HTTP/2 frames while in the connection pool kill reuse
 1.9 HTTP/2 frames while in the connection pool kill reuse
 1.10 Strips trailing dot from host name
 1.10 Strips trailing dot from host name
 1.11 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
 1.11 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
@@ -140,12 +139,6 @@ problems may have been fixed or changed somewhat since this was written!
 waiting for the the 100-continue response.
 waiting for the the 100-continue response.
 https://curl.haxx.se/mail/lib-2008-08/0462.html
 https://curl.haxx.se/mail/lib-2008-08/0462.html


1.8 DNS timing is wrong for HTTP redirects

 When extracting timing information after HTTP redirects, only the last
 transfer's results are returned and not the totals:
 https://github.com/curl/curl/issues/522

1.9 HTTP/2 frames while in the connection pool kill reuse
1.9 HTTP/2 frames while in the connection pool kill reuse


 If the server sends HTTP/2 frames (like for example an HTTP/2 PING frame) to
 If the server sends HTTP/2 frames (like for example an HTTP/2 PING frame) to
+1 −0
Original line number Original line Diff line number Diff line
@@ -54,6 +54,7 @@ CURLcode Curl_initinfo(struct Curl_easy *data)
  pro->t_starttransfer = 0;
  pro->t_starttransfer = 0;
  pro->timespent = 0;
  pro->timespent = 0;
  pro->t_redirect = 0;
  pro->t_redirect = 0;
  pro->is_t_startransfer_set = false;


  info->httpcode = 0;
  info->httpcode = 0;
  info->httpproxycode = 0;
  info->httpproxycode = 0;
+7 −9
Original line number Original line Diff line number Diff line
@@ -149,14 +149,9 @@ int Curl_pgrsDone(struct connectdata *conn)
  return 0;
  return 0;
}
}


/* reset all times except redirect, and reset the known transfer sizes */
/* reset the known transfer sizes */
void Curl_pgrsResetTimesSizes(struct Curl_easy *data)
void Curl_pgrsResetTransferSizes(struct Curl_easy *data)
{
{
  data->progress.t_nslookup = 0;
  data->progress.t_connect = 0;
  data->progress.t_pretransfer = 0;
  data->progress.t_starttransfer = 0;

  Curl_pgrsSetDownloadSize(data, -1);
  Curl_pgrsSetDownloadSize(data, -1);
  Curl_pgrsSetUploadSize(data, -1);
  Curl_pgrsSetUploadSize(data, -1);
}
}
@@ -181,6 +176,7 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
  case TIMER_STARTSINGLE:
  case TIMER_STARTSINGLE:
    /* This is set at the start of each single fetch */
    /* This is set at the start of each single fetch */
    data->progress.t_startsingle = now;
    data->progress.t_startsingle = now;
    data->progress.is_t_startransfer_set = false;
    break;
    break;
  case TIMER_STARTACCEPT:
  case TIMER_STARTACCEPT:
    data->progress.t_acceptdata = now;
    data->progress.t_acceptdata = now;
@@ -205,10 +201,11 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
     * This prevents repeated invocations of the function from incorrectly
     * This prevents repeated invocations of the function from incorrectly
     * changing the t_starttransfer time.
     * changing the t_starttransfer time.
     */
     */
    if (*delta > data->progress.t_redirect) {
    if(data->progress.is_t_startransfer_set) {
      return;
      return;
    }
    }
    else {
    else {
      data->progress.is_t_startransfer_set = true;
      break;
      break;
    }
    }
  case TIMER_POSTRANSFER:
  case TIMER_POSTRANSFER:
@@ -222,7 +219,7 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
    time_t us = Curl_tvdiff_us(now, data->progress.t_startsingle);
    time_t us = Curl_tvdiff_us(now, data->progress.t_startsingle);
    if(!us)
    if(!us)
      us++; /* make sure at least one microsecond passed */
      us++; /* make sure at least one microsecond passed */
    *delta = us;
    *delta += us;
  }
  }
}
}


@@ -230,6 +227,7 @@ void Curl_pgrsStartNow(struct Curl_easy *data)
{
{
  data->progress.speeder_c = 0; /* reset the progress meter display */
  data->progress.speeder_c = 0; /* reset the progress meter display */
  data->progress.start = Curl_tvnow();
  data->progress.start = Curl_tvnow();
  data->progress.is_t_startransfer_set = false;
  data->progress.ul_limit_start.tv_sec = 0;
  data->progress.ul_limit_start.tv_sec = 0;
  data->progress.ul_limit_start.tv_usec = 0;
  data->progress.ul_limit_start.tv_usec = 0;
  data->progress.dl_limit_start.tv_sec = 0;
  data->progress.dl_limit_start.tv_sec = 0;
+1 −1
Original line number Original line Diff line number Diff line
@@ -47,7 +47,7 @@ void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size);
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size);
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size);
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size);
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size);
int Curl_pgrsUpdate(struct connectdata *);
int Curl_pgrsUpdate(struct connectdata *);
void Curl_pgrsResetTimesSizes(struct Curl_easy *data);
void Curl_pgrsResetTransferSizes(struct Curl_easy *data);
void Curl_pgrsTime(struct Curl_easy *data, timerid timer);
void Curl_pgrsTime(struct Curl_easy *data, timerid timer);
long Curl_pgrsLimitWaitTime(curl_off_t cursize,
long Curl_pgrsLimitWaitTime(curl_off_t cursize,
                            curl_off_t startsize,
                            curl_off_t startsize,
+2 −2
Original line number Original line Diff line number Diff line
@@ -1345,7 +1345,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
#endif
#endif


    Curl_initinfo(data); /* reset session-specific information "variables" */
    Curl_initinfo(data); /* reset session-specific information "variables" */
    Curl_pgrsResetTimesSizes(data);
    Curl_pgrsResetTransferSizes(data);
    Curl_pgrsStartNow(data);
    Curl_pgrsStartNow(data);


    if(data->set.timeout)
    if(data->set.timeout)
@@ -1883,7 +1883,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
    break;
    break;
  }
  }
  Curl_pgrsTime(data, TIMER_REDIRECT);
  Curl_pgrsTime(data, TIMER_REDIRECT);
  Curl_pgrsResetTimesSizes(data);
  Curl_pgrsResetTransferSizes(data);


  return CURLE_OK;
  return CURLE_OK;
#endif /* CURL_DISABLE_HTTP */
#endif /* CURL_DISABLE_HTTP */
Loading