一尘不染

如何在net / http中注销处理程序?

go

我正在编写一个Web服务器,其中需要在运行时注册处理程序。例如,“ / create”将为所有URL(例如“ / 123 /
”等)创建一个新的处理程序。我需要一个相应的“ / destroy / 123”,它将为“ / 123 / ”注销处理程序。

这是用于处理“ / create”的代码

package main
import (
    "fmt"
    "net/http"
)

type MyHandler struct {
    id int
}
func (hf *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, r.URL.Path)
}

// Creates MyHandler instances and registers them as handlers at runtime
type HandlerFactory struct {
    handler_id int
}
func (hf *HandlerFactory) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    hf.handler_id++
    handler := MyHandler{hf.handler_id}
    handle := fmt.Sprintf("/%d/", hf.handler_id)
    http.Handle(handle, &handler)
}

func main() {
    factory := HandlerFactory{0}
    http.Handle("/create", &factory)
    http.ListenAndServe("localhost:8080", nil)
}

我尝试通过嵌入来实现自己的多路复用器,http.ServeMux但它在私有变量(ServeMux.m)中保留了其模式到处理程序的映射


阅读 154

收藏
2020-07-02

共1个答案

一尘不染

我要做的是创建一个自定义ServerMux。复制中的代码GOROOT/src/pkg/net/http/server.go。它始于837行,结束于939。

自定义ServerMux将需要一种注销方法。这应该易于实现。只需抓住锁和del()地图条目即可。例如(所有代码未经测试):

// TODO: check if registered and return error if not.
// TODO: possibly remove the automatic permanent link between /dir and /dir/.
func (mux *MyMux) Deregister(pattern string) error {
    mux.mu.Lock()
    defer mux.mu.Unlock()
    del(mux.m, pattern)
    return nil
}

为了使用这个新的多路复用器,您需要执行以下操作:

mux := newMux()
mux.Handle("/create", &factory)

srv := &http.Server {
    Addr: localhost:8080
    Handler: mux,
}
srv.ListenAndServe()

通过deregister()从另一个goroutine 调用来修改多路复用器是完全安全的,并且将修改ListenAndServe()路由消息的方式。

2020-07-02