frp/pkg/util/net/websocket.go

77 lines
1.4 KiB
Go
Raw Normal View History

2018-08-03 11:41:54 +00:00
package net
import (
2018-08-10 03:43:08 +00:00
"errors"
2018-08-03 11:41:54 +00:00
"net"
"net/http"
"strconv"
2018-08-03 11:41:54 +00:00
"golang.org/x/net/websocket"
)
2022-08-28 17:02:53 +00:00
var ErrWebsocketListenerClosed = errors.New("websocket listener closed")
2018-08-10 03:43:08 +00:00
const (
2018-08-10 06:44:14 +00:00
FrpWebsocketPath = "/~!frp"
2018-08-10 03:43:08 +00:00
)
2018-08-03 11:41:54 +00:00
type WebsocketListener struct {
2019-10-12 12:13:12 +00:00
ln net.Listener
acceptCh chan net.Conn
2018-08-10 03:43:08 +00:00
2022-08-28 17:02:53 +00:00
server *http.Server
2018-08-03 11:41:54 +00:00
}
2019-01-31 08:54:46 +00:00
// NewWebsocketListener to handle websocket connections
2018-08-10 03:43:08 +00:00
// ln: tcp listener for websocket connections
func NewWebsocketListener(ln net.Listener) (wl *WebsocketListener) {
wl = &WebsocketListener{
2019-10-12 12:13:12 +00:00
acceptCh: make(chan net.Conn),
2018-08-03 11:41:54 +00:00
}
2018-08-10 03:43:08 +00:00
muxer := http.NewServeMux()
muxer.Handle(FrpWebsocketPath, websocket.Handler(func(c *websocket.Conn) {
notifyCh := make(chan struct{})
conn := WrapCloseNotifyConn(c, func() {
close(notifyCh)
})
2019-10-12 12:13:12 +00:00
wl.acceptCh <- conn
2018-08-10 03:43:08 +00:00
<-notifyCh
2018-08-03 11:41:54 +00:00
}))
2018-08-10 03:43:08 +00:00
wl.server = &http.Server{
Addr: ln.Addr().String(),
Handler: muxer,
2018-08-03 11:41:54 +00:00
}
2018-08-10 03:43:08 +00:00
2022-08-28 17:02:53 +00:00
go func() {
_ = wl.server.Serve(ln)
}()
2018-08-03 11:41:54 +00:00
return
}
2018-08-10 03:43:08 +00:00
func ListenWebsocket(bindAddr string, bindPort int) (*WebsocketListener, error) {
tcpLn, err := net.Listen("tcp", net.JoinHostPort(bindAddr, strconv.Itoa(bindPort)))
2018-08-03 11:41:54 +00:00
if err != nil {
2018-08-10 03:43:08 +00:00
return nil, err
2018-08-03 11:41:54 +00:00
}
2018-08-10 03:43:08 +00:00
l := NewWebsocketListener(tcpLn)
return l, nil
2018-08-03 11:41:54 +00:00
}
2019-10-12 12:13:12 +00:00
func (p *WebsocketListener) Accept() (net.Conn, error) {
c, ok := <-p.acceptCh
2018-08-10 03:43:08 +00:00
if !ok {
return nil, ErrWebsocketListenerClosed
}
2018-08-03 11:41:54 +00:00
return c, nil
}
func (p *WebsocketListener) Close() error {
2018-08-10 03:43:08 +00:00
return p.server.Close()
2018-08-03 11:41:54 +00:00
}
2019-10-12 12:13:12 +00:00
func (p *WebsocketListener) Addr() net.Addr {
return p.ln.Addr()
}