2014-06-16 9 views
7

Sono abbastanza nuovo per andare e non sono stato in grado di trovare alcuna informazione su questo, forse non è solo possibile in questo momento.Golang http mux change handler function

Sto tentando di eliminare o sostituire una rotta di mux (utilizzando http.NewServeMux o mux.Router di gorilla). Il mio obiettivo finale è quello di essere in grado di abilitare/disabilitare una rotta o una serie di percorsi senza dover riavviare il programma.

Probabilmente riuscirò a farlo da gestore a gestore base e restituirei solo 404 se questa funzione è "disabilitata", ma preferirei trovare un modo più generale per farlo poiché vorrei implementarlo per ogni percorso in la mia applicazione.

Oppure dovrei stare meglio solo tenendo traccia dei modelli di URL disabilitati e utilizzando alcuni middleware per impedire l'esecuzione del gestore?

Se qualcuno può almeno indicarmi la giusta direzione, inserirò assolutamente esempi di codice di una soluzione supponendo che ce ne sia uno. Grazie!

risposta

7

Non esiste un modo integrato, ma è abbastanza semplice implementare 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) 
} 
0

Sì, è possibile.

Un modo per farlo è disporre di un'interfaccia che implementa l'interfaccia http.Handle con il metodo ServeHTTP. Dai struct contiene un'altra muxer come gorilla di infine, hanno uno switch atomico per abilitare/disabilitare la subrouting

Questo è un esempio di lavoro di ciò che intendo:

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) 
} 
Problemi correlati