Fix HTTP Spec priority header parsing

This commit is contained in:
Philipp Heckel 2022-07-01 09:28:42 -04:00
parent bd6f3ca2e8
commit 95bd876be2
3 changed files with 19 additions and 3 deletions

View file

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

View file

@ -123,7 +123,8 @@ func ValidRandomString(s string, length int) bool {
// ParsePriority parses a priority string into its equivalent integer value // ParsePriority parses a priority string into its equivalent integer value
func ParsePriority(priority string) (int, error) { func ParsePriority(priority string) (int, error) {
switch strings.TrimSpace(strings.ToLower(priority)) { p := strings.TrimSpace(strings.ToLower(priority))
switch p {
case "": case "":
return 0, nil return 0, nil
case "1", "min": case "1", "min":
@ -137,6 +138,11 @@ func ParsePriority(priority string) (int, error) {
case "5", "max", "urgent": case "5", "max", "urgent":
return 5, nil return 5, nil
default: 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 return 0, errInvalidPriority
} }
} }

View file

@ -60,13 +60,23 @@ func TestParsePriority(t *testing.T) {
} }
func TestParsePriority_Invalid(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 { for _, priority := range priorities {
_, err := ParsePriority(priority) _, err := ParsePriority(priority)
require.Equal(t, errInvalidPriority, err) 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) { func TestPriorityString(t *testing.T) {
priorities := []int{0, 1, 2, 3, 4, 5} priorities := []int{0, 1, 2, 3, 4, 5}
expected := []string{"default", "min", "low", "default", "high", "max"} expected := []string{"default", "min", "low", "default", "high", "max"}