package dcs
import (
"context"
"io"
"github.com/go-faster/errors"
"nhooyr.io/websocket"
"github.com/gotd/td/internal/crypto"
"github.com/gotd/td/internal/mtproxy"
"github.com/gotd/td/internal/mtproxy/obfuscator"
"github.com/gotd/td/internal/proto/codec"
"github.com/gotd/td/internal/wsutil"
"github.com/gotd/td/transport"
)
var _ Resolver = ws {}
type ws struct {
dialOptions *websocket .DialOptions
protocol protocol
tag [4 ]byte
rand io .Reader
}
func (w ws ) connect (ctx context .Context , dc int , domains map [int ]string ) (transport .Conn , error ) {
addr , ok := domains [dc ]
if !ok {
return nil , errors .Errorf ("domain for %d not found" , dc )
}
conn , resp , err := websocket .Dial (ctx , addr , w .dialOptions )
if resp != nil && resp .Body != nil {
_ = resp .Body .Close ()
}
if err != nil {
return nil , errors .Wrap (err , "dial ws" )
}
obsConn := obfuscator .Obfuscated2 (w .rand , wsutil .NetConn (conn ))
if err := obsConn .Handshake (w .tag , dc , mtproxy .Secret {
Secret : nil ,
Type : mtproxy .Simple ,
}); err != nil {
return nil , errors .Wrap (err , "handshake" )
}
transportConn , err := w .protocol .Handshake (obsConn )
if err != nil {
return nil , errors .Wrap (err , "transport handshake" )
}
return transportConn , nil
}
func (w ws ) Primary (ctx context .Context , dc int , list List ) (transport .Conn , error ) {
return w .connect (ctx , dc , list .Domains )
}
func (w ws ) MediaOnly (ctx context .Context , dc int , list List ) (transport .Conn , error ) {
return nil , errors .Errorf ("can't resolve %d: MediaOnly is unsupported" , dc )
}
func (w ws ) CDN (ctx context .Context , dc int , list List ) (transport .Conn , error ) {
return nil , errors .Errorf ("can't resolve %d: CDN is unsupported" , dc )
}
type WebsocketOptions struct {
DialOptions *websocket .DialOptions
Rand io .Reader
}
func (m *WebsocketOptions ) setDefaults () {
if m .DialOptions == nil {
m .DialOptions = &websocket .DialOptions {Subprotocols : []string {
"binary" ,
}}
}
if m .Rand == nil {
m .Rand = crypto .DefaultRand ()
}
}
func Websocket (opts WebsocketOptions ) Resolver {
cdc := codec .Intermediate {}
opts .setDefaults ()
return ws {
dialOptions : opts .DialOptions ,
protocol : transport .NewProtocol (func () transport .Codec { return codec .NoHeader {Codec : cdc } }),
tag : cdc .ObfuscatedTag (),
rand : opts .Rand ,
}
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .