2

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:

4
  • Please don't link to a Gist. Instead, make your question self-contained by adding a stackoverflow.com/help/minimal-reproducible-example Commented Feb 9, 2023 at 8:43
  • You should configure CORS in at most one place. If you do it in NGINX, don't use rs/cors and vice versa. Commented Feb 9, 2023 at 9: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. Commented Feb 10, 2023 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. Commented Feb 10, 2023 at 12:25

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.