summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/fetch.h1
-rw-r--r--content/fetchers/curl.c16
-rw-r--r--content/llcache.c19
-rw-r--r--content/llcache.h3
4 files changed, 35 insertions, 4 deletions
diff --git a/content/fetch.h b/content/fetch.h
index 529a800fa..3c1f1ccae 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -37,6 +37,7 @@ typedef enum {
FETCH_HEADER,
FETCH_DATA,
FETCH_FINISHED,
+ FETCH_TIMEDOUT,
FETCH_ERROR,
FETCH_REDIRECT,
FETCH_NOTMODIFIED,
diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c
index a2c6f2eb4..624cdbf41 100644
--- a/content/fetchers/curl.c
+++ b/content/fetchers/curl.c
@@ -973,11 +973,19 @@ static void fetch_curl_done(CURL *curl_handle, CURLcode result)
msg.data.cert_err.num_certs = i;
fetch_send_callback(&msg, f->fetch_handle);
} else if (error) {
- if (result != CURLE_SSL_CONNECT_ERROR) {
+ switch (result) {
+ case CURLE_SSL_CONNECT_ERROR:
+ msg.type = FETCH_SSL_ERR;
+ break;
+
+ case CURLE_OPERATION_TIMEDOUT:
+ msg.type = FETCH_TIMEDOUT;
+ msg.data.error = curl_easy_strerror(result);
+ break;
+
+ default:
msg.type = FETCH_ERROR;
msg.data.error = curl_easy_strerror(result);
- } else {
- msg.type = FETCH_SSL_ERR;
}
fetch_send_callback(&msg, f->fetch_handle);
@@ -1302,7 +1310,7 @@ nserror fetch_curl_register(void)
SETOPT(CURLOPT_LOW_SPEED_LIMIT, 1L);
SETOPT(CURLOPT_LOW_SPEED_TIME, 180L);
SETOPT(CURLOPT_NOSIGNAL, 1L);
- SETOPT(CURLOPT_CONNECTTIMEOUT, 30L);
+ SETOPT(CURLOPT_CONNECTTIMEOUT, nsoption_uint(curl_fetch_timeout));
if (nsoption_charp(ca_bundle) &&
strcmp(nsoption_charp(ca_bundle), "")) {
diff --git a/content/llcache.c b/content/llcache.c
index 851dbbb5f..e95eefbe6 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -120,6 +120,8 @@ typedef struct {
uint32_t redirect_count; /**< Count of redirects followed */
+ uint32_t retries_remaining; /**< Number of times to retry on timeout */
+
bool tried_with_auth; /**< Whether we've tried with auth */
bool tried_with_tls_downgrade; /**< Whether we've tried TLS <= 1.0 */
@@ -227,6 +229,9 @@ struct llcache_s {
/** The target upper bound for the RAM cache size */
uint32_t limit;
+ /** The number of fetch attempts we make when timing out */
+ uint32_t fetch_attempts;
+
/** Whether or not our users are caught up */
bool all_caught_up;
@@ -909,6 +914,7 @@ static nserror llcache_object_fetch(llcache_object *object, uint32_t flags,
object->fetch.referer = referer_clone;
object->fetch.post = post_clone;
object->fetch.redirect_count = redirect_count;
+ object->fetch.retries_remaining = llcache->fetch_attempts;
return llcache_object_refetch(object);
}
@@ -2653,6 +2659,18 @@ static void llcache_fetch_callback(const fetch_msg *msg, void *p)
break;
/* Out-of-band information */
+ case FETCH_TIMEDOUT:
+ /* Timed out while trying to fetch. */
+ /* The fetch has already been cleaned up by the fetcher but
+ * we would like to retry if we can. */
+ if (object->fetch.retries_remaining > 1) {
+ object->fetch.retries_remaining--;
+ error = llcache_object_refetch(object);
+ break;
+ }
+ /* Otherwise fall through to error, setting the message to
+ * a timeout
+ */
case FETCH_ERROR:
/* An error occurred while fetching */
/* The fetch has has already been cleaned up by the fetcher */
@@ -3303,6 +3321,7 @@ llcache_initialise(const struct llcache_parameters *prm)
llcache->minimum_bandwidth = prm->minimum_bandwidth;
llcache->maximum_bandwidth = prm->maximum_bandwidth;
llcache->time_quantum = prm->time_quantum;
+ llcache->fetch_attempts = prm->fetch_attempts;
llcache->all_caught_up = true;
LOG("llcache initialising with a limit of %d bytes", llcache->limit);
diff --git a/content/llcache.h b/content/llcache.h
index 1b7ba7dae..cce9a79bf 100644
--- a/content/llcache.h
+++ b/content/llcache.h
@@ -230,6 +230,9 @@ struct llcache_parameters {
*/
unsigned long time_quantum;
+ /** The number of fetches to attempt when timing out */
+ uint32_t fetch_attempts;
+
struct llcache_store_parameters store;
};