11

我对 Go 还很陌生,还没有找到任何关于这方面的信息,也许目前还不可能。

我正在尝试删除或替换多路复用器路由(使用 http.NewServeMux 或大猩猩的 mux.Router)。我的最终目标是能够启用/禁用一个路由或一组路由,而无需重新启动程序。

我可能可以在处理程序到处理程序的基础上完成此操作,如果该功能被“禁用”,则仅返回 404,但我宁愿找到一种更通用的方法来执行此操作,因为我想为我的应用程序中的每个路由实现它。

或者我最好只跟踪禁用的 url 模式并使用一些中间件来防止处理程序执行?

如果有人至少可以指出我正确的方向,我绝对会发布解决方案的代码示例,假设有一个。谢谢!

4

3 回答 3

8

没有内置的方式,但很容易实现play

type HasHandleFunc interface { //this is just so it would work for gorilla and http.ServerMux
    HandleFunc(pattern string, handler func(w http.ResponseWriter, req *http.Request))
}
type Handler struct {
    http.HandlerFunc
    Enabled bool
}
type Handlers map[string]*Handler

func (h Handlers) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    path := r.URL.Path
    if handler, ok := h[path]; ok && handler.Enabled {
        handler.ServeHTTP(w, r)
    } else {
        http.Error(w, "Not Found", http.StatusNotFound)
    }
}

func (h Handlers) HandleFunc(mux HasHandleFunc, pattern string, handler http.HandlerFunc) {
    h[pattern] = &Handler{handler, true}
    mux.HandleFunc(pattern, h.ServeHTTP)
}

func main() {
    mux := http.NewServeMux()
    handlers := Handlers{}
    handlers.HandleFunc(mux, "/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("this will show once"))
        handlers["/"].Enabled = false
    })
    http.Handle("/", mux)
    http.ListenAndServe(":9020", nil)
}
于 2014-06-16T21:53:55.750 回答
0

是的你可以。

一种方法是拥有一个实现http.Handle与方法接口的 结构ServeHTTP。然后让结构包含另一个像大猩猩这样的多路复用器,最后有一个原子开关来启用/禁用子路由

这是我的意思的一个工作示例:

package main

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

var recording int32

func isRecording() bool {
    return atomic.LoadInt32(&recording) != 0
}

func setRecording(shouldRecord bool) {
    if shouldRecord {
        atomic.StoreInt32(&recording, 1)
    } else {
        atomic.StoreInt32(&recording, 0)
    }
}

type SwitchHandler struct {
    mux http.Handler
}

func (s *SwitchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if isRecording() {
        fmt.Printf("Switch Handler is Recording\n")
        s.mux.ServeHTTP(w, r)
        return
    }

    fmt.Printf("Switch Handler is NOT Recording\n")
    w.WriteHeader(http.StatusNotFound)
    fmt.Fprintf(w, "NOT Recording\n")

}

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/success/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Recording\n")
    })

    handler := &SwitchHandler{mux: router}

    setRecording(false)

    http.Handle("/", handler)

    http.ListenAndServe(":8080", nil)
}
于 2014-06-16T21:54:10.087 回答
0

根据https://github.com/gorilla/mux/issues/82建议交换路由器而不是删除路由。现有连接将保持打开状态。

于 2019-04-08T06:00:27.003 回答