使用Golang Gorilla包设置回调函数

huangapple go评论76阅读模式
英文:

Setting callback with Golang Gorilla package

问题

在gorilla/mux HTTP web服务器中,有没有一种简单的方法可以设置一个回调函数,在每次发出的HTTP请求上调用该函数?在他们的文档中似乎没有设置回调函数的概念。

我想在每次对我的服务器的调用中检查一个头部,以获取一些信息。

英文:

Is there an easy way to set a callback function that is called on every HTTP request made to a gorilla/mux HTTP webserver? They don't seem to have a notion of setting a callback function in their docs.

I wanted to check one of the headers for some information on every call to my server.

答案1

得分: 2

gorilla/mux本身只是一个路由器和调度器,虽然从技术上讲可以做到你所要求的,但这并不是它的设计初衷。

"惯用"的方法是使用中间件来包装你的处理程序,用于在每次调用时为处理程序添加任何附加功能,比如检查头部以获取一些信息。

在gorilla/mux的完整示例中,你可以这样做:

package main

import (
    "log"
    "net/http"

    "github.com/gorilla/mux"
)

func HeaderCheckWrapper(requiredHeader string, original func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        if foo, ok := r.Header[requiredHeader]; ok {
            // 对头部值进行处理,然后调用原始处理程序:
            log.Printf("找到头部 %q,值为 %q", requiredHeader, foo)
            original(w, r)
            return
        }
        // 否则拒绝请求
        w.WriteHeader(http.StatusPreconditionFailed)
        w.Write([]byte("缺少预期的头部 " + requiredHeader))
    }
}

func YourHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Gorilla!\n"))
}

func main() {
    r := mux.NewRouter()
    // 路由由路径和处理程序函数组成。
    r.HandleFunc("/", HeaderCheckWrapper("X-Foo-Header", YourHandler))

    // 绑定端口并传入我们的路由器
    log.Fatal(http.ListenAndServe(":8000", r))
}

希望对你有所帮助!

英文:

gorilla/mux itself is just a router and dispatcher, which, although technically could do what you're asking, is not really what it's designed for.

The "idiomatic" approach is to wrap your handler with middleware that decorates your handler with any additional functions, like one to check headers for some information on every call.

Expanding on the gorilla/mux full example, you could do something like:

package main

import (
        "log"
        "net/http"

        "github.com/gorilla/mux"
)

func HeaderCheckWrapper(requiredHeader string, original func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
        return func(w http.ResponseWriter, r *http.Request) {
                if foo, ok := r.Header[requiredHeader]; ok {
                        // do whatever with the header value, and then call the original:
                        log.Printf("Found header %q, with value %q", requiredHeader, foo)
                        original(w, r)
                        return
                }
                // otherwise reject the request
                w.WriteHeader(http.StatusPreconditionFailed)
                w.Write([]byte("missing expected header " + requiredHeader))
        }
}

func YourHandler(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Gorilla!\n"))
}

func main() {
        r := mux.NewRouter()
        // Routes consist of a path and a handler function.
        r.HandleFunc("/", HeaderCheckWrapper("X-Foo-Header", YourHandler))

        // Bind to a port and pass our router in
        log.Fatal(http.ListenAndServe(":8000", r))
}

答案2

得分: 2

如果你想要一个能够接收路由器中所有请求的处理程序,你可以使用 alice 将处理程序链接在一起。

这是一种简单的方式来处理所有传入的请求。

以下是一个示例:

package main

import (
	"net/http"

	"github.com/gorilla/mux"
	"github.com/justinas/alice"
)

func MyMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if len(r.URL.Path) > 1 {
			http.Error(w, "请只调用索引,因为这只是一个糟糕的示例", http.StatusNotFound)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func Handler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello"))
}

func main() {
	r := mux.NewRouter()

	r.HandleFunc("/", Handler)
	r.HandleFunc("/fail", Handler)

	chain := alice.New(MyMiddleware).Then(r)

	http.ListenAndServe(":8080", chain)
}

希望对你有帮助!

英文:

If you want to have a handler that can receive all requests in the router you can use alice to chain your handlers together.

This is a simple way to act on all incoming requests.

Here is an example:

package main

import (
	"net/http"

	"github.com/gorilla/mux"
	"github.com/justinas/alice"
)

func MyMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if len(r.URL.Path) > 1 {
			http.Error(w, "please only call index because this is a lame example", http.StatusNotFound)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func Handler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello"))
}

func main() {
	r := mux.NewRouter()

	r.HandleFunc("/", Handler)
	r.HandleFunc("/fail", Handler)

	chain := alice.New(MyMiddleware).Then(r)

	http.ListenAndServe(":8080", chain)
}

huangapple
  • 本文由 发表于 2016年12月7日 06:09:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/41005888.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定