-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrevproxy.go
More file actions
95 lines (80 loc) · 1.96 KB
/
revproxy.go
File metadata and controls
95 lines (80 loc) · 1.96 KB
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
93
94
95
package main
import (
"flag"
"fmt"
"log"
"net/http"
"net/http/httputil"
"net/url"
"os"
"strings"
)
const (
formatReset = "\033[0m"
formatBold = "\033[1m"
formatCyan = "\033[36m"
formatGray = "\033[90m"
formatBlack = "\033[30m"
formatYellow = "\033[33m"
)
var renderColors *bool
func usage() {
fmt.Println("Usage: revproxy [OPTIONS] target")
flag.PrintDefaults()
}
func main() {
flag.Usage = usage
port := flag.Uint("port", 8080, "proxy port")
host := flag.String("host", "", "override host header")
printHeaders := flag.Bool("H", false, "print request headers")
renderColors = flag.Bool("color", false, "format output with colors")
flag.Parse()
if flag.NArg() < 1 {
flag.Usage()
os.Exit(1)
}
target, err := url.Parse(flag.Arg(0))
if err != nil || target.Host == "" {
log.Panicf("invalid target URL: %s", target)
}
if *host == "" {
*host = target.Host
}
questionMark := format("?", formatBlack)
equals := format("=", formatGray)
ampersand := format("&", formatBlack)
proxy := httputil.NewSingleHostReverseProxy(target)
director := proxy.Director
proxy.Director = func(r *http.Request) {
serving := format(r.URL.Path, formatYellow)
if r.URL.RawQuery != "" {
serving += questionMark
var kvs []string
for name, values := range r.URL.Query() {
for _, value := range values {
kvs = append(kvs, format(name, formatCyan)+equals+value)
}
}
serving += strings.Join(kvs, ampersand)
}
log.Printf("%s %s", format(r.Method, formatBold), serving)
if *printHeaders {
for name, values := range r.Header {
value := strings.Join(values, "; ")
log.Printf("%s: %s", format(name, formatGray), value)
}
}
director(r)
r.Host = *host
}
addr := fmt.Sprintf("0.0.0.0:%d", *port)
log.Printf("proxying %s at %s", target, addr)
http.Handle("/", proxy)
http.ListenAndServe(addr, nil)
}
func format(value, format string) string {
if *renderColors {
return format + value + formatReset
}
return value
}