Hi,As we discussed a little while ago, we could provide a curl_easy_getinfo() option that provides the current state of the transfer the easy handle identifies. This is meant to work fine to extract really at any point during a transfer. Either from a callback when the easy interface is used, or wherever when the multi interface is used.
I've made a first go at that, see attachment. I'll be happy to all and any feedback, praises or criticism of anything in the patch. Give me your thoughts!
-- / daniel.haxx.se
From ec12a85981246cd2d76b7095b54c403d680ba3ca Mon Sep 17 00:00:00 2001 From: Daniel Stenberg <[email protected]> Date: Thu, 1 Aug 2013 18:19:41 +0200 Subject: [PATCH] CURLINFO_XFER_STATE: export the state of a transfer --- docs/libcurl/curl_easy_getinfo.3 | 35 +++++++++++++++++++++++- include/curl/curl.h | 19 ++++++++++++- lib/multi.c | 59 ++++++++++++++++++++++++++++++++++++++++ lib/multiif.h | 2 ++ 4 files changed, 113 insertions(+), 2 deletions(-) diff --git a/docs/libcurl/curl_easy_getinfo.3 b/docs/libcurl/curl_easy_getinfo.3 index 62d8ae4..bc2e07a 100644 --- a/docs/libcurl/curl_easy_getinfo.3 +++ b/docs/libcurl/curl_easy_getinfo.3 @@ -5,7 +5,7 @@ .\" * | (__| |_| | _ <| |___ .\" * \___|\___/|_| \_\_____| .\" * -.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <[email protected]>, et al. +.\" * Copyright (C) 1998 - 2013, Daniel Stenberg, <[email protected]>, et al. .\" * .\" * This software is licensed as described in the file COPYING, which .\" * you should have received as part of this distribution. The terms @@ -249,6 +249,39 @@ retrieve this info before closing the active connection. Pass a pointer to a long to receive the most recently received CSeq from the server. If your application encounters a \fICURLE_RTSP_CSEQ_ERROR\fP then you may wish to troubleshoot and/or fix the CSeq mismatch by peeking at this value. +.IP CURLINFO_XFER_STATE +Pass a pointer to a long to receive the current state of the transfer of the +given easy handle. + +The currently available states are: +.RS +.IP "CURLXFER_INIT (0)" +Nothing really happened yet +.IP "CURLXFER_NAMERES (1)" +Name resolving +.IP "CURLXFER_CONNECT (2)" +TCP (or similar) connect +.IP "CURLXFER_PROTOCONNECT (3)" +Protocol specific connect +.IP "CURLXFER_PROXYCONNECT (4)" +HTTP proxy CONNECT procedure +.IP "CURLXFER_WAITDO (5)" +Waiting to issue request +.IP "CURLXFER_DO (6)" +Issuing request +.IP "CURLXFER_TRANSFER (7)" +Transfer +.IP "CURLXFER_TOOFAST (8)" +Switched to due to rate limiting, basically a variation of CURLXFER_TRANSFER. +.IP "CURLXFER_DONE (9)" +Transfer complete +.RE + +Not all transfers will use all states. States may not be changed to in a +numerical order. In some cases a transfer can go back to a previously already +visited state. We may introduce new states in the future + +(Added in 7.33.0) .SH TIMES .nf An overview of the six time values available from curl_easy_getinfo() diff --git a/include/curl/curl.h b/include/curl/curl.h index 41c0881..f02446d 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -1961,6 +1961,22 @@ struct curl_certinfo { format "name: value" */ }; +/* The XFER_STATE option returns state about the particular transfer. Not all + transfers will use all states. States may not be changed to in a numerical + order. In some cases a transfer can go back to a previously already visited + state. We may introduce new states in the future. */ +#define CURLXFER_INIT 0 /* nothing really happened yet */ +#define CURLXFER_NAMERES 1 /* name resolving */ +#define CURLXFER_CONNECT 2 /* TCP (or similar) connect */ +#define CURLXFER_PROTOCONNECT 3 /* protocol specific connect oriented ops */ +#define CURLXFER_PROXYCONNECT 4 /* proxy CONNECT procedure */ +#define CURLXFER_WAITDO 5 /* waiting to issue request */ +#define CURLXFER_DO 6 /* issuing request */ +#define CURLXFER_TRANSFER 7 /* transfer */ +#define CURLXFER_TOOFAST 8 /* toggled transfer due to rate limiting, + basically a variation of *TRANSFER */ +#define CURLXFER_DONE 9 /* transfer complete */ + #define CURLINFO_STRING 0x100000 #define CURLINFO_LONG 0x200000 #define CURLINFO_DOUBLE 0x300000 @@ -2012,9 +2028,10 @@ typedef enum { CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_XFER_STATE = CURLINFO_LONG + 43, /* Fill in new entries below here! */ - CURLINFO_LASTONE = 42 + CURLINFO_LASTONE = 43 } CURLINFO; /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as diff --git a/lib/multi.c b/lib/multi.c index 774e808..7a79bd8 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -2732,3 +2732,62 @@ void Curl_multi_dump(const struct Curl_multi *multi_handle) } } #endif + +/* + * Return the external version of the internal state for this + * connection/handle. + * + * The external version is part of the fixed API and must never change even if + * new states MAY be introduced if absolutely necessary. + */ +CURLcode Curl_multi_easy_state(struct SessionHandle *data, long *valuep) +{ + long ext_state = CURLXFER_INIT; + if(data && data->multi) { + switch(data->mstate) { + case CURLM_STATE_INIT: + break; + case CURLM_STATE_CONNECT_PEND: + case CURLM_STATE_CONNECT: + case CURLM_STATE_WAITCONNECT: + ext_state = CURLXFER_CONNECT; + break; + case CURLM_STATE_WAITRESOLVE: + ext_state = CURLXFER_NAMERES; + break; + case CURLM_STATE_WAITPROXYCONNECT: + ext_state = CURLXFER_PROXYCONNECT; + break; + case CURLM_STATE_PROTOCONNECT: + ext_state = CURLXFER_PROTOCONNECT; + break; + case CURLM_STATE_WAITDO: + ext_state = CURLXFER_WAITDO; + break; + case CURLM_STATE_DO: + case CURLM_STATE_DOING: + case CURLM_STATE_DO_MORE: + case CURLM_STATE_DO_DONE: + ext_state = CURLXFER_DO; + break; + case CURLM_STATE_WAITPERFORM: + case CURLM_STATE_PERFORM: + ext_state = CURLXFER_TRANSFER; + break; + case CURLM_STATE_TOOFAST: + ext_state = CURLXFER_TOOFAST; + break; + case CURLM_STATE_DONE: + case CURLM_STATE_COMPLETED: + case CURLM_STATE_MSGSENT: + case CURLM_STATE_LAST: + ext_state = CURLXFER_DONE; + break; + } + if(valuep) + *valuep = ext_state; + } + else + return CURLE_BAD_FUNCTION_ARGUMENT; + return CURLE_OK; +} diff --git a/lib/multiif.h b/lib/multiif.h index d1b0e2f..fcdd15d 100644 --- a/lib/multiif.h +++ b/lib/multiif.h @@ -95,4 +95,6 @@ size_t Curl_multi_max_total_connections(struct Curl_multi *multi); void Curl_multi_closed(struct connectdata *conn, curl_socket_t s); +CURLcode Curl_multi_easy_state(struct SessionHandle *data, long *valuep); + #endif /* HEADER_CURL_MULTIIF_H */ -- 1.8.4.rc0
------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-library Etiquette: http://curl.haxx.se/mail/etiquette.html
