MINOR: http: Add etag comparison function

Add a function that compares two etags that might be of different types.
If any of them is weak, the 'W/' prefix is discarded and a strict string
comparison is performed.

Co-authored-by: Tim Duesterhus <tim@bastelstu.be>
diff --git a/include/haproxy/http.h b/include/haproxy/http.h
index a84f6db..fb47abd 100644
--- a/include/haproxy/http.h
+++ b/include/haproxy/http.h
@@ -57,6 +57,8 @@
 int http_parse_stline(const struct ist line, struct ist *p1, struct ist *p2, struct ist *p3);
 int http_parse_status_val(const struct ist value, struct ist *status, struct ist *reason);
 
+int http_compare_etags(struct ist etag1, struct ist etag2);
+
 /*
  * Given a path string and its length, find the position of beginning of the
  * query string. Returns NULL if no query string is found in the path.
diff --git a/src/http.c b/src/http.c
index 4b1b9cd..bb99c50 100644
--- a/src/http.c
+++ b/src/http.c
@@ -1047,3 +1047,29 @@
 	code = strl2ui(status->ptr, status->len);
 	return code;
 }
+
+
+/* Returns non-zero if the two ETags are comparable (see RFC 7232#2.3.2).
+ * If any of them is a weak ETag, we discard the weakness prefix and perform
+ * a strict string comparison.
+ * Returns 0 otherwise.
+ */
+int http_compare_etags(struct ist etag1, struct ist etag2)
+{
+	enum http_etag_type etag_type1;
+	enum http_etag_type etag_type2;
+
+	etag_type1 = http_get_etag_type(etag1);
+	etag_type2 = http_get_etag_type(etag2);
+
+	if (etag_type1 == ETAG_INVALID || etag_type2 == ETAG_INVALID)
+		return 0;
+
+	/* Discard the 'W/' prefix an ETag is a weak one. */
+	if (etag_type1 == ETAG_WEAK)
+		etag1 = istadv(etag1, 2);
+	if (etag_type2 == ETAG_WEAK)
+		etag2 = istadv(etag2, 2);
+
+	return isteq(etag1, etag2);
+}