CORS

Live on this server

Allows a frontend on another origin to call the API from the browser.

Lets a frontend on another origin - here a React app on the Vite dev server, at http://localhost:5173 - call the API from the browser. Browsers block such requests unless the server allows them with CORS headers, and ask with a preflight request (OPTIONS) before they send anything but simple requests.

CorsPolicy.Restrictive() allows the origins you add, with the methods you name, and answers the preflight requests for you. Requests from any other origin get no CORS headers, so the browser blocks them.

To run it, create a console app (dotnet new console), add GenHTTP (dotnet add package GenHTTP.Full), replace Program.cs with the code below and start it with dotnet run - it answers at http://localhost:8080/.

Program.cs34 lines
using System.Collections.Concurrent;

using GenHTTP.Engine.Internal;

using GenHTTP.Api.Protocol;

using GenHTTP.Modules.Functional;
using GenHTTP.Modules.Layouting;
using GenHTTP.Modules.Practices;
using GenHTTP.Modules.Security;

var todos = new ConcurrentQueue<string>(["Write the frontend"]);

var api = Inline.Create()
                .Get(() => todos.ToList()) // GET /api/todos/
                .Put((string todo) => // PUT /api/todos/?todo=...
                {
                    todos.Enqueue(todo);

                    while (todos.Count > 50) todos.TryDequeue(out _); // keeps the latest todos only
                });

// the frontend, e.g. a React app served by the Vite dev server
var policy = CorsPolicy.Restrictive()
                       .Add("http://localhost:5173", [RequestMethod.Get, RequestMethod.Put], allowedHeaders: null, exposedHeaders: null, allowCredentials: false);

var app = Layout.Create()
                .Add("api/todos", api)
                .Add(policy);

await Host.Create()
          .Handler(app)
          .Defaults()
          .RunAsync();

Try it

Send the requests to the sample running on this server - change the path, headers or body as you like, or copy them as curl commands.

  1. List the todos

    GET
    curl -i 'https://genhttp.org/demo/cors/api/todos/'
  2. Send the preflight request of the frontend

    Browsers send this before the actual request. Try another origin to see the CORS headers disappear.

    curl -i -X OPTIONS -H "Origin: http://localhost:5173" -H "Access-Control-Request-Method: PUT" https://genhttp.org/demo/cors/api/todos/