Volga
Home
API Docs
GitHub
  • English
  • Русский
Home
API Docs
GitHub
  • English
  • Русский
  • Home
  • Getting Started

    • Quick Start
    • Route Parameters
    • Query Parameters
    • Route Groups
  • Requests & Responses

    • Headers
    • Handling JSON
    • Handling Form Data
    • Working with Files
    • Cookies
  • Middleware & Infrastructure

    • Basic Middleware
    • Custom Middleware
    • Response Compression
    • Request Decompression
    • CORS (Cross-Origin Resource Sharing)
    • Static Files
    • Rate Limiting
  • Security & Access

    • Authentication and Authorization
  • Reliability & Observability

    • Global Error Handling
    • Tracing & Logging
    • Request cancellation
  • Protocols & Realtime

    • HTTP/1 and HTTP/2
    • HTTPS
    • WebSockets
    • Server-Sent Events (SSE)
  • Advanced Patterns

    • Dependency Injection
    • Custom Handling of HEAD, OPTIONS, and TRACE Methods

CORS (Cross-Origin Resource Sharing)

Volga provides an easily configurable CORS middleware.

It is included in the full feature set. However, if you are not using it, you can enable the middleware feature in your Cargo.toml to make CORS functionality available:

[dependencies]
volga = { version = "...", features = ["middleware"] }

Basic Setup

The following example demonstrates a permissive CORS configuration:

use volga::App;

#[tokio::main]
async fn main() -> std::io::Result<()> {   
    let mut app = App::new()
        .with_cors(|cors| cors
            .with_any_origin()
            .with_any_header()
            .with_any_method());

    // Enable CORS middleware
    app.use_cors();

    app.map_post("/", || async {});

    app.run().await
}

By default, CORS is disabled. To avoid a runtime panic, you must call with_cors() before use_cors().

If you need a stricter configuration, you can specify allowed origins, headers, and methods:

use volga::{App, http::Method};

#[tokio::main]
async fn main() -> std::io::Result<()> {   
    let mut app = App::new()
        .with_cors(|cors| cors
            .with_origins(["http://example.com", "http://example.net"])
            .with_headers(["Cache-Control", "Content-Language"])
            .with_methods([Method::GET, Method::POST]));

    // Enable CORS middleware
    app.use_cors();

    app.map_post("/", || async {});

    app.run().await
}

Warning

If you need to enable credentials using with_credentials(true), note that it cannot be used with wildcard origins, headers, or methods for security reasons. These constraints are validated in use_cors(), which will panic if misconfigured.

CORS Policies and Scoping

Volga separates CORS configuration from where it is applied:

  • with_cors() defines one or more CORS policies.

  • use_cors() enables the CORS middleware (required).

  • CORS is applied based on:

    • a default policy (applies to all routes unless overridden), or
    • a named policy (applies only where explicitly specified).

Named Policy for a Route Group

If you configure only a named policy, routes will not get CORS unless you explicitly attach that policy via cors_with(...).

use volga::App;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new()
        .with_cors(|cors| cors
            .with_name("policy")
            .with_origins(["https://example.com"])
            .with_any_header()
            .with_any_method());

    // Enable the middleware (required)
    app.use_cors();

    app.group("/api", |api| {
        // Apply CORS only for `/api/*`
        api.cors_with("policy");

        api.map_get("/users", || async {});
        api.map_post("/posts", || async {});
    });

    // No CORS here (policy not applied)
    app.map_get("/internal", || async {});

    app.run().await
}

Named Policy for an Individual Route

You can attach a policy to a single endpoint:

use volga::App;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new()
        .with_cors(|cors| cors
            .with_name("permissive")
            .with_any_origin()
            .with_any_method()
            .with_any_header());

    app.use_cors();

    app.map_get("/public", || async {})
        .cors_with("permissive");

    app.map_get("/private", || async {})
        .disable_cors();

    app.run().await
}

Warning

When using only named policies, endpoints without an explicitly attached policy will not emit CORS headers.

Overriding and Disabling

CORS can be explicitly disabled on a route (or group) using disable_cors(). This is especially useful when you have a default policy enabled globally, but need to opt out for specific endpoints.

A complete example is available here.

Last Updated: 1/18/26, 6:33 PM
Prev
Request Decompression
Next
Static Files