package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
)
//将request转发给 http://127.0.0.1:2003
func helloHandler(w http.ResponseWriter, r *http.Request) {
trueServer := "http://127.0.0.1:2003"
url, err := url.Parse(trueServer)
if err != nil {
log.Println(err)
return
}
proxy := httputil.NewSingleHostReverseProxy(url)
proxy.ServeHTTP(w, r)
}
func main() {
http.HandleFunc("/hello", helloHandler)
log.Fatal(http.ListenAndServe(":2002", nil))
}
package main
import (
"io"
"net/http"
"log"
)
func helloHandler(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "hello, world!\n")
}
func main() {
http.HandleFunc("/hello", helloHandler)
log.Fatal(http.ListenAndServe(":2003", nil))
}
访问http://127.0.0.1:2002/hello,返回hello, world!
golang实现反向代理将前端传来的/dcv/:host/请求转发到https://" + host + ":8443
package dcvproxy
import (
"net/http"
"strings"
"net"
"net/http/httputil"
"net/url"
"crypto/tls"
stdlog "log"
"os"
"time"
"github.com/labstack/echo/v4"
)
// Represents httpd handler.
type Handler struct {
}
// Creates handler instance.
func New() *Handler {
return &Handler{}
}
func (h *Handler) Handle(c echo.Context) error {
// wrap standard log to logrus
stdLogger := stdlog.New(os.Stdout, "", stdlog.Ldate|stdlog.Lmicroseconds)
stdLogger.SetFlags(0)
stdLogger.SetOutput(&log2LogrusWriter{
entry: logProxy,
})
// route: /dcv/:host/
host := c.Param("Host")
var tlsConfig = &tls.Config{
InsecureSkipVerify: true,
}
dcvURL := "https://" + host + ":8443"
target, err := url.Parse(dcvURL)
if err != nil {
log.Errorf("url.Parse failed: url=%s error=%v", dcvURL, err)
return nil
}
var transport http.RoundTripper = &http.Transport{
Proxy: nil, // http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: tlsConfig,
// Set this value so that the underlying transport round-tripper
// doesn't try to auto decode the body of objects with
// content-encoding set to `gzip`.
//
// Refer:
// https://golang.org/src/net/http/transport.go?h=roundTrip#L1843
DisableCompression: true,
}
proxy := httputil.NewSingleHostReverseProxy(target)
proxy.Transport = transport
proxy.ErrorLog = stdLogger
proxy.ModifyResponse = func(r *http.Response) error {
r.Header.Del("X-Frame-Options")
return nil
}
r := c.Request()
r.URL.Path = "/" + strings.TrimPrefix(r.URL.Path, "/dcv/" + host + "/")
proxy.ServeHTTP(c.Response(), r)
return nil
}