This repository has been archived by the owner on Jun 7, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathsession_client.go
138 lines (126 loc) · 3.59 KB
/
session_client.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package lumina
import (
"bytes"
"context"
"encoding/hex"
"github.com/palantir/stacktrace"
"log"
"net"
)
var _ = hex.EncodeToString
type ClientSession struct {
conn net.Conn
logger *log.Logger
interpreter Interpreter
}
func (c *Client) Dial(ctx context.Context, logger *log.Logger, version int32, interpreter Interpreter) (s *ClientSession, err error) {
// FIXME: Dialer does not support context.Context
conn, err := c.getDialer().Dial()
if err != nil {
err = stacktrace.Propagate(err, "dial failed")
return
}
if logger == nil {
logger = newTaggedLogger()
}
_s := &ClientSession{
conn: conn,
logger: logger,
interpreter: interpreter,
}
rsp, err := _s.Request(ctx, newHeloPacket(version, c.LicenseKey, c.LicenseId))
if err != nil {
err = stacktrace.Propagate(err, "hello request failed")
conn.Close()
return
}
if version < 5 {
if _, ok := rsp.(*RpcOkPacket); !ok {
err = stacktrace.NewError("hello response: %#v", rsp)
conn.Close()
return
}
} else {
if heloResult, ok := rsp.(*HeloResultPacket); !ok {
err = stacktrace.NewError("unexpected hello result: %#v", rsp)
conn.Close()
return
} else {
logger.Printf("hello result: %#v", heloResult.User)
}
}
// The underlying net.Conn has already called runtime.SetFinalizer.
s = _s
return
}
func (s *ClientSession) Close() error {
return s.conn.Close()
}
// The packet cache will be used if available.
func (s *ClientSession) Request(ctx context.Context, req Request) (rsp Packet, err error) {
reqType := req.getType()
s.logger.Print("client send request type: ", reqType)
// s.logger.Printf("client send request data: %+v", req)
var reqRaw RawPacket
if cr, _ := req.(cacheReader); cr != nil {
reqRaw = cr.getCache()
}
if reqRaw == nil {
if err = req.validateFields(); err != nil {
err = stacktrace.Propagate(err, "validation failed for request of type %v", reqType)
return
}
reqPayload := &bytes.Buffer{}
if err = req.writeTo(reqPayload); err != nil {
err = stacktrace.Propagate(err, "unable to marshal request of type %v", reqType)
return
}
reqRaw, err = NewRawPacket(reqType, reqPayload.Bytes())
if err != nil {
err = stacktrace.Propagate(err, "unable to compose raw packet for request of type %v", reqType)
return
}
}
// s.logger.Print("client send request rawdata: ", hex.EncodeToString(reqRaw.GetPayload()))
if err = reqRaw.writeTo(s.conn); err != nil {
err = stacktrace.Propagate(err, "unable to write raw packet to server")
s.Close()
return
}
var rspRaw RawPacket
err = rspRaw.readFrom(s.conn)
if err != nil {
err = stacktrace.Propagate(err, "unable to read raw packet from server")
s.Close()
return
}
rspType := rspRaw.GetType()
s.logger.Print("client recv response type: ", rspType)
// s.logger.Print("client recv response rawdata: ", hex.EncodeToString(rspRaw.GetPayload()))
rsp = rpcInterpreter.GetPacketOfType(rspType)
if rsp == nil {
rsp = s.interpreter.GetPacketOfType(rspType)
}
if rsp == nil {
err = stacktrace.NewError("response of type %v is not supported by interpreter", rspType)
return
}
r := bytes.NewReader(rspRaw.GetPayload())
err = rsp.readFrom(r)
if err == nil && r.Len() > 0 {
err = errTrailingData
}
if err != nil {
s.logger.Print(stacktrace.Propagate(err, "unable to unmarshal response of type %v", rspType))
return
}
// s.logger.Printf("client recv response data: %+v", rsp)
if err = rsp.validateFields(); err != nil {
err = stacktrace.Propagate(err, "validation failed for response of type %v", rspType)
return
}
if cw, _ := rsp.(cacheWriter); cw != nil {
cw.setCache(rspRaw)
}
return
}