Skip to content
Browse files

Add -T command line option that tells curl to set a timeout on the co…

…nnection (through CURLOPT_TIMEOUT). Also, always try to set SO_KEEPALIVE on curl sockets, but don't worry if it fails.
  • Loading branch information...
1 parent c626bfd commit 7ecec0126c7f81e688246c460959b81c573b1506 merlino committed with
Showing with 48 additions and 1 deletion.
  1. +14 −1 c/client.c
  2. +3 −0 c/doc/zsync.1
  3. +30 −0 c/http.c
  4. +1 −0 c/http.h
View
15 c/client.c
@@ -434,7 +434,7 @@ int main(int argc, char **argv) {
srand(getpid());
{ /* Option parsing */
int opt;
- while ((opt = getopt(argc, argv, "A:k:o:i:Vsqvu:C:K")) != -1) {
+ while ((opt = getopt(argc, argv, "A:k:o:i:Vsqvu:C:KT:")) != -1) {
switch (opt) {
case 'A': /* Authentication options for remote server */
{ /* Scan string as hostname=username:password */
@@ -494,6 +494,19 @@ int main(int argc, char **argv) {
/* Insecure (disable SSL host/peer verification) */
be_insecure = 1;
break;
+ case 'T':
+ /* Timeout */
+ {
+ char *endptr = NULL;
+ errno = 0;
+ use_timeout = strtol( optarg, &endptr, 10 );
+ if( errno || *endptr != 0 || use_timeout < 0 ) {
+ /* Unable to convert, garbage at the end of the string, or number was negative */
+ fprintf( stderr, "Timeout (-T): Invalid number `%s'\n", optarg );
+ exit(1);
+ }
+ }
+ break;
}
}
}
View
3 c/doc/zsync.1
@@ -57,6 +57,9 @@ Use the specified certificate file to verify the peer when making https connecti
.TP
\fB\-K\fR
Do not perform peer verification when making https connections.
+.TP
+\fB\-T\fR \fItimeout\fP
+Timeout, in seconds, per HTTP transfer. Note that zsync may make multiple HTTP transfers over the course of one run. If this option is omitted, no timeout will be set.
.TP
\fB\-v\fR
Send HTTP debugging information to stderr, including request and response headers.
View
30 c/http.c
@@ -63,6 +63,12 @@ int be_insecure = 0;
/* Should we tell curl to be verbose? */
int be_verbose = 0;
+/* Should we tell curl to set a timeout? */
+long use_timeout = 0;
+
+/* Declare up here so we can use it in make_curl_handle */
+int range_fetch_sockoptcallback( void *clientp, curl_socket_t curlfd, curlsocktype purpose );
+
/* add_auth(host, user, pass)
* Specify user & password combination to use connecting to the given host.
*/
@@ -102,6 +108,9 @@ CURL *make_curl_handle() {
/* Set a User-Agent string */
curl_easy_setopt( curl, CURLOPT_USERAGENT, "zsync/" VERSION );
+ /* Turn on SO_KEEPALIVE */
+ curl_easy_setopt( curl, CURLOPT_SOCKOPTFUNCTION, range_fetch_sockoptcallback );
+
/* Command line options */
if(be_verbose) {
@@ -125,6 +134,11 @@ CURL *make_curl_handle() {
curl_easy_setopt( curl, CURLOPT_SSL_VERIFYHOST, 0 );
}
+ if(use_timeout) {
+ /* -T */
+ curl_easy_setopt( curl, CURLOPT_TIMEOUT, use_timeout );
+ }
+
return curl;
}
@@ -318,6 +332,22 @@ int range_fetch_expect( struct range_fetch *rf, off_t from, off_t to ) {
return 0;
}
+/* Curl SOCKOPTFUNCTION. Sets SO_KEEPALIVE on the socket. */
+int range_fetch_sockoptcallback( void *clientp, curl_socket_t curlfd, curlsocktype purpose ) {
+
+ /* CURLSOCKTYPE_IPCXN is the primary connection */
+ if( purpose == CURLSOCKTYPE_IPCXN ) {
+ int optval = 1;
+ if( setsockopt(curlfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, sizeof(optval) ) ) {
+ /* setsockopt failed. continue anyway. */
+ perror("setsockopt");
+ }
+ }
+
+ /* Returns 0 on success */
+ return 0;
+}
+
/* Curl HEADERFUNCTION. Gets headers one-by-one (including the HTTP status line) plus a range_fetch struct. */
size_t range_fetch_read_http_headers( void *ptr, size_t size, size_t nmemb, void *userdata ) {
struct range_fetch *rf = (struct range_fetch *)userdata;
View
1 c/http.h
@@ -22,6 +22,7 @@ extern char *referer;
extern char *cacert;
extern int be_insecure;
extern int be_verbose;
+extern long use_timeout;
FILE* http_get(const char *orig_url, char **track_referer, const char *tfname);

0 comments on commit 7ecec01

Please sign in to comment.
Something went wrong with that request. Please try again.