Skip to content

CORS on rejected requests #518

Open
Open
@bertptrs

Description

@bertptrs

The CORS filter automatically adds the proper headers to responses and handles pre-flight requests, but if a route is ever rejected, the headers are not added, and so a browser will reject the response. This makes it hard to determine the failure from the client side, since the response never arrives there.

I've created a small demo to show this problem. Based on the example in the readme, we have the following server:

use warp::Filter;

#[tokio::main]
async fn main() {
    // GET / with header X-Username -> Hello, X-Username
    let hello = warp::filters::header::header("X-Username")
        .map(|name: String| format!("Hello, {}!", name));

    // Add CORS to that route
    let hello = hello.with(warp::cors().allow_any_origin());

    warp::serve(hello)
        .run(([127, 0, 0, 1], 3030))
        .await;
}

A valid request is handled correctly, and the allowed origin header will show up:

$ curl localhost:3030 -H "Origin: example.org" -v -H "X-Username: Bert"
*   Trying 127.0.0.1:3030...
* Connected to localhost (127.0.0.1) port 3030 (#0)
> GET / HTTP/1.1
> Host: localhost:3030
> User-Agent: curl/7.69.1
> Accept: */*
> Origin: example.org
> X-Username: Bert
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: text/plain; charset=utf-8
< access-control-allow-origin: example.org
< content-length: 12
< date: Fri, 03 Apr 2020 08:29:43 GMT
< 
* Connection #0 to host localhost left intact
Hello, Bert!

If we are missing the required header, we get a Bad Request response as expected, but the access-control-allow-origin-header will be missing:

$ curl localhost:3030 -H "Origin: example.org" -v
*   Trying 127.0.0.1:3030...
* Connected to localhost (127.0.0.1) port 3030 (#0)
> GET / HTTP/1.1
> Host: localhost:3030
> User-Agent: curl/7.69.1
> Accept: */*
> Origin: example.org
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< content-type: text/plain; charset=utf-8
< content-length: 35
< date: Fri, 03 Apr 2020 08:35:37 GMT
< 
* Connection #0 to host localhost left intact
Missing request header "X-Username"

It's possible to work around this issue by having a recover at the end to catch all possible errors at the end. This is inconvenient because in general, the default error messages are pretty good and don't need replacement, since you can clearly see what's wrong here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    rfcExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions