add more tests

This commit is contained in:
ginuerzh 2018-12-26 20:24:20 +08:00
parent d3b03e4231
commit bb1afcc437
7 changed files with 608 additions and 45 deletions

21
Dockerfile.mod Normal file
View File

@ -0,0 +1,21 @@
FROM golang:1-alpine as builder
RUN apk add --no-cache musl-dev git gcc
ADD . /data
WORKDIR /data
ENV GO111MODULE=on
RUN cd cmd/gost && go build
FROM alpine:latest
WORKDIR /bin/
COPY --from=builder /data/cmd/gost/gost .
RUN /bin/gost -V
ENTRYPOINT ["/bin/gost"]

View File

@ -110,6 +110,8 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
wsOpts.WriteBufferSize = node.GetInt("wbuf") wsOpts.WriteBufferSize = node.GetInt("wbuf")
wsOpts.UserAgent = node.Get("agent") wsOpts.UserAgent = node.Get("agent")
var host string
var tr gost.Transporter var tr gost.Transporter
switch node.Transport { switch node.Transport {
case "tls": case "tls":
@ -160,6 +162,7 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
case "obfs4": case "obfs4":
tr = gost.Obfs4Transporter() tr = gost.Obfs4Transporter()
case "ohttp": case "ohttp":
host = node.Get("host")
tr = gost.ObfsHTTPTransporter() tr = gost.ObfsHTTPTransporter()
default: default:
tr = gost.TCPTransporter() tr = gost.TCPTransporter()
@ -197,9 +200,12 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
gost.TimeoutDialOption(time.Duration(timeout)*time.Second), gost.TimeoutDialOption(time.Duration(timeout)*time.Second),
) )
if host == "" {
host = node.Host
}
handshakeOptions := []gost.HandshakeOption{ handshakeOptions := []gost.HandshakeOption{
gost.AddrHandshakeOption(node.Addr), gost.AddrHandshakeOption(node.Addr),
gost.HostHandshakeOption(node.Host), gost.HostHandshakeOption(host),
gost.UserHandshakeOption(node.User), gost.UserHandshakeOption(node.User),
gost.TLSConfigHandshakeOption(tlsCfg), gost.TLSConfigHandshakeOption(tlsCfg),
gost.IntervalHandshakeOption(time.Duration(node.GetInt("ping")) * time.Second), gost.IntervalHandshakeOption(time.Duration(node.GetInt("ping")) * time.Second),

View File

@ -34,6 +34,11 @@ func HTTP2Connector(user *url.Userinfo) Connector {
} }
func (c *http2Connector) Connect(conn net.Conn, addr string, options ...ConnectOption) (net.Conn, error) { func (c *http2Connector) Connect(conn net.Conn, addr string, options ...ConnectOption) (net.Conn, error) {
opts := &ConnectOptions{}
for _, option := range options {
option(opts)
}
cc, ok := conn.(*http2ClientConn) cc, ok := conn.(*http2ClientConn)
if !ok { if !ok {
return nil, errors.New("wrong connection type") return nil, errors.New("wrong connection type")
@ -142,7 +147,7 @@ func (tr *http2Transporter) Dial(addr string, options ...DialOption) (net.Conn,
} }
client = &http.Client{ client = &http.Client{
Transport: &transport, Transport: &transport,
Timeout: timeout, // Timeout: timeout,
} }
tr.clients[addr] = client tr.clients[addr] = client
} }
@ -214,7 +219,7 @@ func (tr *h2Transporter) Dial(addr string, options ...DialOption) (net.Conn, err
} }
client = &http.Client{ client = &http.Client{
Transport: &transport, Transport: &transport,
Timeout: timeout, // Timeout: timeout,
} }
tr.clients[addr] = client tr.clients[addr] = client
} }

49
obfs.go
View File

