MINOR: cache: Add Expires header value parsing

When no Cache-Control max-age or s-maxage information is present in a
cached response, we need to parse the Expires header value (RFC 7234#5.3).
An invalid Expires date value or a date earlier than the reception date
will make the cache_entry stale upon creation.
For now, the Cache-Control and Expires headers are parsed after the
insertion of the response in the cache so even if the parsing of the
Expires results in an already stale entry, the entry will exist in the
cache.
diff --git a/src/cache.c b/src/cache.c
index 2c37ca1..a73f266 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -482,6 +482,9 @@
 	struct http_hdr_ctx ctx = { .blk = NULL };
 	int smaxage = -1;
 	int maxage = -1;
+	int expires = -1;
+	struct tm tm = {};
+	time_t expires_val = 0;
 
 	while (http_find_header(htx, ist("cache-control"), &ctx, 0)) {
 		char *value;
@@ -505,7 +508,28 @@
 		}
 	}
 
-	/* TODO: Expires - Data */
+	/* Look for Expires header if no s-maxage or max-age Cache-Control data
+	 * was found. */
+	if (maxage == -1 && smaxage == -1) {
+		ctx.blk = NULL;
+		if (http_find_header(htx, ist("expires"), &ctx, 1)) {
+			if (parse_http_date(istptr(ctx.value), istlen(ctx.value), &tm)) {
+				expires_val = my_timegm(&tm);
+				/* A request having an expiring date earlier
+				 * than the current date should be considered as
+				 * stale. */
+				expires = (expires_val >= now.tv_sec) ?
+					(expires_val - now.tv_sec) : 0;
+			}
+			else {
+				/* Following RFC 7234#5.3, an invalid date
+				 * format must be treated as a date in the past
+				 * so the cache entry must be seen as already
+				 * expired. */
+				expires = 0;
+			}
+		}
+	}
 
 
 	if (smaxage > 0)
@@ -514,6 +538,9 @@
 	if (maxage > 0)
 		return MIN(maxage, cache->maxage);
 
+	if (expires >= 0)
+		return MIN(expires, cache->maxage);
+
 	return cache->maxage;
 
 }