1package util
2
3import (
4	"net/http"
5
6	middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
7)
8
9const (
10	XForwardedProto = "X-Forwarded-Proto"
11	XForwardedHost  = "X-Forwarded-Host"
12	XForwardedURI   = "X-Forwarded-Uri"
13)
14
15// GetRequestProto returns the request scheme or X-Forwarded-Proto if present
16// and the request is proxied.
17func GetRequestProto(req *http.Request) string {
18	proto := req.Header.Get(XForwardedProto)
19	if !IsProxied(req) || proto == "" {
20		proto = req.URL.Scheme
21	}
22	return proto
23}
24
25// GetRequestHost returns the request host header or X-Forwarded-Host if
26// present and the request is proxied.
27func GetRequestHost(req *http.Request) string {
28	host := req.Header.Get(XForwardedHost)
29	if !IsProxied(req) || host == "" {
30		host = req.Host
31	}
32	return host
33}
34
35// GetRequestURI return the request URI or X-Forwarded-Uri if present and the
36// request is proxied.
37func GetRequestURI(req *http.Request) string {
38	uri := req.Header.Get(XForwardedURI)
39	if !IsProxied(req) || uri == "" {
40		// Use RequestURI to preserve ?query
41		uri = req.URL.RequestURI()
42	}
43	return uri
44}
45
46// IsProxied determines if a request was from a proxy based on the RequestScope
47// ReverseProxy tracker.
48func IsProxied(req *http.Request) bool {
49	scope := middlewareapi.GetRequestScope(req)
50	if scope == nil {
51		return false
52	}
53	return scope.ReverseProxy
54}
55
56func IsForwardedRequest(req *http.Request) bool {
57	return IsProxied(req) &&
58		req.Host != GetRequestHost(req)
59}
60