Просмотр исходного кода

Fix HTTP Spec priority header parsing

Philipp Heckel 3 лет назад
Родитель
Сommit
95bd876be2
3 измененных файлов с 19 добавлено и 3 удалено
  1. 1 1
      server/types.go
  2. 7 1
      util/util.go
  3. 11 1
      util/util_test.go

+ 1 - 1
server/types.go

@@ -174,7 +174,7 @@ func parseQueryFilters(r *http.Request) (*queryFilter, error) {
 	for _, p := range util.SplitNoEmpty(readParam(r, "x-priority", "priority", "prio", "p"), ",") {
 		priority, err := util.ParsePriority(p)
 		if err != nil {
-			return nil, err
+			return nil, errHTTPBadRequestPriorityInvalid
 		}
 		priorityFilter = append(priorityFilter, priority)
 	}

+ 7 - 1
util/util.go

@@ -123,7 +123,8 @@ func ValidRandomString(s string, length int) bool {
 
 // ParsePriority parses a priority string into its equivalent integer value
 func ParsePriority(priority string) (int, error) {
-	switch strings.TrimSpace(strings.ToLower(priority)) {
+	p := strings.TrimSpace(strings.ToLower(priority))
+	switch p {
 	case "":
 		return 0, nil
 	case "1", "min":
@@ -137,6 +138,11 @@ func ParsePriority(priority string) (int, error) {
 	case "5", "max", "urgent":
 		return 5, nil
 	default:
+		// Ignore new HTTP Priority header (see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-priority)
+		// Cloudflare adds this to requests when forwarding to the backend (ntfy), so we just ignore it.
+		if strings.HasPrefix(p, "u=") {
+			return 3, nil
+		}
 		return 0, errInvalidPriority
 	}
 }

+ 11 - 1
util/util_test.go

@@ -60,13 +60,23 @@ func TestParsePriority(t *testing.T) {
 }
 
 func TestParsePriority_Invalid(t *testing.T) {
-	priorities := []string{"-1", "6", "aa", "-"}
+	priorities := []string{"-1", "6", "aa", "-", "o=1"}
 	for _, priority := range priorities {
 		_, err := ParsePriority(priority)
 		require.Equal(t, errInvalidPriority, err)
 	}
 }
 
+func TestParsePriority_HTTPSpecPriority(t *testing.T) {
+	priorities := []string{"u=1", "u=3", "u=7, i"} // see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-priority
+	for _, priority := range priorities {
+		_, err := ParsePriority(priority)
+		actual, err := ParsePriority(priority)
+		require.Nil(t, err)
+		require.Equal(t, 3, actual) // Always expect 3!
+	}
+}
+
 func TestPriorityString(t *testing.T) {
 	priorities := []int{0, 1, 2, 3, 4, 5}
 	expected := []string{"default", "min", "low", "default", "high", "max"}