github.com/chwjbn/xclash@v0.2.0/hub/route/provider.go (about)

     1  package route
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  
     7  	"github.com/chwjbn/xclash/constant/provider"
     8  	"github.com/chwjbn/xclash/tunnel"
     9  
    10  	"github.com/go-chi/chi/v5"
    11  	"github.com/go-chi/render"
    12  )
    13  
    14  func proxyProviderRouter() http.Handler {
    15  	r := chi.NewRouter()
    16  	r.Get("/", getProviders)
    17  
    18  	r.Route("/{name}", func(r chi.Router) {
    19  		r.Use(parseProviderName, findProviderByName)
    20  		r.Get("/", getProvider)
    21  		r.Put("/", updateProvider)
    22  		r.Get("/healthcheck", healthCheckProvider)
    23  	})
    24  	return r
    25  }
    26  
    27  func getProviders(w http.ResponseWriter, r *http.Request) {
    28  	providers := tunnel.Providers()
    29  	render.JSON(w, r, render.M{
    30  		"providers": providers,
    31  	})
    32  }
    33  
    34  func getProvider(w http.ResponseWriter, r *http.Request) {
    35  	provider := r.Context().Value(CtxKeyProvider).(provider.ProxyProvider)
    36  	render.JSON(w, r, provider)
    37  }
    38  
    39  func updateProvider(w http.ResponseWriter, r *http.Request) {
    40  	provider := r.Context().Value(CtxKeyProvider).(provider.ProxyProvider)
    41  	if err := provider.Update(); err != nil {
    42  		render.Status(r, http.StatusServiceUnavailable)
    43  		render.JSON(w, r, newError(err.Error()))
    44  		return
    45  	}
    46  	render.NoContent(w, r)
    47  }
    48  
    49  func healthCheckProvider(w http.ResponseWriter, r *http.Request) {
    50  	provider := r.Context().Value(CtxKeyProvider).(provider.ProxyProvider)
    51  	provider.HealthCheck()
    52  	render.NoContent(w, r)
    53  }
    54  
    55  func parseProviderName(next http.Handler) http.Handler {
    56  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    57  		name := getEscapeParam(r, "name")
    58  		ctx := context.WithValue(r.Context(), CtxKeyProviderName, name)
    59  		next.ServeHTTP(w, r.WithContext(ctx))
    60  	})
    61  }
    62  
    63  func findProviderByName(next http.Handler) http.Handler {
    64  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    65  		name := r.Context().Value(CtxKeyProviderName).(string)
    66  		providers := tunnel.Providers()
    67  		provider, exist := providers[name]
    68  		if !exist {
    69  			render.Status(r, http.StatusNotFound)
    70  			render.JSON(w, r, ErrNotFound)
    71  			return
    72  		}
    73  
    74  		ctx := context.WithValue(r.Context(), CtxKeyProvider, provider)
    75  		next.ServeHTTP(w, r.WithContext(ctx))
    76  	})
    77  }