http2/hpack: remove hpack's constant time string comparison

Delete the constant time string comparison. It's slow and shows up in
profiles, nobody else does it, and the spec text no longer recommends
doing it. See bug for discussion and details.

Also clean up some naked returns while I'm here (noted during review).

Fixes golang/go#19238

Change-Id: I344c5766c5d97bbcf01eab0624097941591ce00f
Reviewed-on: https://go-review.googlesource.com/37394
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Tom Bergan <tombergan@google.com>
diff --git a/http2/hpack/encode.go b/http2/hpack/encode.go
index 6b3b9f8..395e1c2 100644
--- a/http2/hpack/encode.go
+++ b/http2/hpack/encode.go
@@ -89,21 +89,16 @@
 // becomes false.
 func (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) {
 	for idx, hf := range staticTable {
-		if !constantTimeStringCompare(hf.Name, f.Name) {
+		if hf.Name != f.Name {
 			continue
 		}
 		if i == 0 {
 			i = uint64(idx + 1)
 		}
-		if f.Sensitive {
+		if f.Sensitive || hf.Value != f.Value {
 			continue
 		}
-		if !constantTimeStringCompare(hf.Value, f.Value) {
-			continue
-		}
-		i = uint64(idx + 1)
-		nameValueMatch = true
-		return
+		return uint64(idx + 1), true
 	}
 
 	j, nameValueMatch := e.dynTab.search(f)
diff --git a/http2/hpack/hpack.go b/http2/hpack/hpack.go
index 007bc7f..d18be44 100644
--- a/http2/hpack/hpack.go
+++ b/http2/hpack/hpack.go
@@ -199,22 +199,6 @@
 	}
 }
 
-// constantTimeStringCompare compares string a and b in a constant
-// time manner.
-func constantTimeStringCompare(a, b string) bool {
-	if len(a) != len(b) {
-		return false
-	}
-
-	c := byte(0)
-
-	for i := 0; i < len(a); i++ {
-		c |= a[i] ^ b[i]
-	}
-
-	return c == 0
-}
-
 // Search searches f in the table. The return value i is 0 if there is
 // no name match. If there is name match or name/value match, i is the
 // index of that entry (1-based). If both name and value match,
@@ -223,7 +207,7 @@
 	l := len(dt.ents)
 	for j := l - 1; j >= 0; j-- {
 		ent := dt.ents[j]
-		if !constantTimeStringCompare(ent.Name, f.Name) {
+		if ent.Name != f.Name {
 			continue
 		}
 		if i == 0 {
@@ -232,14 +216,12 @@
 		if f.Sensitive {
 			continue
 		}
-		if !constantTimeStringCompare(ent.Value, f.Value) {
+		if ent.Value != f.Value {
 			continue
 		}
-		i = uint64(l - j)
-		nameValueMatch = true
-		return
+		return uint64(l - j), true
 	}
-	return
+	return i, false
 }
 
 func (d *Decoder) maxTableIndex() int {