Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
G
gost
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
gost
Commits
89d2b7b4
Commit
89d2b7b4
authored
Jul 25, 2017
by
rui.zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
change Transporter interface
parent
346c2c27
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
232 additions
and
109 deletions
+232
-109
gost/cli/cli.go
gost/cli/cli.go
+4
-4
gost/client.go
gost/client.go
+55
-12
gost/http2.go
gost/http2.go
+124
-62
gost/kcp.go
gost/kcp.go
+4
-6
gost/srv/srv.go
gost/srv/srv.go
+2
-2
gost/tls.go
gost/tls.go
+12
-6
gost/ws.go
gost/ws.go
+31
-17
No files found.
gost/cli/cli.go
View file @
89d2b7b4
...
@@ -89,15 +89,15 @@ func main() {
...
@@ -89,15 +89,15 @@ func main() {
},
},
*/
*/
// http2
// http2
+tls, http2+tcp
gost
.
Node
{
gost
.
Node
{
Addr
:
"127.0.0.1:1443"
,
Addr
:
"127.0.0.1:1443"
,
Client
:
gost
.
NewClient
(
Client
:
gost
.
NewClient
(
gost
.
HTTP2Connector
(
url
.
UserPassword
(
"admin"
,
"123456"
)),
gost
.
HTTP2Connector
(
url
.
UserPassword
(
"admin"
,
"123456"
)),
gost
.
HTTP2Transporter
(
gost
.
HTTP2Transporter
(
nil
,
nil
,
&
tls
.
Config
{
InsecureSkipVerify
:
true
},
&
tls
.
Config
{
InsecureSkipVerify
:
true
},
// or nil, will use h2c mode (http2+tcp).
time
.
Second
*
60
,
time
.
Second
*
1
,
),
),
),
),
},
},
...
@@ -138,6 +138,6 @@ func main() {
...
@@ -138,6 +138,6 @@ func main() {
rb
,
_
=
httputil
.
DumpResponse
(
resp
,
true
)
rb
,
_
=
httputil
.
DumpResponse
(
resp
,
true
)
log
.
Println
(
string
(
rb
))
log
.
Println
(
string
(
rb
))
time
.
Sleep
(
100
*
time
.
Millisecond
)
time
.
Sleep
(
100
0
*
time
.
Millisecond
)
}
}
}
}
gost/client.go
View file @
89d2b7b4
package
gost
package
gost
import
(
import
(
"crypto/tls"
"net"
"net"
)
)
...
@@ -22,13 +23,13 @@ func NewClient(c Connector, tr Transporter) *Client {
...
@@ -22,13 +23,13 @@ func NewClient(c Connector, tr Transporter) *Client {
}
}
// Dial connects to the target address.
// Dial connects to the target address.
func
(
c
*
Client
)
Dial
(
addr
string
)
(
net
.
Conn
,
error
)
{
func
(
c
*
Client
)
Dial
(
addr
string
,
options
...
DialOption
)
(
net
.
Conn
,
error
)
{
return
c
.
Transporter
.
Dial
(
addr
)
return
c
.
Transporter
.
Dial
(
addr
,
options
...
)
}
}
// Handshake performs a handshake with the proxy over connection conn.
// Handshake performs a handshake with the proxy over connection conn.
func
(
c
*
Client
)
Handshake
(
conn
net
.
Conn
)
(
net
.
Conn
,
error
)
{
func
(
c
*
Client
)
Handshake
(
conn
net
.
Conn
,
options
...
HandshakeOption
)
(
net
.
Conn
,
error
)
{
return
c
.
Transporter
.
Handshake
(
conn
)
return
c
.
Transporter
.
Handshake
(
conn
,
options
...
)
}
}
// Connect connects to the address addr via the proxy over connection conn.
// Connect connects to the address addr via the proxy over connection conn.
...
@@ -40,13 +41,13 @@ func (c *Client) Connect(conn net.Conn, addr string) (net.Conn, error) {
...
@@ -40,13 +41,13 @@ func (c *Client) Connect(conn net.Conn, addr string) (net.Conn, error) {
var
DefaultClient
=
NewClient
(
HTTPConnector
(
nil
),
TCPTransporter
())
var
DefaultClient
=
NewClient
(
HTTPConnector
(
nil
),
TCPTransporter
())
// Dial connects to the address addr via the DefaultClient.
// Dial connects to the address addr via the DefaultClient.
func
Dial
(
addr
string
)
(
net
.
Conn
,
error
)
{
func
Dial
(
addr
string
,
options
...
DialOption
)
(
net
.
Conn
,
error
)
{
return
DefaultClient
.
Dial
(
addr
)
return
DefaultClient
.
Dial
(
addr
,
options
...
)
}
}
// Handshake performs a handshake via the DefaultClient.
// Handshake performs a handshake via the DefaultClient.
func
Handshake
(
conn
net
.
Conn
)
(
net
.
Conn
,
error
)
{
func
Handshake
(
conn
net
.
Conn
,
options
...
HandshakeOption
)
(
net
.
Conn
,
error
)
{
return
DefaultClient
.
Handshake
(
conn
)
return
DefaultClient
.
Handshake
(
conn
,
options
...
)
}
}
// Connect connects to the address addr via the DefaultClient.
// Connect connects to the address addr via the DefaultClient.
...
@@ -61,8 +62,8 @@ type Connector interface {
...
@@ -61,8 +62,8 @@ type Connector interface {
// Transporter is responsible for handshaking with the proxy server.
// Transporter is responsible for handshaking with the proxy server.
type
Transporter
interface
{
type
Transporter
interface
{
Dial
(
addr
string
)
(
net
.
Conn
,
error
)
Dial
(
addr
string
,
options
...
DialOption
)
(
net
.
Conn
,
error
)
Handshake
(
conn
net
.
Conn
)
(
net
.
Conn
,
error
)
Handshake
(
conn
net
.
Conn
,
options
...
HandshakeOption
)
(
net
.
Conn
,
error
)
// Indicate that the Transporter supports multiplex
// Indicate that the Transporter supports multiplex
Multiplex
()
bool
Multiplex
()
bool
}
}
...
@@ -75,14 +76,56 @@ func TCPTransporter() Transporter {
...
@@ -75,14 +76,56 @@ func TCPTransporter() Transporter {
return
&
tcpTransporter
{}
return
&
tcpTransporter
{}
}
}
func
(
tr
*
tcpTransporter
)
Dial
(
addr
string
)
(
net
.
Conn
,
error
)
{
func
(
tr
*
tcpTransporter
)
Dial
(
addr
string
,
options
...
DialOption
)
(
net
.
Conn
,
error
)
{
return
net
.
Dial
(
"tcp"
,
addr
)
return
net
.
Dial
(
"tcp"
,
addr
)
}
}
func
(
tr
*
tcpTransporter
)
Handshake
(
conn
net
.
Conn
)
(
net
.
Conn
,
error
)
{
func
(
tr
*
tcpTransporter
)
Handshake
(
conn
net
.
Conn
,
options
...
HandshakeOption
)
(
net
.
Conn
,
error
)
{
return
conn
,
nil
return
conn
,
nil
}
}
func
(
tr
*
tcpTransporter
)
Multiplex
()
bool
{
func
(
tr
*
tcpTransporter
)
Multiplex
()
bool
{
return
false
return
false
}
}
// DialOptions describes the options for dialing.
type
DialOptions
struct
{
}
// DialOption allows a common way to set dial options.
type
DialOption
func
(
opts
*
DialOptions
)
// HandshakeOptions describes the options for handshake.
type
HandshakeOptions
struct
{
Addr
string
TLSConfig
*
tls
.
Config
WSOptions
*
WSOptions
KCPConfig
*
KCPConfig
}
// HandshakeOption allows a common way to set handshake options.
type
HandshakeOption
func
(
opts
*
HandshakeOptions
)
func
AddrHandshakeOption
(
addr
string
)
HandshakeOption
{
return
func
(
opts
*
HandshakeOptions
)
{
opts
.
Addr
=
addr
}
}
func
TLSConfigHandshakeOption
(
config
*
tls
.
Config
)
HandshakeOption
{
return
func
(
opts
*
HandshakeOptions
)
{
opts
.
TLSConfig
=
config
}
}
func
WSOptionsHandshakeOption
(
options
*
WSOptions
)
HandshakeOption
{
return
func
(
opts
*
HandshakeOptions
)
{
opts
.
WSOptions
=
options
}
}
func
KCPConfigHandshakeOption
(
config
*
KCPConfig
)
HandshakeOption
{
return
func
(
opts
*
HandshakeOptions
)
{
opts
.
KCPConfig
=
config
}
}
gost/http2.go
View file @
89d2b7b4
...
@@ -79,8 +79,8 @@ type http2Transporter struct {
...
@@ -79,8 +79,8 @@ type http2Transporter struct {
tlsConfig
*
tls
.
Config
tlsConfig
*
tls
.
Config
tr
*
http2
.
Transport
tr
*
http2
.
Transport
chain
*
Chain
chain
*
Chain
conns
map
[
string
]
*
http2
.
ClientCon
n
sessions
map
[
string
]
*
http2Sessio
n
connMutex
sync
.
Mutex
sessionMutex
sync
.
Mutex
pingInterval
time
.
Duration
pingInterval
time
.
Duration
}
}
...
@@ -97,93 +97,49 @@ func HTTP2Transporter(chain *Chain, config *tls.Config, ping time.Duration) Tran
...
@@ -97,93 +97,49 @@ func HTTP2Transporter(chain *Chain, config *tls.Config, ping time.Duration) Tran
tr
:
new
(
http2
.
Transport
),
tr
:
new
(
http2
.
Transport
),
chain
:
chain
,
chain
:
chain
,
pingInterval
:
ping
,
pingInterval
:
ping
,
conns
:
make
(
map
[
string
]
*
http2
.
ClientCon
n
),
sessions
:
make
(
map
[
string
]
*
http2Sessio
n
),
}
}
}
}
func
(
tr
*
http2Transporter
)
Dial
(
addr
string
)
(
net
.
Conn
,
error
)
{
func
(
tr
*
http2Transporter
)
Dial
(
addr
string
,
options
...
DialOption
)
(
net
.
Conn
,
error
)
{
tr
.
con
nMutex
.
Lock
()
tr
.
sessio
nMutex
.
Lock
()
conn
,
ok
:=
tr
.
conns
[
addr
]
defer
tr
.
sessionMutex
.
Unlock
()
session
,
ok
:=
tr
.
sessions
[
addr
]
if
!
ok
{
if
!
ok
{
c
c
,
err
:=
tr
.
chain
.
Dial
(
addr
)
c
onn
,
err
:=
tr
.
chain
.
Dial
(
addr
)
if
err
!=
nil
{
if
err
!=
nil
{
tr
.
connMutex
.
Unlock
()
return
nil
,
err
return
nil
,
err
}
}
if
tr
.
tlsConfig
!=
nil
{
if
tr
.
tlsConfig
!=
nil
{
tc
:=
tls
.
Client
(
c
c
,
tr
.
tlsConfig
)
tc
:=
tls
.
Client
(
c
onn
,
tr
.
tlsConfig
)
if
err
:=
tc
.
Handshake
();
err
!=
nil
{
if
err
:=
tc
.
Handshake
();
err
!=
nil
{
tr
.
connMutex
.
Unlock
()
return
nil
,
err
return
nil
,
err
}
}
c
c
=
tc
c
onn
=
tc
}
}
c
onn
,
err
=
tr
.
tr
.
NewClientConn
(
cc
)
c
c
,
err
:=
tr
.
tr
.
NewClientConn
(
conn
)
if
err
!=
nil
{
if
err
!=
nil
{
tr
.
connMutex
.
Unlock
()
return
nil
,
err
return
nil
,
err
}
}
tr
.
conns
[
addr
]
=
conn
session
=
newHTTP2Session
(
conn
,
cc
,
tr
.
pingInterval
)
go
tr
.
ping
(
tr
.
pingInterval
,
addr
,
conn
)
tr
.
sessions
[
addr
]
=
session
}
}
tr
.
connMutex
.
Unlock
()
if
!
conn
.
CanTakeNewRequest
()
{
if
!
session
.
Healthy
()
{
tr
.
connMutex
.
Lock
()
session
.
Close
()
delete
(
tr
.
conns
,
addr
)
// TODO: we could re-connect to the addr automatically.
delete
(
tr
.
sessions
,
addr
)
// TODO: we could re-connect to the addr automatically.
tr
.
connMutex
.
Unlock
()
return
nil
,
errors
.
New
(
"connection is dead"
)
return
nil
,
errors
.
New
(
"connection is dead"
)
}
}
return
&
http2DummyConn
{
return
&
http2DummyConn
{
raddr
:
addr
,
raddr
:
addr
,
conn
:
c
onn
,
conn
:
session
.
clientC
onn
,
},
nil
},
nil
}
}
func
(
tr
*
http2Transporter
)
ping
(
interval
time
.
Duration
,
addr
string
,
conn
*
http2
.
ClientConn
)
{
func
(
tr
*
http2Transporter
)
Handshake
(
conn
net
.
Conn
,
options
...
HandshakeOption
)
(
net
.
Conn
,
error
)
{
if
interval
<=
0
{
return
}
log
.
Log
(
"[http2] ping is enabled, interval:"
,
interval
)
baseCtx
:=
context
.
Background
()
t
:=
time
.
NewTicker
(
interval
)
retries
:=
PingRetries
for
{
select
{
case
<-
t
.
C
:
if
!
conn
.
CanTakeNewRequest
()
{
return
}
ctx
,
cancel
:=
context
.
WithTimeout
(
baseCtx
,
PingTimeout
)
if
err
:=
conn
.
Ping
(
ctx
);
err
!=
nil
{
log
.
Logf
(
"[http2] ping: %s"
,
err
)
if
retries
>
0
{
retries
--
log
.
Log
(
"[http2] retry ping"
)
cancel
()
continue
}
// connection is dead, remove it.
tr
.
connMutex
.
Lock
()
delete
(
tr
.
conns
,
addr
)
tr
.
connMutex
.
Unlock
()
cancel
()
return
}
cancel
()
retries
=
PingRetries
}
}
}
func
(
tr
*
http2Transporter
)
Handshake
(
conn
net
.
Conn
)
(
net
.
Conn
,
error
)
{
return
conn
,
nil
return
conn
,
nil
}
}
...
@@ -333,6 +289,112 @@ func (h *http2Handler) handleFunc(w http.ResponseWriter, r *http.Request) {
...
@@ -333,6 +289,112 @@ func (h *http2Handler) handleFunc(w http.ResponseWriter, r *http.Request) {
log
.
Logf
(
"[http2] %s >-< %s"
,
r
.
RemoteAddr
,
target
)
log
.
Logf
(
"[http2] %s >-< %s"
,
r
.
RemoteAddr
,
target
)
}
}
type
http2Listener
struct
{
ln
net
.
Listener
}
// HTTP2Listener creates a Listener for server using HTTP2 as transport.
func
HTTP2Listener
(
addr
string
,
config
*
tls
.
Config
)
(
Listener
,
error
)
{
var
ln
net
.
Listener
var
err
error
if
config
!=
nil
{
ln
,
err
=
tls
.
Listen
(
"tcp"
,
addr
,
config
)
}
else
{
ln
,
err
=
net
.
Listen
(
"tcp"
,
addr
)
}
if
err
!=
nil
{
return
nil
,
err
}
return
ln
,
err
//return &http2Listener{ln: ln}, nil
}
type
http2Session
struct
{
conn
net
.
Conn
clientConn
*
http2
.
ClientConn
closeChan
chan
struct
{}
pingChan
chan
struct
{}
}
func
newHTTP2Session
(
conn
net
.
Conn
,
clientConn
*
http2
.
ClientConn
,
interval
time
.
Duration
)
*
http2Session
{
session
:=
&
http2Session
{
conn
:
conn
,
clientConn
:
clientConn
,
closeChan
:
make
(
chan
struct
{}),
}
if
interval
>
0
{
session
.
pingChan
=
make
(
chan
struct
{})
go
session
.
Ping
(
interval
)
}
return
session
}
func
(
s
*
http2Session
)
Ping
(
interval
time
.
Duration
)
{
if
interval
<=
0
{
return
}
defer
close
(
s
.
pingChan
)
log
.
Log
(
"[http2] ping is enabled, interval:"
,
interval
)
baseCtx
:=
context
.
Background
()
t
:=
time
.
NewTicker
(
interval
)
retries
:=
PingRetries
for
{
select
{
case
<-
t
.
C
:
if
Debug
{
log
.
Log
(
"[http2] sending ping"
)
}
if
!
s
.
clientConn
.
CanTakeNewRequest
()
{
log
.
Logf
(
"[http2] connection is dead"
)
return
}
ctx
,
cancel
:=
context
.
WithTimeout
(
baseCtx
,
PingTimeout
)
if
err
:=
s
.
clientConn
.
Ping
(
ctx
);
err
!=
nil
{
log
.
Logf
(
"[http2] ping: %s"
,
err
)
if
retries
>
0
{
retries
--
log
.
Log
(
"[http2] retry ping"
)
cancel
()
continue
}
cancel
()
return
}
if
Debug
{
log
.
Log
(
"[http2] ping OK"
)
}
cancel
()
retries
=
PingRetries
case
<-
s
.
closeChan
:
return
}
}
}
func
(
s
*
http2Session
)
Healthy
()
bool
{
select
{
case
<-
s
.
pingChan
:
return
false
default
:
}
return
s
.
clientConn
.
CanTakeNewRequest
()
}
func
(
s
*
http2Session
)
Close
()
error
{
select
{
case
<-
s
.
closeChan
:
default
:
close
(
s
.
closeChan
)
}
return
nil
}
// HTTP2 connection, wrapped up just like a net.Conn
// HTTP2 connection, wrapped up just like a net.Conn
type
http2Conn
struct
{
type
http2Conn
struct
{
r
io
.
Reader
r
io
.
Reader
...
...
gost/kcp.go
View file @
89d2b7b4
...
@@ -179,25 +179,23 @@ func KCPTransporter(config *KCPConfig) Transporter {
...
@@ -179,25 +179,23 @@ func KCPTransporter(config *KCPConfig) Transporter {
}
}
}
}
func
(
tr
*
kcpTransporter
)
Dial
(
addr
string
)
(
conn
net
.
Conn
,
err
error
)
{
func
(
tr
*
kcpTransporter
)
Dial
(
addr
string
,
options
...
DialOption
)
(
conn
net
.
Conn
,
err
error
)
{
tr
.
sessionMutex
.
Lock
()
tr
.
sessionMutex
.
Lock
()
defer
tr
.
sessionMutex
.
Unlock
()
session
,
ok
:=
tr
.
sessions
[
addr
]
session
,
ok
:=
tr
.
sessions
[
addr
]
if
!
ok
{
if
!
ok
{
session
,
err
=
tr
.
dial
(
addr
,
tr
.
config
)
session
,
err
=
tr
.
dial
(
addr
,
tr
.
config
)
if
err
!=
nil
{
if
err
!=
nil
{
tr
.
sessionMutex
.
Unlock
()
return
return
}
}
tr
.
sessions
[
addr
]
=
session
tr
.
sessions
[
addr
]
=
session
}
}
tr
.
sessionMutex
.
Unlock
()
conn
,
err
=
session
.
GetConn
()
conn
,
err
=
session
.
GetConn
()
if
err
!=
nil
{
if
err
!=
nil
{
tr
.
sessionMutex
.
Lock
()
session
.
Close
()
session
.
Close
()
delete
(
tr
.
sessions
,
addr
)
// TODO: we could obtain a new session automatically.
delete
(
tr
.
sessions
,
addr
)
// TODO: we could obtain a new session automatically.
tr
.
sessionMutex
.
Unlock
()
}
}
return
return
}
}
...
@@ -241,7 +239,7 @@ func (tr *kcpTransporter) dial(addr string, config *KCPConfig) (*kcpSession, err
...
@@ -241,7 +239,7 @@ func (tr *kcpTransporter) dial(addr string, config *KCPConfig) (*kcpSession, err
return
&
kcpSession
{
conn
:
conn
,
session
:
session
},
nil
return
&
kcpSession
{
conn
:
conn
,
session
:
session
},
nil
}
}
func
(
tr
*
kcpTransporter
)
Handshake
(
conn
net
.
Conn
)
(
net
.
Conn
,
error
)
{
func
(
tr
*
kcpTransporter
)
Handshake
(
conn
net
.
Conn
,
options
...
HandshakeOption
)
(
net
.
Conn
,
error
)
{
return
conn
,
nil
return
conn
,
nil
}
}
...
...
gost/srv/srv.go
View file @
89d2b7b4
...
@@ -189,8 +189,8 @@ func http2Server() {
...
@@ -189,8 +189,8 @@ func http2Server() {
s
.
Handle
(
gost
.
HTTP2Handler
(
s
.
Handle
(
gost
.
HTTP2Handler
(
gost
.
UsersHandlerOption
(
url
.
UserPassword
(
"admin"
,
"123456"
)),
gost
.
UsersHandlerOption
(
url
.
UserPassword
(
"admin"
,
"123456"
)),
))
))
ln
,
err
:=
gost
.
TLSListener
(
":1443"
,
tlsConfig
())
ln
,
err
:=
gost
.
TLSListener
(
":1443"
,
tlsConfig
())
// HTTP2 h2 mode
// ln, err := gost.TCPListener(":1443")
// ln, err := gost.TCPListener(":1443")
// HTTP2 h2c mode
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Fatal
(
err
)
log
.
Fatal
(
err
)
}
}
...
...
gost/tls.go
View file @
89d2b7b4
...
@@ -6,21 +6,27 @@ import (
...
@@ -6,21 +6,27 @@ import (
)
)
type
tlsTransporter
struct
{
type
tlsTransporter
struct
{
tlsConfig
*
tls
.
Config
}
}
// TLSTransporter creates a Transporter that is used by TLS proxy client.
// TLSTransporter creates a Transporter that is used by TLS proxy client.
// It accepts a TLS config for TLS handshake.
// It accepts a TLS config for TLS handshake.
func
TLSTransporter
(
cfg
*
tls
.
Config
)
Transporter
{
func
TLSTransporter
()
Transporter
{
return
&
tlsTransporter
{
tlsConfig
:
cfg
}
return
&
tlsTransporter
{}
}
}
func
(
tr
*
tlsTransporter
)
Dial
(
addr
string
)
(
net
.
Conn
,
error
)
{
func
(
tr
*
tlsTransporter
)
Dial
(
addr
string
,
options
...
DialOption
)
(
net
.
Conn
,
error
)
{
return
net
.
Dial
(
"tcp"
,
addr
)
return
net
.
Dial
(
"tcp"
,
addr
)
}
}
func
(
tr
*
tlsTransporter
)
Handshake
(
conn
net
.
Conn
)
(
net
.
Conn
,
error
)
{
func
(
tr
*
tlsTransporter
)
Handshake
(
conn
net
.
Conn
,
options
...
HandshakeOption
)
(
net
.
Conn
,
error
)
{
return
tls
.
Client
(
conn
,
tr
.
tlsConfig
),
nil
opts
:=
&
HandshakeOptions
{}
for
_
,
option
:=
range
options
{
option
(
opts
)
}
if
opts
.
TLSConfig
==
nil
{
opts
.
TLSConfig
=
&
tls
.
Config
{
InsecureSkipVerify
:
true
}
}
return
tls
.
Client
(
conn
,
opts
.
TLSConfig
),
nil
}
}
func
(
tr
*
tlsTransporter
)
Multiplex
()
bool
{
func
(
tr
*
tlsTransporter
)
Multiplex
()
bool
{
...
...
gost/ws.go
View file @
89d2b7b4
...
@@ -27,14 +27,14 @@ type websocketConn struct {
...
@@ -27,14 +27,14 @@ type websocketConn struct {
rb
[]
byte
rb
[]
byte
}
}
func
websocketClientConn
(
url
string
,
conn
net
.
Conn
,
options
*
WSOptions
)
(
net
.
Conn
,
error
)
{
func
websocketClientConn
(
url
string
,
conn
net
.
Conn
,
tlsConfig
*
tls
.
Config
,
options
*
WSOptions
)
(
net
.
Conn
,
error
)
{
if
options
==
nil
{
if
options
==
nil
{
options
=
&
WSOptions
{}
options
=
&
WSOptions
{}
}
}
dialer
:=
websocket
.
Dialer
{
dialer
:=
websocket
.
Dialer
{
ReadBufferSize
:
options
.
ReadBufferSize
,
ReadBufferSize
:
options
.
ReadBufferSize
,
WriteBufferSize
:
options
.
WriteBufferSize
,
WriteBufferSize
:
options
.
WriteBufferSize
,
TLSClientConfig
:
options
.
TLS
Config
,
TLSClientConfig
:
tls
Config
,
HandshakeTimeout
:
options
.
HandshakeTimeout
,
HandshakeTimeout
:
options
.
HandshakeTimeout
,
EnableCompression
:
options
.
EnableCompression
,
EnableCompression
:
options
.
EnableCompression
,
NetDial
:
func
(
net
,
addr
string
)
(
net
.
Conn
,
error
)
{
NetDial
:
func
(
net
,
addr
string
)
(
net
.
Conn
,
error
)
{
...
@@ -98,26 +98,31 @@ func (c *websocketConn) SetWriteDeadline(t time.Time) error {
...
@@ -98,26 +98,31 @@ func (c *websocketConn) SetWriteDeadline(t time.Time) error {
}
}
type
wsTransporter
struct
{
type
wsTransporter
struct
{
addr
string
options
*
WSOptions
options
*
WSOptions
}
}
// WSTransporter creates a Transporter that is used by websocket proxy client.
// WSTransporter creates a Transporter that is used by websocket proxy client.
func
WSTransporter
(
addr
string
,
opts
*
WSOptions
)
Transporter
{
func
WSTransporter
(
opts
*
WSOptions
)
Transporter
{
return
&
wsTransporter
{
return
&
wsTransporter
{
addr
:
addr
,
options
:
opts
,
options
:
opts
,
}
}
}
}
func
(
tr
*
wsTransporter
)
Dial
(
addr
string
)
(
net
.
Conn
,
error
)
{
func
(
tr
*
wsTransporter
)
Dial
(
addr
string
,
options
...
DialOption
)
(
net
.
Conn
,
error
)
{
tr
.
addr
=
addr
// NOTE: the addr must match the initial tr.addr
return
net
.
Dial
(
"tcp"
,
addr
)
return
net
.
Dial
(
"tcp"
,
addr
)
}
}
func
(
tr
*
wsTransporter
)
Handshake
(
conn
net
.
Conn
)
(
net
.
Conn
,
error
)
{
func
(
tr
*
wsTransporter
)
Handshake
(
conn
net
.
Conn
,
options
...
HandshakeOption
)
(
net
.
Conn
,
error
)
{
url
:=
url
.
URL
{
Scheme
:
"ws"
,
Host
:
tr
.
addr
,
Path
:
"/ws"
}
opts
:=
&
HandshakeOptions
{}
return
websocketClientConn
(
url
.
String
(),
conn
,
tr
.
options
)
for
_
,
option
:=
range
options
{
option
(
opts
)
}
wsOptions
:=
tr
.
options
if
opts
.
WSOptions
!=
nil
{
wsOptions
=
opts
.
WSOptions
}
url
:=
url
.
URL
{
Scheme
:
"ws"
,
Host
:
opts
.
Addr
,
Path
:
"/ws"
}
return
websocketClientConn
(
url
.
String
(),
conn
,
nil
,
wsOptions
)
}
}
func
(
tr
*
wsTransporter
)
Multiplex
()
bool
{
func
(
tr
*
wsTransporter
)
Multiplex
()
bool
{
...
@@ -125,25 +130,34 @@ func (tr *wsTransporter) Multiplex() bool {
...
@@ -125,25 +130,34 @@ func (tr *wsTransporter) Multiplex() bool {
}
}
type
wssTransporter
struct
{
type
wssTransporter
struct
{
addr
string
options
*
WSOptions
options
*
WSOptions
}
}
// WSSTransporter creates a Transporter that is used by websocket secure proxy client.
// WSSTransporter creates a Transporter that is used by websocket secure proxy client.
func
WSSTransporter
(
addr
string
,
opts
*
WSOptions
)
Transporter
{
func
WSSTransporter
(
opts
*
WSOptions
)
Transporter
{
return
&
wssTransporter
{
return
&
wssTransporter
{
addr
:
addr
,
options
:
opts
,
options
:
opts
,
}
}
}
}
func
(
tr
*
wssTransporter
)
Dial
(
addr
string
)
(
net
.
Conn
,
error
)
{
func
(
tr
*
wssTransporter
)
Dial
(
addr
string
,
options
...
DialOption
)
(
net
.
Conn
,
error
)
{
return
net
.
Dial
(
"tcp"
,
addr
)
return
net
.
Dial
(
"tcp"
,
addr
)
}
}
func
(
tr
*
wssTransporter
)
Handshake
(
conn
net
.
Conn
)
(
net
.
Conn
,
error
)
{
func
(
tr
*
wssTransporter
)
Handshake
(
conn
net
.
Conn
,
options
...
HandshakeOption
)
(
net
.
Conn
,
error
)
{
url
:=
url
.
URL
{
Scheme
:
"wss"
,
Host
:
tr
.
addr
,
Path
:
"/ws"
}
opts
:=
&
HandshakeOptions
{}
return
websocketClientConn
(
url
.
String
(),
conn
,
tr
.
options
)
for
_
,
option
:=
range
options
{
option
(
opts
)
}
wsOptions
:=
tr
.
options
if
opts
.
WSOptions
!=
nil
{
wsOptions
=
opts
.
WSOptions
}
if
opts
.
TLSConfig
==
nil
{
opts
.
TLSConfig
=
&
tls
.
Config
{
InsecureSkipVerify
:
true
}
}
url
:=
url
.
URL
{
Scheme
:
"wss"
,
Host
:
opts
.
Addr
,
Path
:
"/ws"
}
return
websocketClientConn
(
url
.
String
(),
conn
,
opts
.
TLSConfig
,
wsOptions
)
}
}
func
(
tr
*
wssTransporter
)
Multiplex
()
bool
{
func
(
tr
*
wssTransporter
)
Multiplex
()
bool
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment