1

We encountered a very weird behavior when using Nginx as a reverse proxy.

We have REST services that need to be used with the browser, We configured these HTTP Golang services to handle CORS using cors package.

We noticed that when the browser triggers a preflight request the request doesn't go to the backend service and instead Nginx responds with the status 405 Method Not Allowed and the request is never forwarded or proxied to the backend service at all.

To fix this issue we had to handle OPTIONS requests manually from the location directive, This is very limited as we need the liberty to update for example the allowed headers using Access-Control-Allow-Headers based on the requested route.

How can we forward any Preflight or OPTIONS request to the backend to handle?

NOTE: We are using default Nginx configurations according to the official Nginx docker image.

file: main.go

package main

import (
    "net/http"

    "github.com/rs/cors"
)

func main() {
    mux := http.NewServeMux()

    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello World"))
    })

    r := cors.AllowAll().Handler(mux)
    http.ListenAndServe(":3000", r)
}

file: server.conf

server {
    listen 80;
    server_name example.com;


    location / {
        proxy_pass http://localhost:3000;
        
        # Handling OPTIONS for this location directive.
        if ($request_method = 'OPTIONS') {
          add_header Access-Control-Allow-Origin "$http_origin";
          add_header Access-Control-Allow-Credentials 'true';
          add_header Access-Control-Allow-Headers 'Authorization, Content-Type, Origin, X-Requested-With, Accept';
          add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, PUT, DELETE';
          add_header Content-Type 'text/plain; charset=utf-8';
          return 204;
        }

        proxy_set_header X-Original-URI $request_uri;
        proxy_set_header X-Original-Remote-Addr $remote_addr;
        proxy_set_header X-Original-Host $host;
    }
}

Related:

Ahmed Mahmoud
  • 11
  • 2
  • 2
  • Please don't link to a Gist. Instead, make your question self-contained by adding a https://stackoverflow.com/help/minimal-reproducible-example – jub0bs Feb 09 '23 at 08:43
  • You should configure CORS in at most one place. If you do it in NGINX, don't use rs/cors and vice versa. – jub0bs Feb 09 '23 at 09:04
  • 1
    @jub0bs I've updated the post with the demo built-in. I want to handle CORS using my backend service, not Nginx to have more flexibility, But I can't do so, because NGINX is not allowing any OPTIONS preflight requests to my backend in the first place. – Ahmed Mahmoud Feb 10 '23 at 10:36
  • 1
    You write: _NGINX is not allowing any OPTIONS preflight requests to my backend in the first place._ You need to fix this first. Find out why NGINX is blocking `OPTIONS` requests, and you'll be one step closer to solving your issue. – jub0bs Feb 10 '23 at 12:25

0 Answers0