0

I am using gorilla/mux and go-swagger to serve REST endpoints. Since I am running goswagger and calling REST endpoints from browser, the POST call is making http.MethodOptions first and then http.MethodPut later. Because of which I had a lot of extra code for http.MethodOptions and doing practically nothing on my application. I am guess this can be avoided but I couldn't find an example. If I delete http.MethodOptions from the code the rest call if failing from browser although CURL request succeed from terminal.

package rest

func Middleware(handler http.Handler) http.Handler {
    log.Println("middleware registered")
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println("REST URI:", r.RequestURI, r.Method)
        w.Header().Add("Access-Control-Allow-Origin", "*")
        w.Header().Add("Content-Type", "application/json, multipart/form-data")
        w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
        w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
        handler.ServeHTTP(w, r)
    })
}

func ListenAndServe(pathPrefix, addr string) error {

    // router := mux.NewRouter()
    // router.Use(Middleware)

    apiRouter := mux.NewRouter().PathPrefix(pathPrefix).Subrouter()
    apiRouter.Use(Middleware)

    // register product route
    {
        // apiRouter.Path("/").Handler(http.HandlerFunc(handlers.Products)).Methods()
        apiRouter.HandleFunc("/product", handlers.Products).Methods(http.MethodGet, http.MethodPost, http.MethodOptions)
        apiRouter.HandleFunc("/product/{id}", handlers.Product).Methods(http.MethodGet, http.MethodPut, http.MethodDelete, http.MethodOptions)
    }

    // register container route
    {
        containerRouter := apiRouter.PathPrefix("/container").Subrouter()
        containerRouter.HandleFunc("/{id}/start", handlers.containerStart).Methods(http.MethodPut, http.MethodOptions)
        containerRouter.HandleFunc("/{id}/stop", handlers.containerStop).Methods(http.MethodPut, http.MethodOptions)

    }

    srv := &http.Server{
        Addr:         addr,
        WriteTimeout: 15 * time.Second,
        ReadTimeout:  15 * time.Second,
        IdleTimeout:  time.Second * 60,
        Handler:      apiRouter,
    }
    return srv.ListenAndServe()
}

And Code for Container start

package handlers

import (
    "net/http"
    "github.com/gorilla/mux"
)

func ContainerStart(w http.ResponseWriter, r *http.Request) {
    switch r.Method {
    case http.MethodOptions:
    case http.MethodPut:
        /*
            swagger:route PUT /container/{id}/start Container startContainer

            Start Container artifact

                Consumes:
                - application/json

                Produces:
                - application/json

                Schemes: http

                Responses:
                    default: genericError
                    200:
        */
        log.Println("REST: container start")
        // DO Something
    }
}
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
BhanuKiran
  • 2,631
  • 3
  • 20
  • 36
  • Does this answer your question? [CORS-enabled server not denying requests](https://stackoverflow.com/questions/45069689/cors-enabled-server-not-denying-requests) – jub0bs Feb 12 '23 at 14:55

1 Answers1

0

The OPTIONS request you are seeing is called a preflight request which is part of CORS. CORS is a common obstacle which has been tackled many times, gorilla even offers pre-built middleware.

The reason cURL works is because it doesn't implement CORS, since it is a security feature which is only really relevant to full browsers.

CORS only applies to cross-origin requests. If the site making the POST request is dedicated to this REST API, you can also bypass the issue by hosting both on the same domain(that is more complicated to host), but this depends on your senario.

Dylan Reimerink
  • 5,874
  • 2
  • 15
  • 21
  • 1
    CORS isn't the obstacle to what the OP wants to do, though; rather, the Same-Origin Policy is. – jub0bs Apr 25 '22 at 07:56