2020-11-13 13:51:07 +01:00
|
|
|
package middleware
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
|
2021-12-02 21:58:08 +01:00
|
|
|
"github.com/go-chi/chi/v5"
|
2020-11-13 13:51:07 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
// URLFormatCtxKey is the context.Context key to store the URL format data
|
|
|
|
// for a request.
|
|
|
|
URLFormatCtxKey = &contextKey{"URLFormat"}
|
|
|
|
)
|
|
|
|
|
|
|
|
// URLFormat is a middleware that parses the url extension from a request path and stores it
|
|
|
|
// on the context as a string under the key `middleware.URLFormatCtxKey`. The middleware will
|
|
|
|
// trim the suffix from the routing path and continue routing.
|
|
|
|
//
|
|
|
|
// Routers should not include a url parameter for the suffix when using this middleware.
|
|
|
|
//
|
|
|
|
// Sample usage.. for url paths: `/articles/1`, `/articles/1.json` and `/articles/1.xml`
|
|
|
|
//
|
|
|
|
// func routes() http.Handler {
|
|
|
|
// r := chi.NewRouter()
|
|
|
|
// r.Use(middleware.URLFormat)
|
|
|
|
//
|
|
|
|
// r.Get("/articles/{id}", ListArticles)
|
|
|
|
//
|
|
|
|
// return r
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// func ListArticles(w http.ResponseWriter, r *http.Request) {
|
|
|
|
// urlFormat, _ := r.Context().Value(middleware.URLFormatCtxKey).(string)
|
|
|
|
//
|
|
|
|
// switch urlFormat {
|
|
|
|
// case "json":
|
|
|
|
// render.JSON(w, r, articles)
|
|
|
|
// case "xml:"
|
|
|
|
// render.XML(w, r, articles)
|
|
|
|
// default:
|
|
|
|
// render.JSON(w, r, articles)
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
func URLFormat(next http.Handler) http.Handler {
|
|
|
|
fn := func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ctx := r.Context()
|
|
|
|
|
|
|
|
var format string
|
|
|
|
path := r.URL.Path
|
|
|
|
|
|
|
|
if strings.Index(path, ".") > 0 {
|
|
|
|
base := strings.LastIndex(path, "/")
|
2021-01-05 14:05:40 +01:00
|
|
|
idx := strings.LastIndex(path[base:], ".")
|
2020-11-13 13:51:07 +01:00
|
|
|
|
|
|
|
if idx > 0 {
|
|
|
|
idx += base
|
|
|
|
format = path[idx+1:]
|
|
|
|
|
|
|
|
rctx := chi.RouteContext(r.Context())
|
|
|
|
rctx.RoutePath = path[:idx]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
r = r.WithContext(context.WithValue(ctx, URLFormatCtxKey, format))
|
|
|
|
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
}
|
|
|
|
return http.HandlerFunc(fn)
|
|
|
|
}
|