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 ( "bytes" "compress/gzip" "flag" "fmt" "io" "io/ioutil" "net/http" "net/http/httputil" "net/url" "strconv" )
var remoteHost *string var referrer *string var myApiHost *string var myApiHostSchema *string
func main() { port := flag.Int("p", 80, "HTTP API Port") remoteHost = flag.String("r", "target.host", "Remote Host") referrer = flag.String("f", "target.host", "Referrer") myApiHost = flag.String("m", "localhost", "My API Host") myApiHostSchema = flag.String("s", "http", "My API Host Schema") flag.Parse()
url, err := url.Parse("https://" + *remoteHost) if err != nil { panic(err) }
director := func(req *http.Request) { req.URL.Scheme = url.Scheme req.URL.Host = url.Host req.Host = url.Host req.Header.Set("Referer", "https://"+*referrer+"/") req.Header.Set("Origin", "https://"+*referrer) req.Header.Set("authority", *remoteHost) }
reverseProxy := httputil.NewSingleHostReverseProxy(url) reverseProxy.Director = director reverseProxy.ModifyResponse = rewriteBody handler := handler{proxy: reverseProxy} http.Handle("/", handler)
http.ListenAndServe(fmt.Sprintf(":%d", *port), nil) }
type handler struct { proxy *httputil.ReverseProxy }
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.proxy.ServeHTTP(w, r) }
func rewriteBody(resp *http.Response) (err error) { var reader io.ReadCloser switch resp.Header.Get("Content-Encoding") { case "gzip": reader, err = gzip.NewReader(resp.Body) defer reader.Close() default: reader = resp.Body } delete(resp.Header, "Content-Encoding")
b, err := ioutil.ReadAll(reader)
if err != nil { return err }
err = resp.Body.Close() if err != nil { return err } b = bytes.Replace(b, []byte("https:\\/\\/"+*remoteHost), []byte(*myApiHostSchema+":\\/\\/"+*myApiHost), -1) body := ioutil.NopCloser(bytes.NewReader(b)) resp.Body = body resp.ContentLength = int64(len(b)) resp.Header.Set("Content-Length", strconv.Itoa(len(b))) return nil }
|