blob: 920e89e54f67cf2cab47826079b25a0f365f6511 [file] [log] [blame]
Serge Bazanskiebe60752021-09-16 11:28:00 +02001package main
2
3import (
4 "flag"
5 "fmt"
6 "log"
7 "net"
8 "net/http"
9 "net/http/httputil"
10)
11
12var (
13 flagUpstream string
14 flagUpstreamHost string
15 flagDownstreamHost string
16 flagListen string
17)
18
19func newProxy() http.Handler {
20 proxy := httputil.ReverseProxy{
21 Director: func(r *http.Request) {
22 r.URL.Scheme = "http"
23 r.URL.Host = flagUpstream
24 r.Host = flagUpstreamHost
25 // MMR reads this field and prioritizes it over the Host header.
26 r.Header.Set("X-Forwarded-Host", flagUpstreamHost)
27 },
28 }
29
30 acl := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
31 remote := r.RemoteAddr
32 sip := r.Header.Get("Hscloud-Nic-Source-IP")
33 sport := r.Header.Get("Hscloud-Nic-Source-Port")
34 if sip != "" && sport != "" {
35 remote = net.JoinHostPort(sip, sport)
36 r.Header.Set("X-Forwarded-For", remote)
37 }
38 log.Printf("%s %s %s", remote, r.Method, r.URL.Path)
39
40 // ... during federation requests, Host is foo.example.com:443, strip
41 // that out if that's the case. Ignore port number, we don't care about
42 // it.
43 host, _, err := net.SplitHostPort(r.Host)
44 if err != nil {
45 // Error can mean many things, but generally it means 'no port', or
46 // a very malformed host. Regardless, just default to the raw
47 // value, we explicitly check it against a required host value
48 // further down
49 host = r.Host
50 }
51
52 if host != flagDownstreamHost {
53 log.Printf("Invalid host requested %q, wanted %q", r.Host, flagDownstreamHost)
54 w.WriteHeader(http.StatusBadRequest)
55 fmt.Fprintf(w, "invalid host\n")
56 return
57 }
58 proxy.ServeHTTP(w, r)
59 })
60
61 return acl
62}
63
64func main() {
65 flag.StringVar(&flagUpstreamHost, "upstream_host", "hackerspace.pl", "Upstream Host header, as sent to upstream")
66 flag.StringVar(&flagUpstream, "upstream", "foo.bar.svc.cluster.local:8080", "Address and port to reach upstream")
67 flag.StringVar(&flagDownstreamHost, "downstream_host", "matrix.hackerspace.pl", "Downstream Host header, as requested by client traffic")
68 flag.StringVar(&flagListen, "listen", ":8080", "Address to listen at for downstream traffic")
69 flag.Parse()
70
71 log.Printf("Starting media-repo-proxy")
72
73 proxy := newProxy()
74
75 log.Printf("Listening on %s...", flagListen)
76 if err := http.ListenAndServe(flagListen, proxy); err != nil {
77 log.Printf("Listen failed: %v", err)
78 }
79}