-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrequest.go
87 lines (73 loc) · 1.75 KB
/
request.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
package main
import (
"context"
"errors"
"net/http"
"net/url"
"promproxy/resolver"
"regexp"
"strconv"
"strings"
)
var targetRegex = regexp.MustCompile("^([^:]*)(?::(.+))?$")
type basicAuth struct {
username string
password string
}
type request struct {
host string
port int
path string
resolver resolver.Resolver
basicAuth *basicAuth
headers http.Header
}
func parseRequest(ctx context.Context, url *url.URL) (*request, error) {
parts := strings.Split(url.Path, "/")
matches := targetRegex.FindStringSubmatch(parts[1])
if len(matches) != 3 {
return nil, errors.New("Invalid URL")
}
request := request{
host: matches[1],
port: 80,
path: parts[2],
headers: http.Header{},
}
if matches[2] != "" {
port, err := strconv.Atoi(matches[2])
if err != nil {
return nil, errors.New("Invalid target port")
}
request.port = port
}
if basicAuthParam := url.Query().Get("basic_auth"); basicAuthParam != "" {
userAndPwd := strings.SplitN(basicAuthParam, ":", 2)
// TODO: check array bounds
request.basicAuth = &basicAuth{username: userAndPwd[0], password: userAndPwd[1]}
}
for _, reqHeader := range url.Query()["header"] {
keyAndValue := strings.SplitN(reqHeader, ":", 2)
if len(keyAndValue) == 2 {
request.headers.Add(keyAndValue[0], keyAndValue[1])
}
}
if request.host == "localhost" {
request.resolver = resolver.NewLocalhostResolver()
} else {
// var r resolver.Resolver
switch url.Query().Get("lookup") {
case "dns":
request.resolver = resolver.NewDNSResolver()
case "docker":
r, err := resolver.NewDockerResolver(ctx)
if err != nil {
return nil, err
}
request.resolver = r
default:
request.resolver = resolver.NewDNSResolver()
}
}
return &request, nil
}