summaryrefslogtreecommitdiff
path: root/handlers/proxy.go
blob: d1f6def60e8958cb4a4b46e1ee3812395913ca16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package handlers

import (
	"auth-proxy/logging"
	"auth-proxy/worker"
	"net/http"
	"net/http/httputil"
	"net/url"
)

// NewProxy creates a new reverse proxy handler using httputil.ReverseProxy.
func NewProxy(targetURL string) http.Handler {
	target, err := url.Parse(targetURL)
	if err != nil {
		panic("Invalid target URL: " + err.Error())
	}

	proxy := httputil.NewSingleHostReverseProxy(target)

	// The default director is mostly fine, but we want to log and ensure the Host header is correct.
	director := proxy.Director
	proxy.Director = func(req *http.Request) {
		director(req)          // Run the default director
		req.Host = target.Host // Set the Host header to the target's host

		// Asynchronously log the proxying action to avoid blocking the request.
		urlStr := req.URL.String()
		ip := logging.GetClientIP(req)
		worker.Submit(workerPool, func() {
			logging.AppLog.Info("Proxying request", "url", urlStr, "ip", ip)
		})
	}

	// Custom error handler for logging
	proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
		ip := logging.GetClientIP(r)
		// Asynchronously log the proxy error to avoid blocking the response.
		worker.Submit(workerPool, func() {
			logging.AppLog.Error("Proxy error", "error", err, "ip", ip)
		})
		http.Error(w, "Proxy Error", http.StatusBadGateway)
	}

	return proxy
}