Golang http mux функция обработки изменений

#go #gorilla

#Вперед #горилла

Вопрос:

Я довольно новичок в Go и не смог найти никакой информации об этом, возможно, в настоящее время это просто невозможно.

Я пытаюсь удалить или заменить мультиплексный маршрут (используя http.NewServeMux, или мультиплексирование gorilla.Маршрутизатор). Моя конечная цель — иметь возможность включать / отключать маршрут или набор маршрутов без необходимости перезапуска программы.

Вероятно, я могу выполнить это на основе от обработчика к обработчику и просто вернуть 404, если эта функция «отключена», но я предпочел бы найти более общий способ сделать это, поскольку я хотел бы реализовать его для каждого маршрута в моем приложении.

Или мне было бы лучше просто отслеживать отключенные шаблоны URL и использовать некоторое промежуточное программное обеспечение для предотвращения выполнения обработчика?

Если кто-то может хотя бы указать мне правильное направление, я обязательно опубликую примеры кода решения, предполагающего, что оно есть. Спасибо!

Ответ №1:

Встроенного способа нет, но его достаточно легко реализовать.

 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 amp;amp; 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] = amp;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)
}
  

Ответ №2:

Да, вы можете.

Один из способов сделать это — иметь sturct, который реализует http.Handle интерфейс с методом ServeHTTP . Затем пусть структура содержит другой мультиплексор, подобный gorilla, и, наконец, имеет атомарный переключатель для включения / отключения подпрограммы

Это рабочий пример того, что я имею в виду:

 package main

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

var recording int32

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

func setRecording(shouldRecord bool) {
    if shouldRecord {
        atomic.StoreInt32(amp;recording, 1)
    } else {
        atomic.StoreInt32(amp;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 Recordingn")
        s.mux.ServeHTTP(w, r)
        return
    }

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

}

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

    handler := amp;SwitchHandler{mux: router}

    setRecording(false)

    http.Handle("/", handler)

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

Ответ №3:

Согласно https://github.com/gorilla/mux/issues/82 предлагается поменять маршрутизатор местами вместо удаления маршрутов. Существующие соединения останутся открытыми.