-
Notifications
You must be signed in to change notification settings - Fork 1
/
httputil.go
92 lines (80 loc) · 2 KB
/
httputil.go
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package util
import (
"net"
"net/http"
"net/url"
"strings"
)
func GetSchemeHost(request *http.Request) (string, string) {
host := GetHost(request)
scheme := getScheme(request, host)
return scheme, host
}
// Calculate the path. If a header X-Forwarded-Prefix is found, the result is prefixed
func GetPath(path string, request *http.Request) string {
forwardedPrefix := getForwardedHeader(request, "Prefix")
if forwardedPrefix != "" {
path = join(forwardedPrefix, path)
}
return path
}
func join(first string, second string) string {
result := first
if !strings.HasSuffix(result, "/") {
result = result + "/"
}
return result + strings.TrimPrefix(second, "/")
}
func getScheme(request *http.Request, host string) string {
port := ""
if _, p, err := net.SplitHostPort(host); err == nil {
port = p
}
forwardedProto := getForwardedHeader(request, "Proto")
scheme := ""
switch {
case forwardedProto != "":
scheme = forwardedProto
case request.TLS != nil:
scheme = "https"
case request.URL.Scheme != "":
scheme = request.URL.Scheme
case port == "443":
scheme = "https"
default:
scheme = "http"
}
return scheme
}
// Get the host from the request values with the following priority:
// 1. Header X-Forwarded-Host
// 2. host from request
// 3. host from request.URL
func GetHost(request *http.Request) string {
host := ""
forwardedHost := getForwardedHeader(request, "Host")
switch {
case forwardedHost != "":
host = forwardedHost
case request.Host != "":
host = request.Host
case request.URL.Host != "":
host = request.URL.Host
}
return host
}
func getForwardedHeader(req *http.Request, prefix string) string {
headerList := req.Header.Get("X-Forwarded-" + prefix)
headerValue := strings.SplitN(headerList, ",", 2)[0]
return strings.TrimSpace(headerValue)
}
func GetUrl(path string, request *http.Request) string {
scheme, host := GetSchemeHost(request)
fullPath := GetPath(path, request)
url := url.URL{
Scheme: scheme,
Host: host,
Path: fullPath,
}
return url.String()
}