Skip to content

Commit

Permalink
add cors example and muxie.Methods().NoContent(http.MethodOptions)
Browse files Browse the repository at this point in the history
  • Loading branch information
kataras committed May 16, 2020
1 parent ee2fdec commit c9d5de3
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 18 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<div align="center">
<!-- Release -->
<a href="https://github.com/kataras/muxie/releases">
<img src="https://img.shields.io/badge/release%20-v1.0.8-0077b3.svg?style=flat-squaree"
<img src="https://img.shields.io/badge/release%20-v1.0.9-0077b3.svg?style=flat-squaree"
alt="Release/stability" />
</a>
<!-- Godocs -->
Expand Down Expand Up @@ -84,7 +84,7 @@ The only requirement is the [Go Programming Language](https://golang.org/dl/)
$ go get -u github.com/kataras/muxie
```

## Philosophy
<!-- ## Philosophy
I believe that providing the right tools for the right job represents my best self
and I really enjoy writing small libraries and even frameworks that can be used and learnt by thousands like me.
Expand Down Expand Up @@ -117,7 +117,7 @@ For the hesitants: There is a [public repository](https://github.com/kataras/tri
And... never forget to put some fun in your life ❤︎
Yours,<br />
Gerasimos Maropoulos ([@MakisMaropoulos](https://twitter.com/MakisMaropoulos))
Gerasimos Maropoulos ([@MakisMaropoulos](https://twitter.com/MakisMaropoulos)) -->

## License

Expand Down
46 changes: 46 additions & 0 deletions _examples/11_cors/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package main

import (
"fmt"
"net/http"

"github.com/kataras/muxie"
)

func main() {
mux := muxie.NewMux()
mux.PathCorrection = true

mux.Use(corsMiddleware) // <--- IMPORTANT: register the cors middleware.

mux.Handle("/", muxie.Methods().
NoContent(http.MethodOptions). // <--- IMPORTANT: cors preflight.
HandleFunc(http.MethodPost, postHandler))

fmt.Println("Server started at http://localhost:80")
http.ListenAndServe(":80", mux)
}

func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := w.Header()
h.Set("Access-Control-Allow-Origin", "*")
h.Set("Access-Control-Allow-Credentials", "true")

if r.Method == http.MethodOptions {
h.Set("Access-Control-Methods", "POST, PUT, PATCH, DELETE")
h.Set("Access-Control-Allow-Headers", "Access-Control-Allow-Origin,Content-Type")
h.Set("Access-Control-Max-Age", "86400")
w.WriteHeader(http.StatusNoContent)
return
}

next.ServeHTTP(w, r)
})
}

func postHandler(w http.ResponseWriter, r *http.Request) {
var request map[string]interface{}
muxie.JSON.Bind(r, &request)
muxie.JSON.Dispatch(w, map[string]string{"message": "ok"})
}
2 changes: 1 addition & 1 deletion doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Source code and other details for the project are available at GitHub:
Current Version
1.0.8
1.0.9
Installation
Expand Down
34 changes: 31 additions & 3 deletions method_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,18 @@ func Methods() *MethodHandler {
// 3. mux.Handle("/user/:id", muxie.Method("GET", getUserHandler).Method("POST", saveUserHandler))
//
// 4. mux.Handle("/user/:id", muxie.Methods().
// Handle("GET", getHandler).
// HandleFunc("POST", postHandler))
// Handle("GET", getHandler).
// HandleFunc("POST", postHandler))
//
return &MethodHandler{handlers: make(map[string]http.Handler)}
}

// NoContentHandler defaults to a handler which just sends 204 status.
// See `MethodHandler.NoContent` method.
var NoContentHandler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
})

// MethodHandler implements the `http.Handler` which can be used on `Mux#Handle/HandleFunc`
// to declare handlers responsible for specific HTTP method(s).
//
Expand All @@ -43,6 +49,12 @@ type MethodHandler struct {
// origin *Mux

handlers map[string]http.Handler // method:handler
// Handle/HandleFunc can accept more than one methods per handler separated by comma or space,
// however in order to not repeat ourselves for every handler:
// extra methods will be not registered to a handler but they can register
// the route so it can be reachable, it is binded to a handler which just sends status no content,
// can be used for OPTIONS on cors.
noContentMethods []string

methodsAllowedStr string
}
Expand All @@ -67,7 +79,7 @@ func (m *MethodHandler) Handle(method string, handler http.Handler) *MethodHandl
return m
}

method = strings.ToUpper(strings.TrimSpace(method))
method = normalizeMethod(method)

if m.methodsAllowedStr == "" {
m.methodsAllowedStr = method
Expand All @@ -80,6 +92,18 @@ func (m *MethodHandler) Handle(method string, handler http.Handler) *MethodHandl
return m
}

// NoContent registers a handler to a method
// which sends 204 (no status content) to the client.
//
// Example: _examples/11_cors for more.
func (m *MethodHandler) NoContent(methods ...string) *MethodHandler {
for _, method := range methods {
m.handlers[normalizeMethod(method)] = NoContentHandler
}

return m
}

// HandleFunc adds a handler function to be responsible for a specific HTTP Method.
// Returns this MethodHandler for further calls.
func (m *MethodHandler) HandleFunc(method string, handlerFunc func(w http.ResponseWriter, r *http.Request)) *MethodHandler {
Expand All @@ -100,3 +124,7 @@ func (m *MethodHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Allow", m.methodsAllowedStr)
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
}

func normalizeMethod(method string) string {
return strings.ToUpper(strings.TrimSpace(method))
}
30 changes: 19 additions & 11 deletions mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ import (
//
// See `NewMux`.
type Mux struct {
// PathCorrection removes leading slashes from the request path.
// Defaults to false, however is highly recommended to turn it on.
PathCorrection bool
Routes *Trie
// PathCorrectionNoRedirect if `PathCorrection` is set to true,
// it will execute the handlers chain without redirection.
// Defaults to false.
PathCorrectionNoRedirect bool
Routes *Trie

paramsPool *sync.Pool

Expand Down Expand Up @@ -157,18 +163,20 @@ func (m *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// update the new path and redirect.
// use Trim to ensure there is no open redirect due to two leading slashes
r.URL.Path = pathSep + strings.Trim(path, pathSep)
url := r.URL.String()
method := r.Method
// Fixes https://github.com/kataras/iris/issues/921
// This is caused for security reasons, imagine a payment shop,
// you can't just permantly redirect a POST request, so just 307 (RFC 7231, 6.4.7).
if method == http.MethodPost || method == http.MethodPut {
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
if !m.PathCorrectionNoRedirect {
url := r.URL.String()
method := r.Method
// Fixes https://github.com/kataras/iris/issues/921
// This is caused for security reasons, imagine a payment shop,
// you can't just permantly redirect a POST request, so just 307 (RFC 7231, 6.4.7).
if method == http.MethodPost || method == http.MethodPut {
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
return
}

http.Redirect(w, r, url, http.StatusMovedPermanently)
return
}

http.Redirect(w, r, url, http.StatusMovedPermanently)
return
}
}

Expand Down

0 comments on commit c9d5de3

Please sign in to comment.