From f8f040e6596fa22b68198adf42dc6adcedfa57f0 Mon Sep 17 00:00:00 2001 From: Ryan Winograd Date: Mon, 26 Jun 2017 11:51:05 -0500 Subject: progress: prevent resetting t_starttransfer Prevent `Curl_pgrsTime` from modifying `t_starttransfer` when invoked with `TIMER_STARTTRANSFER` more than once during a single request. When a redirect occurs, this is considered a new request and `t_starttransfer` can be updated to reflect the `t_starttransfer` time of the redirect request. Closes #1616 Bug: https://github.com/curl/curl/pull/1602#issuecomment-310267370 --- tests/unit/unit1399.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 tests/unit/unit1399.c (limited to 'tests/unit/unit1399.c') diff --git a/tests/unit/unit1399.c b/tests/unit/unit1399.c new file mode 100644 index 000000000..1befc8aaf --- /dev/null +++ b/tests/unit/unit1399.c @@ -0,0 +1,96 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curlcheck.h" + +#include "urldata.h" +#include "progress.h" + +static int usec_magnitude = 1000000; + +static bool unit_setup(void) +{ + return CURLE_OK; +} + +static void unit_stop(void) +{ + +} + +static bool usec_matches_seconds(time_t time_usec, int expected_seconds) +{ + int time_sec = (int)(time_usec / usec_magnitude); + return time_sec == expected_seconds; +} + +UNITTEST_START + struct Curl_easy data; + struct timeval now = Curl_tvnow(); + + data.progress.t_starttransfer = 0; + data.progress.t_redirect = 0; + + /* + * Set the startsingle time to a second ago. This time is used by + * Curl_pgrsTime to calculate how much time the events takes. + * t_starttransfer should be updated to reflect the difference from this time + * when `Curl_pgrsTime is invoked. + */ + data.progress.t_startsingle.tv_sec = now.tv_sec - 1; + data.progress.t_startsingle.tv_usec = now.tv_usec; + + Curl_pgrsTime(&data, TIMER_STARTTRANSFER); + + fail_unless(usec_matches_seconds(data.progress.t_starttransfer, 1), + "about 1 second should have passed"); + + /* + * Update the startsingle time to a second ago to simulate another second has + * passed. + * Now t_starttransfer should not be changed, as t_starttransfer has already + * occurred and another invocation of `Curl_pgrsTime` for TIMER_STARTTRANSFER + * is superfluous. + */ + data.progress.t_startsingle.tv_sec = now.tv_sec - 2; + data.progress.t_startsingle.tv_usec = now.tv_usec; + + Curl_pgrsTime(&data, TIMER_STARTTRANSFER); + + fail_unless(usec_matches_seconds(data.progress.t_starttransfer, 1), + "about 1 second should have passed"); + + /* + * Simulate what happens after a redirect has occurred. + * + * Since the value of t_starttransfer is set to the value from the first + * request, it should be updated when a transfer occurs such that + * t_starttransfer is the starttransfer time of the redirect request. + */ + data.progress.t_startsingle.tv_sec = now.tv_sec - 3; + data.progress.t_startsingle.tv_usec = now.tv_usec; + data.progress.t_redirect = (now.tv_sec - 2) * usec_magnitude; + + Curl_pgrsTime(&data, TIMER_STARTTRANSFER); + + fail_unless(usec_matches_seconds(data.progress.t_starttransfer, 3), + "about 3 second should have passed"); +UNITTEST_STOP -- cgit v1.2.3