Example #1
0
func (rp *FastReverseProxy) serveWebsocket(dstHost string, reqData *RequestData, ctx *fasthttp.RequestCtx) {
	req := &ctx.Request
	uri := req.URI()
	uri.SetHost(dstHost)
	dstConn, err := rp.dialFunc(dstHost)
	if err != nil {
		log.LogError(reqData.String(), string(uri.Path()), err)
		return
	}
	if clientIP, _, err := net.SplitHostPort(ctx.RemoteAddr().String()); err == nil {
		if prior := string(req.Header.Peek("X-Forwarded-For")); len(prior) > 0 {
			clientIP = prior + ", " + clientIP
		}
		req.Header.Set("X-Forwarded-For", clientIP)
	}
	_, err = req.WriteTo(dstConn)
	if err != nil {
		log.LogError(reqData.String(), string(uri.Path()), err)
		return
	}
	ctx.Hijack(func(conn net.Conn) {
		defer dstConn.Close()
		defer conn.Close()
		errc := make(chan error, 2)
		cp := func(dst io.Writer, src io.Reader) {
			_, err := io.Copy(dst, src)
			errc <- err
		}
		go cp(dstConn, conn)
		go cp(conn, dstConn)
		<-errc
	})
}