V2: Imitate a correct OPTIONS request

Howdy @Gumaa,

Faking a valid OPTIONS response is definitely one of the weirder requests I’ve seen, but I’ve definitely also seen pickier backends before, so…

A valid response is described by Mozilla on their developer web docs - both for a regular OPTIONS request and for a CORS preflight OPTIONS request. For a CORS preflight:

The server responds with Access-Control-Allow-Methods and says that POST , GET , and OPTIONS are viable methods to query the resource in question. This header is similar to the Allow response header, but used strictly within the context of CORS.

HTTP/1.1 204 No Content
Date: Mon, 01 Dec 2008 01:15:39 GMT 
Server: Apache/2.0.61 (Unix) 
Access-Control-Allow-Origin: http://foo.example 
Access-Control-Allow-Methods: POST, GET, OPTIONS 
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type 
Access-Control-Max-Age: 86400 
Vary: Accept-Encoding, Origin
Keep-Alive: timeout=2, max=100 
Connection: Keep-Alive

OPTIONS - HTTP | MDN

So we need:

  • An empty 204 No Content response
  • The usual CORS headers you’d put on
  • Plus Access-Control-Allow-Methods to respond to the OPTIONS request

It looks like you’re already applying all those headers when you reverse proxy. However, you’re going to need to use advanced matchers to ensure that OPTIONS requests get a preconfigured responder while normal requests get proxied.

Have a look at this advanced matcher example in particular:

To match on anything other than a path, define a named matcher and refer to it using @name :

@post {
	method POST
}
reverse_proxy @post localhost:9000

Caddyfile Concepts — Caddy Documentation

Seems almost perfect for us… Just need to tweak it to look for OPTIONS instead of POST, add in the path and instead of using it on the reverse proxy, we want to use it for the responder and for the headers.

The respond directive is what you’re after for the Status 204, and the header directive for the CORS headers.

Now, just to keep things neat, I’d recommend you use a handle directive to bundle the respond and header directives together in a neat package and tell Caddy to exclusively use that for any OPTIONS request.

So to sum up:

  1. Define your OPTIONS + /jsonrpc matcher
  2. handle that matcher specifically
  3. Throw a respond and a header directive in that handle
2 Likes