@ -67,10 +67,7 @@ func (l *obfsHTTPListener) Accept() (net.Conn, error) {
type obfsHTTPConn struct { type obfsHTTPConn struct {
net.Conn net.Conn
host string host string
request *http.Request buf []byte
response *http.Response
rbuf []byte
wbuf []byte
isServer bool isServer bool
handshaked bool handshaked bool
handshakeMutex sync.Mutex handshakeMutex sync.Mutex
@ -99,19 +96,19 @@ func (c *obfsHTTPConn) Handshake() (err error) {
func (c *obfsHTTPConn) serverHandshake() (err error) { func (c *obfsHTTPConn) serverHandshake() (err error) {
br := bufio.NewReader(c.Conn) br := bufio.NewReader(c.Conn)
c.request, err = http.ReadRequest(br) r, err := http.ReadRequest(br)
if err != nil { if err != nil {
return return
} }
if Debug { if Debug {
dump, _ := httputil.DumpRequest(c.request, false) dump, _ := httputil.DumpRequest(r, false)
log.Logf("[ohttp] %s -> %s\n%s", c.Conn.RemoteAddr(), c.Conn.LocalAddr(), string(dump)) log.Logf("[ohttp] %s -> %s\n%s", c.Conn.RemoteAddr(), c.Conn.LocalAddr(), string(dump))
} }
if br.Buffered() > 0 { if r.ContentLength > 0 {
c.rbuf, err = br.Peek(br.Buffered()) c.buf, err = ioutil.ReadAll(r.Body)
} else { } else {
c.rbuf, err = ioutil.ReadAll(c.request.Body) c.buf, err = br.Peek(br.Buffered())
} }
if err != nil { if err != nil {
@ -120,13 +117,13 @@ func (c *obfsHTTPConn) serverHandshake() (err error) {
} }
b := bytes.Buffer{} b := bytes.Buffer{}
if c.request.Header.Get("Upgrade") == "websocket" { if r.Header.Get("Upgrade") == "websocket" {
b.WriteString("HTTP/1.1 101 Switching Protocols\r\n") b.WriteString("HTTP/1.1 101 Switching Protocols\r\n")
b.WriteString("Server: nginx/1.10.0\r\n") b.WriteString("Server: nginx/1.10.0\r\n")
b.WriteString("Date: " + time.Now().Format(time.RFC1123) + "\r\n") b.WriteString("Date: " + time.Now().Format(time.RFC1123) + "\r\n")
b.WriteString("Connection: Upgrade\r\n") b.WriteString("Connection: Upgrade\r\n")
b.WriteString("Upgrade: websocket\r\n") b.WriteString("Upgrade: websocket\r\n")
b.WriteString(fmt.Sprintf("Sec-WebSocket-Accept: %s\r\n", computeAcceptKey(c.request.Header.Get("Sec-WebSocket-Key")))) b.WriteString(fmt.Sprintf("Sec-WebSocket-Accept: %s\r\n", computeAcceptKey(r.Header.Get("Sec-WebSocket-Key"))))
b.WriteString("\r\n") b.WriteString("\r\n")
} else { } else {
b.WriteString("HTTP/1.1 200 OK\r\n") b.WriteString("HTTP/1.1 200 OK\r\n")
@ -146,24 +143,19 @@ func (c *obfsHTTPConn) serverHandshake() (err error) {
} }
func (c *obfsHTTPConn) clientHandshake() (err error) { func (c *obfsHTTPConn) clientHandshake() (err error) {
r := c.request r := &http.Request{
if r == nil {
r = &http.Request{
Method: http.MethodGet, Method: http.MethodGet,
ProtoMajor: 1, ProtoMajor: 1,
ProtoMinor: 1, ProtoMinor: 1,
URL: &url.URL{Scheme: "http", Host: c.host}, URL: &url.URL{Scheme: "http", Host: c.host},
Header: make(http.Header), Header: make(http.Header),
} }
r.Header.Set("Connection", "keep-alive") r.Header.Set("User-Agent", "curl/7.49.1")
r.Header.Set("Connection", "Upgrade")
r.Header.Set("Upgrade", "websocket") r.Header.Set("Upgrade", "websocket")
r.Header.Set("User-Agent", DefaultUserAgent) key, _ := generateChallengeKey()
if len(c.wbuf) > 0 { r.Header.Set("Sec-WebSocket-Key", key)
log.Log("write buf", len(c.wbuf))
r.Body = ioutil.NopCloser(bytes.NewReader(c.wbuf))
r.ContentLength = int64(len(c.wbuf))
}
}
if err = r.Write(c.Conn); err != nil { if err = r.Write(c.Conn); err != nil {
return return
} }
@ -182,6 +174,7 @@ func (c *obfsHTTPConn) clientHandshake() (err error) {
dump, _ := httputil.DumpResponse(resp, false) dump, _ := httputil.DumpResponse(resp, false)
log.Logf("[ohttp] %s <- %s\n%s", c.Conn.LocalAddr(), c.Conn.RemoteAddr(), string(dump)) log.Logf("[ohttp] %s <- %s\n%s", c.Conn.LocalAddr(), c.Conn.RemoteAddr(), string(dump))
} }
return nil return nil
} }
@ -189,24 +182,18 @@ func (c *obfsHTTPConn) Read(b []byte) (n int, err error) {
if err = c.Handshake(); err != nil { if err = c.Handshake(); err != nil {
return return
} }
if len(c.rbuf) > 0 { if len(c.buf) > 0 {
n = copy(b, c.rbuf) n = copy(b, c.buf)
c.rbuf = c.rbuf[n:] c.buf = c.buf[n:]
return return
} }
return c.Conn.Read(b) return c.Conn.Read(b)
} }
func (c *obfsHTTPConn) Write(b []byte) (n int, err error) { func (c *obfsHTTPConn) Write(b []byte) (n int, err error) {
handshaked := c.handshaked
c.wbuf = b
if err = c.Handshake(); err != nil { if err = c.Handshake(); err != nil {
return return
} }
if !handshaked {
n = len(c.wbuf)
return
}
return c.Conn.Write(b) return c.Conn.Write(b)
} }

371
obfs_test.go Normal file
View File

@ -0,0 +1,371 @@
package gost
import (
"crypto/rand"
"fmt"
"net/http/httptest"
"net/url"
"testing"
)
func httpOverObfsHTTPRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := ObfsHTTPListener("")
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: ObfsHTTPTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverObfsHTTP(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverObfsHTTPRoundtrip(httpSrv.URL, sendData, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTPOverObfsHTTP(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := ObfsHTTPListener("")
if err != nil {
b.Error(err)
}
// b.Log(ln.Addr())
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: ObfsHTTPTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
go server.Run()
defer server.Close()
for i := 0; i < b.N; i++ {
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
b.Error(err)
}
}
}
func BenchmarkHTTPOverObfsHTTPParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := ObfsHTTPListener("")
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: ObfsHTTPTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
go server.Run()
defer server.Close()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
b.Error(err)
}
}
})
}
func socks5OverObfsHTTPRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := ObfsHTTPListener("")
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: ObfsHTTPTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverObfsHTTP(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
err := socks5OverObfsHTTPRoundtrip(httpSrv.URL, sendData,
tc.cliUser,
tc.srvUsers,
)
if err == nil {
if !tc.pass {
t.Errorf("#%d should failed", i)
}
} else {
// t.Logf("#%d %v", i, err)
if tc.pass {
t.Errorf("#%d got error: %v", i, err)
}
}
}
}
func socks4OverObfsHTTPRoundtrip(targetURL string, data []byte) error {
ln, err := ObfsHTTPListener("")
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: ObfsHTTPTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverObfsHTTP(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverObfsHTTPRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverObfsHTTPRoundtrip(targetURL string, data []byte) error {
ln, err := ObfsHTTPListener("")
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: ObfsHTTPTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverObfsHTTP(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverObfsHTTPRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverObfsHTTPRoundtrip(targetURL string, data []byte,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := ObfsHTTPListener("")
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: ObfsHTTPTransporter(),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverObfsHTTP(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range ssProxyTests {
err := ssOverObfsHTTPRoundtrip(httpSrv.URL, sendData,
tc.clientCipher,
tc.serverCipher,
)
if err == nil {
if !tc.pass {
t.Errorf("#%d should failed", i)
}
} else {
// t.Logf("#%d %v", i, err)
if tc.pass {
t.Errorf("#%d got error: %v", i, err)
}
}
}
}
func sniOverObfsHTTPRoundtrip(targetURL string, data []byte, host string) error {
ln, err := ObfsHTTPListener("")
if err != nil {
return err
}
u, err := url.Parse(targetURL)
if err != nil {
return err
}
client := &Client{
Connector: SNIConnector(host),
Transporter: ObfsHTTPTransporter(),
}
server := &Server{
Listener: ln,
Handler: SNIHandler(HostHandlerOption(u.Host)),
}
go server.Run()
defer server.Close()
return sniRoundtrip(client, server, targetURL, data)
}
func TestSNIOverObfsHTTP(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
httpsSrv := httptest.NewTLSServer(httpTestHandler)
defer httpsSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
var sniProxyTests = []struct {
targetURL string
host string
pass bool
}{
{httpSrv.URL, "", true},
{httpSrv.URL, "example.com", true},
{httpsSrv.URL, "", true},
{httpsSrv.URL, "example.com", true},
}
for i, tc := range sniProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := sniOverObfsHTTPRoundtrip(tc.targetURL, sendData, tc.host)
if err == nil {
if !tc.pass {
t.Errorf("#%d should failed", i)
}
} else {
// t.Logf("#%d %v", i, err)
if tc.pass {
t.Errorf("#%d got error: %v", i, err)
}
}
})
}
}

13
ssh.go
View File

@ -95,13 +95,15 @@ func (c *sshRemoteForwardConnector) Connect(conn net.Conn, addr string, options
if err != nil { if err != nil {
return return
} }
log.Log("[ssh-rtcp] listening on", ln.Addr())
for { for {
rc, err := ln.Accept() rc, err := ln.Accept()
if err != nil { if err != nil {
log.Logf("[ssh-rtcp] %s <-> %s accpet : %s", ln.Addr(), addr, err) log.Logf("[ssh-rtcp] %s <-> %s accpet : %s", ln.Addr(), addr, err)
return return
} }
// log.Log("[ssh-rtcp] accept", rc.LocalAddr(), rc.RemoteAddr())
select { select {
case cc.session.connChan <- rc: case cc.session.connChan <- rc:
default: default:
@ -593,7 +595,6 @@ func (h *sshForwardHandler) tcpipForwardRequest(sshConn ssh.Conn, req *ssh.Reque
return return
} }
log.Log("[ssh-rtcp] listening on tcp", addr)
ln, err := net.Listen("tcp", addr) //tie to the client connection ln, err := net.Listen("tcp", addr) //tie to the client connection
if err != nil { if err != nil {
log.Log("[ssh-rtcp]", err) log.Log("[ssh-rtcp]", err)
@ -602,6 +603,8 @@ func (h *sshForwardHandler) tcpipForwardRequest(sshConn ssh.Conn, req *ssh.Reque
} }
defer ln.Close() defer ln.Close()
log.Log("[ssh-rtcp] listening on tcp", ln.Addr())
replyFunc := func() error { replyFunc := func() error {
if t.Port == 0 && req.WantReply { // Client sent port 0. let them know which port is actually being used if t.Port == 0 && req.WantReply { // Client sent port 0. let them know which port is actually being used
_, port, err := getHostPortFromAddr(ln.Addr()) _, port, err := getHostPortFromAddr(ln.Addr())
@ -850,15 +853,15 @@ func (c *sshNopConn) RemoteAddr() net.Addr {
} }
func (c *sshNopConn) SetDeadline(t time.Time) error { func (c *sshNopConn) SetDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} return &net.OpError{Op: "set", Net: "ssh", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
} }
func (c *sshNopConn) SetReadDeadline(t time.Time) error { func (c *sshNopConn) SetReadDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} return &net.OpError{Op: "set", Net: "ssh", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
} }
func (c *sshNopConn) SetWriteDeadline(t time.Time) error { func (c *sshNopConn) SetWriteDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} return &net.OpError{Op: "set", Net: "ssh", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
} }
type sshConn struct { type sshConn struct {

View File

@ -4,11 +4,181 @@ import (
"crypto/rand" "crypto/rand"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"net"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"testing" "testing"
) )
func sshDirectForwardRoundtrip(targetURL string, data []byte) error {
ln, err := TCPListener("")
if err != nil {
return err
}
client := &Client{
Connector: SSHDirectForwardConnector(),
Transporter: SSHForwardTransporter(),
}
server := &Server{
Listener: ln,
Handler: SSHForwardHandler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSHDirectForward(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := sshDirectForwardRoundtrip(httpSrv.URL, sendData)
if err != nil {
t.Error(err)
}
}
func BenchmarkSSHDirectForward(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := TCPListener("")
if err != nil {
b.Error(err)
}
client := &Client{
Connector: SSHDirectForwardConnector(),
Transporter: SSHForwardTransporter(),
}
server := &Server{
Listener: ln,
Handler: SSHForwardHandler(),
}
go server.Run()
defer server.Close()
for i := 0; i < b.N; i++ {
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
b.Error(err)
}
}
}
func BenchmarkSSHDirectForwardParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := TCPListener("")
if err != nil {
b.Error(err)
}
client := &Client{
Connector: SSHDirectForwardConnector(),
Transporter: SSHForwardTransporter(),
}
server := &Server{
Listener: ln,
Handler: SSHForwardHandler(),
}
go server.Run()
defer server.Close()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
b.Error(err)
}
}
})
}
func sshRemoteForwardRoundtrip(t *testing.T, targetURL string, data []byte) (err error) {
ln, err := TCPListener("")
if err != nil {
return
}
client := &Client{
Connector: SSHRemoteForwardConnector(),
Transporter: SSHForwardTransporter(),
}
server := &Server{
Listener: ln,
Handler: SSHForwardHandler(),
}
go server.Run()
defer server.Close()
conn, err := proxyConn(client, server)
if err != nil {
return
}
defer conn.Close()
go func() {
conn, err = client.Connect(conn, ":0")
if err != nil {
return
}
}()
c, err := net.Dial("tcp", conn.LocalAddr().String())
if err != nil {
return
}
defer c.Close()
u, err := url.Parse(targetURL)
if err != nil {
return
}
cc, err := net.Dial("tcp", u.Host)
if err != nil {
return
}
defer cc.Close()
go transport(conn, cc)
t.Log("httpRoundtrip")
return httpRoundtrip(c, targetURL, data)
}
func _TestSSHRemoteForward(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := sshRemoteForwardRoundtrip(t, httpSrv.URL, sendData)
if err != nil {
t.Error(err)
}
}
func httpOverSSHTunnelRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config, func httpOverSSHTunnelRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error { clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {