cURL

curl's project page on SourceForge.net

Sponsors:
Haxx

cURL > Mailing List > Monthly Index > Single Mail

curl-tracker Archives

[curl:bugs] #1213 Wrong STARTTRANSFER timer accounting for POST requests

From: Fabian Frank <fabian_stietzel_at_users.sf.net>
Date: Sun, 19 Jan 2014 21:49:46 +0000

I had a mini heart attack when I read this, because I actually rely on CURLINFO_STARTTRANSFER_TIME for POST uploads in production. I tried to reproduce this with my own mock server, which is also capable of sleeping first and only then sending any data. I can not confirm this bug.

**Example output for POST:**
~~~~~~
* STATE: INIT => CONNECT handle 0x7ffeb200cc08; line 1020 (connection #-5000)
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* STATE: CONNECT => WAITCONNECT handle 0x7ffeb200cc08; line 1067 (connection #0)
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
* STATE: WAITCONNECT => DO handle 0x7ffeb200cc08; line 1186 (connection #0)
> POST /sleep?t=1000 HTTP/1.1
Host: 127.0.0.1:8000
Accept: */*
Content-Length: 7
Content-Type: application/x-www-form-urlencoded

* upload completely sent off: 7 out of 7 bytes
* STATE: DO => DO_DONE handle 0x7ffeb200cc08; line 1272 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x7ffeb200cc08; line 1398 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x7ffeb200cc08; line 1411 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200 OK
< Content-Type: text/plain
< Date: Sun, 19 Jan 2014 21:41:03 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
finished sleeping
* STATE: PERFORM => DONE handle 0x7ffeb200cc08; line 1581 (connection #0)
* Connection #0 to host 127.0.0.1 left intact
URL: http://127.0.0.1:8000/sleep?t=1000
CURLINFO_TOTAL_TIME: 1.00283900
CURLINFO_CONNECT_TIME: 0.00086900
CURLINFO_PRETRANSFER_TIME: 0.00095600
**CURLINFO_STARTTRANSFER_TIME: 1.00263300**
~~~~~~

**Example output for GET:**
~~~~~~
* STATE: INIT => CONNECT handle 0x7f8b6400cc08; line 1020 (connection #-5000)
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* STATE: CONNECT => WAITCONNECT handle 0x7f8b6400cc08; line 1067 (connection #0)
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
* STATE: WAITCONNECT => DO handle 0x7f8b6400cc08; line 1186 (connection #0)
> GET /sleep?t=1000 HTTP/1.1
Host: 127.0.0.1:8000
Accept: */*

* STATE: DO => DO_DONE handle 0x7f8b6400cc08; line 1272 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x7f8b6400cc08; line 1398 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x7f8b6400cc08; line 1411 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200 OK
< Content-Type: text/plain
< Date: Sun, 19 Jan 2014 21:42:28 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
finished sleeping
* STATE: PERFORM => DONE handle 0x7f8b6400cc08; line 1581 (connection #0)
* Connection #0 to host 127.0.0.1 left intact
URL: http://127.0.0.1:8000/sleep?t=1000
CURLINFO_TOTAL_TIME: 1.00215800
CURLINFO_CONNECT_TIME: 0.00086800
CURLINFO_PRETRANSFER_TIME: 0.00095700
**CURLINFO_STARTTRANSFER_TIME: 1.00196000**
~~~~~~

In both cases the CURLINFO_STARTTRANSFER_TIME matches exactly the 1s sleep of the mock server.

---
** [bugs:#1213] Wrong STARTTRANSFER timer accounting for POST requests**
**Status:** closed-later
**Labels:** POST CURLINFO_STARTTRANSFER_TIME 
**Created:** Sat Apr 06, 2013 07:17 PM UTC by Mezon
**Last Updated:** Tue Nov 05, 2013 09:22 AM UTC
**Owner:** Daniel Stenberg
curl 7.28.1 (i686-pc-linux-gnu) libcurl/7.28.1 OpenSSL/0.9.8o zlib/1.2.3.4
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smtp smtps telnet tftp 
Features: IPv6 Largefile NTLM NTLM_WB SSL libz 
There is an error in timing accounting at least for STARTTRANSFER timer during POST requests.
Timer works fine with GET requests, but while using POST the time for CURLINFO_STARTTRANSFER_TIME is wrong. While using POST CURLINFO_STARTTRANSFER_TIME minus CURLINFO_PRETRANSFER_TIME is near to zero every time.
Proof of concept:
I've prepared CGI script that sleeps 3 seconds on start, before it returns any data.
While making curl GET request to the script, (CURLINFO_STARTTRANSFER_TIME - CURLINFO_PRETRANSFER_TIME) is ok [~ 3 seconds]. Trying the same thing with POST request, cause the 3 seconds appears in CURLINFO_TOTAL_TIME instead of CURLINFO_STARTTRANSFER_TIME. So with POST it looks like the transfer took 3 seconds instead of waiting for server reply.
IMHO the problem is in ./lib/transfer.c in readwrite_upload() function, where Curl_pgrsTime(data, TIMER_STARTTRANSFER) is called in wrong place. Unfortunately I'm not sure where to replace it to fix the bug. I think it should go somewhere in Curl_readwrite() function, for example here:
~~~~~~
/* We go ahead and do a read if we have a readable socket or if
     the stream was rewound (in which case we have data in a
     buffer) */
if((k->keepon & KEEP_RECV) &&
     ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
    result = readwrite_data(data, conn, k, &didwhat, done);
    if(result || *done)
      return result;
  }
  else {
      Curl_pgrsTime(data, TIMER_STARTTRANSFER); // <-- here
  }
~~~~~~
I'm not sure if any other timers are affected.
Best regards,
Mezon
---
Sent from sourceforge.net because curl-tracker@cool.haxx.se is subscribed to https://sourceforge.net/p/curl/bugs/
To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/curl/admin/bugs/options.  Or, if this is a mailing list, you can unsubscribe from the mailing list.
Received on 2014-01-19

These mail archives are generated by hypermail.

donate! Page updated December 29, 2013.
web site info

File upload with ASP.NET