lightweight go reverse proxy for ollama with bearer token authentication
go proxy ollama
at v1.0.0 1.8 kB view raw
1package main 2 3import ( 4 "fmt" 5 "net/http" 6 "net/http/httputil" 7 "net/url" 8 "strings" 9) 10 11// authMiddleware validates Bearer token authorization 12func authMiddleware(token string) func(http.Handler) http.Handler { 13 return func(next http.Handler) http.Handler { 14 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 15 authHeader := r.Header.Get("Authorization") 16 if authHeader == "" { 17 http.Error(w, "Unauthorized", http.StatusUnauthorized) 18 return 19 } 20 21 parts := strings.SplitN(authHeader, " ", 2) 22 if len(parts) != 2 || parts[0] != "Bearer" { 23 http.Error(w, "Unauthorized", http.StatusUnauthorized) 24 return 25 } 26 27 if parts[1] == "" || parts[1] != token { 28 http.Error(w, "Unauthorized", http.StatusUnauthorized) 29 return 30 } 31 32 next.ServeHTTP(w, r) 33 }) 34 } 35} 36 37// newProxy creates a reverse proxy for the target URL 38func newProxy(targetURL string) (*httputil.ReverseProxy, error) { 39 if targetURL == "" { 40 return nil, fmt.Errorf("target URL cannot be empty") 41 } 42 43 target, err := url.Parse(targetURL) 44 if err != nil { 45 return nil, fmt.Errorf("invalid target URL: %w", err) 46 } 47 48 if target.Scheme == "" || target.Host == "" { 49 return nil, fmt.Errorf("invalid target URL: missing scheme or host") 50 } 51 52 proxy := httputil.NewSingleHostReverseProxy(target) 53 54 // Customize the request before sending to backend 55 originalDirector := proxy.Director 56 proxy.Director = func(req *http.Request) { 57 originalDirector(req) 58 59 // Remove proxy headers to make it look like a local request 60 req.Header.Del("X-Forwarded-For") 61 req.Header.Del("X-Forwarded-Host") 62 req.Header.Del("X-Forwarded-Proto") 63 req.Header.Del("Via") 64 req.Header.Del("Authorization") 65 66 // Set Host to the target host to make it appear local 67 req.Host = target.Host 68 } 69 70 return proxy, nil 71}