actix / actix/actix-web

Incorrect parsing of Accept header

Open
#2,914 5 comments 0 reactions 1 assignee Claimed by @JohnTitor View on GitHub
A-web C-bug
Dominant language
Rust
Stars
24.8k
Forks
1.9k
Avg merge
23h 10m
Merged PRs (30d)
26

Description

## Expected Behavior

HTTP Accept headers are permitted to contain accept parameters without a set value. For example:

```
Accept: application/prs.test;version
```

When extracting this to a `web::Header`, the resulting value should be:

```
Header(Accept([QualityItem { item: "application/prs.test;version", quality: Quality(1000) }]))
```

The relevant portion of the HTTP/1.1 specification provides the following grammar:

```
Accept = "Accept" ":"
#( media-range [ accept-params ] )

media-range = ( "*/*"
| ( type "/" "*" )
| ( type "/" subtype )
) *( ";" parameter )
accept-params = ";" "q" "=" qvalue *( accept-extension )
accept-extension = ";" token [ "=" ( token | quoted-string ) ]
```

The grammar for `accept-extension` does not require the `=` character followed by a token/quoted-string in order to be a valid parameter. Similarly, the grammar for a media-range parameter does not specify any such requirement.

## Current Behavior

The current behaviour of this results in the following value:

```
Header(Accept([]))
```

## Possible Solution

The Accept header parser should be updated so as not to require the optional part of accept parameters.

## Steps to Reproduce (for bugs)

1. Extract a `web::Header` value by specifying it as one of the parameters of a service function.
2. Place `println!("{:?}", accept);` within this function.
3. Send an HTTP request to the server with the following header: `Accept: application/prs.test;version`.
4. Observe that the printed output shows no Accept headers present.

## Context

I'm creating an API that is intended to handle different values of a `version` accept parameter. In the case where the `version` parameter is missing *or* is present without a value set, the API should assume a default value. Additionally, the API may accept other parameters that change the representation of the content being returned to the client.

## Your Environment

- Rust Version (I.e, output of `rustc -V`): `rustc 1.64.0 (a55dd71d5 2022-09-19)`
- Actix Web Version: `4.2.1`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.