/
net_functions.go
97 lines (80 loc) · 2.45 KB
/
net_functions.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package ws_ns
import (
"crypto/tls"
"fmt"
"net/http"
"time"
"github.com/gorilla/websocket"
"github.com/inoxlang/inox/internal/commonfmt"
"github.com/inoxlang/inox/internal/core"
"github.com/inoxlang/inox/internal/core/permkind"
"github.com/inoxlang/inox/internal/utils"
)
const (
WS_SIMUL_CONN_TOTAL_LIMIT_NAME = "ws/simul-connections"
OPTION_DOES_NOT_EXIST_FMT = "option '%s' does not exist"
)
func websocketConnect(ctx *core.Context, u core.URL, options ...core.Option) (*WebsocketConnection, error) {
insecure := false
for _, opt := range options {
switch opt.Name {
case "insecure":
insecure = bool(opt.Value.(core.Bool))
default:
return nil, commonfmt.FmtErrInvalidOptionName(opt.Name)
}
}
return WebsocketConnect(WebsocketConnectParams{
Ctx: ctx,
URL: u,
Insecure: insecure,
})
}
type WebsocketConnectParams struct {
Ctx *core.Context
URL core.URL
Insecure bool
RequestHeader http.Header
MessageTimeout time.Duration //if 0 defaults to DEFAULT_WS_MESSAGE_TIMEOUT
HandshakeTimeout time.Duration //if 0 defaults to DEFAULT_WS_HANDSHAKE_TIMEOUT
}
func WebsocketConnect(args WebsocketConnectParams) (*WebsocketConnection, error) {
ctx := args.Ctx
u := args.URL
insecure := args.Insecure
requestHeader := args.RequestHeader
messageTimeout := utils.DefaultIfZero(args.MessageTimeout, DEFAULT_WS_MESSAGE_TIMEOUT)
handshakeTimeout := utils.DefaultIfZero(args.HandshakeTimeout, DEFAULT_WS_HANDSHAKE_TIMEOUT)
//check that a websocket read or write-stream permission is granted
perm := core.WebsocketPermission{
Kind_: permkind.WriteStream,
Endpoint: u,
}
if err := ctx.CheckHasPermission(perm); err != nil {
perm.Kind_ = permkind.Read
if err := ctx.CheckHasPermission(perm); err != nil {
return nil, err
}
}
ctx.Take(WS_SIMUL_CONN_TOTAL_LIMIT_NAME, 1)
dialer := *websocket.DefaultDialer
dialer.HandshakeTimeout = handshakeTimeout
dialer.TLSClientConfig = &tls.Config{
InsecureSkipVerify: insecure,
}
c, resp, err := dialer.Dial(string(u), requestHeader)
if err != nil {
ctx.GiveBack(WS_SIMUL_CONN_TOTAL_LIMIT_NAME, 1)
if resp == nil {
return nil, fmt.Errorf("dial: %s", err.Error())
} else {
return nil, fmt.Errorf("dial: %s (http status code: %d, text: %s)", err.Error(), resp.StatusCode, resp.Status)
}
}
return &WebsocketConnection{
conn: c,
endpoint: u,
messageTimeout: messageTimeout,
serverContext: ctx,
}, nil
}