tower-rs / tower-http

HTTP specific Tower utilities.
680 stars 159 forks source link

CORS middleware blocks other Vary headers from being set #397

Closed AlyoshaVasilieva closed 8 months ago

AlyoshaVasilieva commented 1 year ago

Bug Report

Version

0.4.3

Platform

Windows 10 x64

Description

The CORS middleware blocks all other Vary headers, only allowing its own to be set in responses.

Cargo.toml:

[package]
name = "bug-repro"
version = "0.1.0"
edition = "2021"

[dependencies]
axum = "0.6.20"
tokio = { version = "1.29.1", features = ["macros", "rt", "rt-multi-thread"] }
tower-http = { version = "0.4.3", features = ["cors"] }

main.rs:

use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::routing::get;
use axum::Router;
use tower_http::cors::CorsLayer;

#[tokio::main]
async fn main() {
    let router = Router::new().route("/", get(hello)).layer(CorsLayer::permissive());
    axum::Server::bind(&"127.0.0.1:6000".parse().unwrap())
        .serve(router.into_make_service())
        .await
        .unwrap()
}

async fn hello() -> Response {
    (StatusCode::OK, [("vary", "accept, accept-encoding")], "Hello world").into_response()
}

This code clearly adds a Vary header. However, by sending a request to this app using curl, the only Vary header values that appear are:

< vary: origin
< vary: access-control-request-method
< vary: access-control-request-headers

Removing the CorsLayer allows vary: accept, accept-encoding to appear in responses.

jplatte commented 1 year ago

Interesting, we send multiple vary values too when the usual solution seems to be one header with a comma-separated list of arguments.