98 lines
1.9 KiB
Go
98 lines
1.9 KiB
Go
// +build !js
|
|
|
|
package websocket
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
ws "github.com/gorilla/websocket"
|
|
"github.com/libp2p/go-libp2p-core/transport"
|
|
ma "github.com/multiformats/go-multiaddr"
|
|
manet "github.com/multiformats/go-multiaddr/net"
|
|
)
|
|
|
|
// Default gorilla upgrader
|
|
var upgrader = ws.Upgrader{
|
|
// Allow requests from *all* origins.
|
|
CheckOrigin: func(r *http.Request) bool {
|
|
return true
|
|
},
|
|
}
|
|
|
|
func (t *WebsocketTransport) maDial(ctx context.Context, raddr ma.Multiaddr) (manet.Conn, error) {
|
|
wsurl, err := parseMultiaddr(raddr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
wscon, _, err := ws.DefaultDialer.Dial(wsurl, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
mnc, err := manet.WrapNetConn(NewConn(wscon))
|
|
if err != nil {
|
|
wscon.Close()
|
|
return nil, err
|
|
}
|
|
return mnc, nil
|
|
}
|
|
|
|
func (t *WebsocketTransport) maListen(a ma.Multiaddr) (manet.Listener, error) {
|
|
lnet, lnaddr, err := manet.DialArgs(a)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
nl, err := net.Listen(lnet, lnaddr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
u, err := url.Parse("http://" + nl.Addr().String())
|
|
if err != nil {
|
|
nl.Close()
|
|
return nil, err
|
|
}
|
|
|
|
malist, err := t.wrapListener(nl, u)
|
|
if err != nil {
|
|
nl.Close()
|
|
return nil, err
|
|
}
|
|
|
|
go malist.serve()
|
|
|
|
return malist, nil
|
|
}
|
|
|
|
func (t *WebsocketTransport) Listen(a ma.Multiaddr) (transport.Listener, error) {
|
|
malist, err := t.maListen(a)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return t.Upgrader.UpgradeListener(t, malist), nil
|
|
}
|
|
|
|
func (t *WebsocketTransport) wrapListener(l net.Listener, origin *url.URL) (*listener, error) {
|
|
laddr, err := manet.FromNetAddr(l.Addr())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
wsma, err := ma.NewMultiaddr("/ws")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
laddr = laddr.Encapsulate(wsma)
|
|
|
|
return &listener{
|
|
laddr: laddr,
|
|
Listener: l,
|
|
incoming: make(chan *Conn),
|
|
closed: make(chan struct{}),
|
|
}, nil
|
|
}
|