vpeter

curl multi API HTTP/2 PING

Feb 28th, 2018
99
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. diff -aurNp '--exclude=bin' curl-7.58.0-orig/include/curl/curl.h curl-7.58.0/include/curl/curl.h
  2. --- curl-7.58.0-orig/include/curl/curl.h    2018-01-22 09:55:10.000000000 +0100
  3. +++ curl-7.58.0/include/curl/curl.h 2018-02-17 12:20:09.515491604 +0100
  4. @@ -1819,6 +1819,9 @@ typedef enum {
  5.    /* Post MIME data. */
  6.    CINIT(MIMEPOST, OBJECTPOINT, 269),
  7.  
  8. +  /* time between sending HTTP/2 PING request */
  9. +  CINIT(CONNUP_KEEPINTVL, LONG, 270),
  10. +
  11.    CURLOPT_LASTENTRY /* the last unused */
  12.  } CURLoption;
  13.  
  14. diff -aurNp '--exclude=bin' curl-7.58.0-orig/include/curl/easy.h curl-7.58.0/include/curl/easy.h
  15. --- curl-7.58.0-orig/include/curl/easy.h    2017-12-03 00:33:20.000000000 +0100
  16. +++ curl-7.58.0/include/curl/easy.h 2018-02-17 09:50:20.061622205 +0100
  17. @@ -29,6 +29,7 @@ CURL_EXTERN CURL *curl_easy_init(void);
  18.  CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
  19.  CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
  20.  CURL_EXTERN void curl_easy_cleanup(CURL *curl);
  21. +CURL_EXTERN CURLcode curl_easy_conn_upkeep(CURL *curl);
  22.  
  23.  /*
  24.   * NAME curl_easy_getinfo()
  25. diff -aurNp '--exclude=bin' curl-7.58.0-orig/include/curl/multi.h curl-7.58.0/include/curl/multi.h
  26. --- curl-7.58.0-orig/include/curl/multi.h   2017-12-03 00:33:21.000000000 +0100
  27. +++ curl-7.58.0/include/curl/multi.h    2018-02-17 11:39:12.872394487 +0100
  28. @@ -132,6 +132,15 @@ CURL_EXTERN CURLM *curl_multi_init(void)
  29.  CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
  30.                                              CURL *curl_handle);
  31.  
  32. +/*
  33. + * Name:    curl_multi_conn_upkeep()
  34. + *
  35. + * Desc:    keep all connections alive
  36. + *
  37. + * Returns: CURLMcode type, general multi error code.
  38. + */
  39. +CURL_EXTERN CURLMcode curl_multi_conn_upkeep(CURLM *multi_handle);
  40. +
  41.   /*
  42.    * Name:    curl_multi_remove_handle()
  43.    *
  44. diff -aurNp '--exclude=bin' curl-7.58.0-orig/lib/easy.c curl-7.58.0/lib/easy.c
  45. --- curl-7.58.0-orig/lib/easy.c 2018-01-22 09:55:10.000000000 +0100
  46. +++ curl-7.58.0/lib/easy.c  2018-02-17 11:31:11.481827134 +0100
  47. @@ -1177,3 +1177,22 @@ CURLcode curl_easy_send(struct Curl_easy
  48.  
  49.    return result;
  50.  }
  51. +
  52. +/*
  53. + * Performs connections keep functions.
  54. + */
  55. +CURLcode curl_easy_conn_upkeep(struct Curl_easy *data)
  56. +{
  57. +  /* Verify that we got a somewhat good easy handle too */
  58. +  if(!GOOD_EASY_HANDLE(data))
  59. +    return CURLM_BAD_EASY_HANDLE;
  60. +
  61. +  if(data->multi_easy) {
  62. +    /* Use the common function to keep connections alive. */
  63. +    return Curl_conn_upkeep(&data->multi_easy->conn_cache, data);
  64. +  }
  65. +  else {
  66. +    /* No connections, so just return success */
  67. +    return CURLE_OK;
  68. +  }
  69. +}
  70. diff -aurNp '--exclude=bin' curl-7.58.0-orig/lib/http2.c curl-7.58.0/lib/http2.c
  71. --- curl-7.58.0-orig/lib/http2.c    2018-01-22 09:55:10.000000000 +0100
  72. +++ curl-7.58.0/lib/http2.c 2018-02-17 11:54:57.144345445 +0100
  73. @@ -180,17 +180,48 @@ static bool http2_connisdead(struct conn
  74.    return ret_val;
  75.  }
  76.  
  77. -
  78.  static unsigned int http2_conncheck(struct connectdata *check,
  79.                                      unsigned int checks_to_perform)
  80.  {
  81.    unsigned int ret_val = CONNRESULT_NONE;
  82. +  struct http_conn *c = &check->proto.httpc;
  83. +  int rc;
  84. +  bool send_frames = false;
  85.  
  86.    if(checks_to_perform & CONNCHECK_ISDEAD) {
  87.      if(http2_connisdead(check))
  88.        ret_val |= CONNRESULT_DEAD;
  89.    }
  90.  
  91. +  if(checks_to_perform & CONNCHECK_KEEPALIVE) {
  92. +    struct curltime now = Curl_now();
  93. +    time_t elapsed = Curl_timediff(now, check->keepalive);
  94. +#if 0
  95. +    infof(check->data, "elapsed conn_up_keepintvl %6d %d\n",
  96. +          elapsed, check->conn_up_keepintvl);
  97. +#endif
  98. +    if(elapsed > check->conn_up_keepintvl) {
  99. +      /* Perform an HTTP/2 PING */
  100. +      rc = nghttp2_submit_ping(c->h2, 0, ZERO_NULL);
  101. +      if(!rc) {
  102. +        /* Successfully added a PING frame to the session. Need to flag this
  103. +           so the frame is sent. */
  104. +        send_frames = true;
  105. +      } else
  106. +       failf(check->data, "nghttp2_submit_ping() failed: %s(%d)",
  107. +              nghttp2_strerror(rc), rc);
  108. +
  109. +      check->keepalive = now;
  110. +    }
  111. +  }
  112. +
  113. +  if(send_frames) {
  114. +    rc = nghttp2_session_send(c->h2);
  115. +    if(rc)
  116. +      failf(check->data, "nghttp2_session_send() failed: %s(%d)",
  117. +            nghttp2_strerror(rc), rc);
  118. +  }
  119. +
  120.    return ret_val;
  121.  }
  122.  
  123. diff -aurNp '--exclude=bin' curl-7.58.0-orig/lib/multi.c curl-7.58.0/lib/multi.c
  124. --- curl-7.58.0-orig/lib/multi.c    2018-01-22 09:55:10.000000000 +0100
  125. +++ curl-7.58.0/lib/multi.c 2018-02-17 11:39:51.456579807 +0100
  126. @@ -620,6 +620,16 @@ static CURLcode multi_done(struct connec
  127.    return result;
  128.  }
  129.  
  130. +CURLMcode curl_multi_conn_upkeep(struct Curl_multi *multi)
  131. +{
  132. +  /* First, make some basic checks that the CURLM handle is a good handle */
  133. +  if(!GOOD_MULTI_HANDLE(multi))
  134. +    return CURLM_BAD_HANDLE;
  135. +
  136. +  /* Use the common function to keep connections alive. */
  137. +   return Curl_conn_upkeep(&multi->conn_cache, multi);
  138. +}
  139. +
  140.  CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
  141.                                     struct Curl_easy *data)
  142.  {
  143. diff -aurNp '--exclude=bin' curl-7.58.0-orig/lib/setopt.c curl-7.58.0/lib/setopt.c
  144. --- curl-7.58.0-orig/lib/setopt.c   2018-01-22 10:02:06.000000000 +0100
  145. +++ curl-7.58.0/lib/setopt.c    2018-02-17 12:20:06.072088428 +0100
  146. @@ -2524,6 +2524,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *
  147.    case CURLOPT_SSH_COMPRESSION:
  148.      data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE;
  149.      break;
  150. +  case CURLOPT_CONNUP_KEEPINTVL:
  151. +    data->set.conn_up_keepintvl = va_arg(param, long) * 1000;
  152. +    break;
  153.    default:
  154.      /* unknown tag and its companion, just ignore: */
  155.      result = CURLE_UNKNOWN_OPTION;
  156. diff -aurNp '--exclude=bin' curl-7.58.0-orig/lib/url.c curl-7.58.0/lib/url.c
  157. --- curl-7.58.0-orig/lib/url.c  2018-01-23 08:55:37.000000000 +0100
  158. +++ curl-7.58.0/lib/url.c   2018-02-17 11:54:49.856754734 +0100
  159. @@ -528,6 +528,8 @@ CURLcode Curl_init_userdefined(struct Cu
  160.    set->sep_headers = TRUE; /* separated header lists by default */
  161.    set->buffer_size = READBUFFER_SIZE;
  162.  
  163. +  set->conn_up_keepintvl = 60000L; /* default time is 60 seconds */
  164. +  
  165.    Curl_http2_init_userset(set);
  166.    return result;
  167.  }
  168. @@ -1829,6 +1831,9 @@ static struct connectdata *allocate_conn
  169.    /* Store creation time to help future close decision making */
  170.    conn->created = Curl_now();
  171.  
  172. +  /* Store current time to give a baseline to keepalive connection times. */
  173. +  conn->keepalive = Curl_now();
  174. +
  175.    conn->data = data; /* Setup the association between this connection
  176.                          and the Curl_easy */
  177.  
  178. @@ -1920,6 +1925,8 @@ static struct connectdata *allocate_conn
  179.    conn->fclosesocket = data->set.fclosesocket;
  180.    conn->closesocket_client = data->set.closesocket_client;
  181.  
  182. +  conn->conn_up_keepintvl = data->set.conn_up_keepintvl;
  183. +
  184.    return conn;
  185.    error:
  186.  
  187. @@ -4848,3 +4855,30 @@ static unsigned int get_protocol_family(
  188.  
  189.    return family;
  190.  }
  191. +
  192. +/*
  193. + * Wrapper to call functions in Curl_conncache_foreach()
  194. + *
  195. + * Returns always 0.
  196. + */
  197. +static int conn_upkeep(struct connectdata *conn,
  198. +                       void *param)
  199. +{
  200. +  if(conn->handler->connection_check) {
  201. +    /* Do a protocol-specific keepalive check on the connection. */
  202. +    conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE);
  203. +  }
  204. +
  205. +  return 0; /* continue iteration */
  206. +}
  207. +
  208. +CURLcode Curl_conn_upkeep(struct conncache *conn_cache,
  209. +                          void *data)
  210. +{
  211. +  /* Loop over every connection and make connection alive. */
  212. +  Curl_conncache_foreach(data,
  213. +                         conn_cache,
  214. +                         data,
  215. +                         conn_upkeep);
  216. +  return CURLE_OK;
  217. +}
  218. \ No newline at end of file
  219. diff -aurNp '--exclude=bin' curl-7.58.0-orig/lib/url.h curl-7.58.0/lib/url.h
  220. --- curl-7.58.0-orig/lib/url.h  2018-01-22 09:55:10.000000000 +0100
  221. +++ curl-7.58.0/lib/url.h   2018-02-17 09:50:07.192735072 +0100
  222. @@ -92,4 +92,7 @@ void Curl_verboseconnect(struct connectd
  223.    (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
  224.    !conn->bits.proxy_ssl_connected[SECONDARYSOCKET])
  225.  
  226. +CURLcode Curl_conn_upkeep(struct conncache *conn_cache,
  227. +                          void *data);
  228. +
  229.  #endif /* HEADER_CURL_URL_H */
  230. diff -aurNp '--exclude=bin' curl-7.58.0-orig/lib/urldata.h curl-7.58.0/lib/urldata.h
  231. --- curl-7.58.0-orig/lib/urldata.h  2018-01-22 10:02:06.000000000 +0100
  232. +++ curl-7.58.0/lib/urldata.h   2018-02-17 11:54:39.698909137 +0100
  233. @@ -699,6 +699,7 @@ struct Curl_handler {
  234.  
  235.  #define CONNCHECK_NONE 0                 /* No checks */
  236.  #define CONNCHECK_ISDEAD (1<<0)          /* Check if the connection is dead. */
  237. +#define CONNCHECK_KEEPALIVE (1<<1)       /* Perform any keepalive function. */
  238.  
  239.  #define CONNRESULT_NONE 0                /* No extra information. */
  240.  #define CONNRESULT_DEAD (1<<0)           /* The connection is dead. */
  241. @@ -888,6 +889,11 @@ struct connectdata {
  242.  
  243.    long ip_version; /* copied from the Curl_easy at creation time */
  244.  
  245. +  /* Protocols can use a custom keepalive mechanism to keep connections alive.
  246. +     This allows those protocols to track the last time the keepalive mechanism
  247. +     was used on this connection. */
  248. +  struct curltime keepalive;
  249. +
  250.    /**** curl_get() phase fields */
  251.  
  252.    curl_socket_t sockfd;   /* socket to read from or CURL_SOCKET_BAD */
  253. @@ -1012,6 +1018,8 @@ struct connectdata {
  254.    char *unix_domain_socket;
  255.    bool abstract_unix_socket;
  256.  #endif
  257. +
  258. +  time_t conn_up_keepintvl; /* time between sending HTTP/2 PING request */
  259.  };
  260.  
  261.  /* The end of connectdata. */
  262. @@ -1682,6 +1690,8 @@ struct UserDefined {
  263.    struct Curl_http2_dep *stream_dependents;
  264.  
  265.    bool abstract_unix_socket;
  266. +  
  267. +  time_t conn_up_keepintvl; /* time between sending HTTP/2 PING request */
  268.  };
  269.  
  270.  struct Names {
RAW Paste Data