--- a/bin/varnishd/http2/cache_http2_hpack.c
+++ b/bin/varnishd/http2/cache_http2_hpack.c
@@ -171,7 +171,7 @@ h2h_addhdr(struct http *hp, struct h2h_d
 
 	/* Match H/2 pseudo headers */
 	/* XXX: Should probably have some include tbl for pseudo-headers */
-	if (!Tstrcmp(nm, ":method")) {
+	if (Tstreq(nm, ":method")) {
 		hdr.b = val.b;
 		n = HTTP_HDR_METHOD;
 		disallow_empty = 1;
@@ -181,13 +181,13 @@ h2h_addhdr(struct http *hp, struct h2h_d
 			if (!vct_istchar(*p))
 				return (H2SE_PROTOCOL_ERROR);
 		}
-	} else if (!Tstrcmp(nm, ":path")) {
+	} else if (Tstreq(nm, ":path")) {
 		hdr.b = val.b;
 		n = HTTP_HDR_URL;
 		disallow_empty = 1;
 
 		// rfc9113,l,2693,2705
-		if (Tlen(val) > 0 && val.b[0] != '/' && Tstrcmp(val, "*")) {
+		if (Tlen(val) > 0 && val.b[0] != '/' && !Tstreq(val, "*")) {
 			VSLb(hp->vsl, SLT_BogoHeader,
 			    "Illegal :path pseudo-header %.*s",
 			    (int)Tlen(val), val.b);
@@ -199,7 +199,7 @@ h2h_addhdr(struct http *hp, struct h2h_d
 			if (vct_islws(*p) || vct_isctl(*p))
 				return (H2SE_PROTOCOL_ERROR);
 		}
-	} else if (!Tstrcmp(nm, ":scheme")) {
+	} else if (Tstreq(nm, ":scheme")) {
 		/* XXX: What to do about this one? (typically
 		   "http" or "https"). For now set it as a normal
 		   header, stripping the first ':'. */
@@ -213,7 +213,7 @@ h2h_addhdr(struct http *hp, struct h2h_d
 			if (!vct_istchar(*p))
 				return (H2SE_PROTOCOL_ERROR);
 		}
-	} else if (!Tstrcmp(nm, ":authority")) {
+	} else if (Tstreq(nm, ":authority")) {
 		/* NB: we inject "host" in place of "rity" for
 		 * the ":authority" pseudo-header.
 		 */
--- a/include/vdef.h
+++ b/include/vdef.h
@@ -276,9 +276,25 @@ typedef struct {
 #define Tcheck(t)	do { (void)pdiff((t).b, (t).e); } while (0)
 #define Tlen(t)		(pdiff((t).b, (t).e))
 #define Tstr(s)		(/*lint -e(446)*/ (txt){(s), (s) + strlen(s)})
-#define Tstrcmp(t, s)	(strncmp((t).b, (s), Tlen(t)))
+#define Tstreq(t, s)	(Tlen(t) == strlen(s) && !vmemcmp((t).b, (s), Tlen(t)))
 #define Tforeach(c, t)	for ((c) = (t).b; (c) < (t).e; (c)++)
 
 /* #3020 dummy definitions until PR is merged*/
 #define LIKELY(x)	(x)
 #define UNLIKELY(x)	(x)
+
+/**********************************************************************
+ * various optinal built-ins
+ *
+ * https://clang.llvm.org/docs/LanguageExtensions.html#builtin-functions
+ *
+ */
+#ifndef __has_builtin
+#  define __has_builtin(x) 0
+#endif
+
+#if __has_builtin(__builtin_memcmp)
+#  define vmemcmp(s1, s2, n) __builtin_memcmp(s1, s2, n)
+#else
+#  define vmemcmp(s1, s2, n) memcmp(s1, s2, n)
+#endif
--- a/bin/varnishtest/tests/h00007.vtc
+++ b/bin/varnishtest/tests/h00007.vtc
@@ -9,6 +9,7 @@ feature cmd {haproxy --version 2>&1 | gr
 server s1 {
     rxreq
     txresp -body "s1 >>> Hello world!"
+    shutdown
 } -start
 
 varnish v1 -proto "PROXY" -vcl+backend {} -start
@@ -28,7 +29,7 @@ haproxy h1 -D -conf {
 varnish v1 -vcl+backend {
 	import std;
 
-	acl localhost {
+	acl localhost -fold {
 		"localhost";
 		"127.0.0.1";
 		"::1";
@@ -58,3 +59,7 @@ client c1 -connect ${h1_fe1_sock} {
     expect resp.http.notstdip == false
     expect resp.body == "s1 >>> Hello world!"
 } -run
+
+varnish v1 -vsl_catchup
+
+haproxy h1 -wait
--- /dev/null
+++ b/bin/varnishtest/tests/f00019.vtc
@@ -0,0 +1,31 @@
+vtest "Verify pseudo-header parsing"
+
+varnish v1 -cliok "param.set feature +http2"
+varnish v1 -vcl {
+	backend default none;
+	sub vcl_recv {
+		return (synth(200));
+	}
+} -start
+
+client c1 {
+	stream 1 {
+		txreq -noadd \
+			-hdr ":authority" "foo.com" \
+			-hdr ":path" "/foobar" \
+			-hdr ":scheme" "http" \
+			-hdr ":method" "GET"
+		rxresp
+		expect resp.status == 200
+	} -run
+
+	stream 3 {
+		txreq -noadd \
+			-hdr ":a" "foo.com" \
+			-hdr ":p" "/foobar" \
+			-hdr ":s" "http" \
+			-hdr ":m" "GET"
+		rxrst
+		expect rst.err == PROTOCOL_ERROR
+	} -run
+} -run
