}
func (s *Server) ListenAndServe(ctx context.Context, cancelRoot context.CancelFunc) error {
- s.Logger.Infow("Hotline server started", "version", VERSION)
+ s.Logger.Infow("Hotline server started",
+ "version", VERSION,
+ "API port", fmt.Sprintf(":%v", s.Port),
+ "Transfer port", fmt.Sprintf(":%v", s.Port+1),
+ )
+
var wg sync.WaitGroup
wg.Add(1)
return nil
}
-func (s *Server) APIPort() int {
- return s.APIListener.Addr().(*net.TCPAddr).Port
-}
-
func (s *Server) ServeFileTransfers(ln net.Listener) error {
- s.Logger.Infow("Hotline file transfer server started", "Addr", fmt.Sprintf(":%v", s.Port+1))
-
for {
conn, err := ln.Accept()
if err != nil {
}
func (s *Server) Serve(ctx context.Context, cancelRoot context.CancelFunc, ln net.Listener) error {
- s.Logger.Infow("Hotline server started", "Addr", fmt.Sprintf(":%v", s.Port))
for {
conn, err := ln.Accept()
}
server.APIListener = ln
- if netPort != 0 {
- netPort += 1
- }
-
- ln2, err := net.Listen("tcp", fmt.Sprintf("%s:%v", netInterface, netPort))
+ ln2, err := net.Listen("tcp", fmt.Sprintf("%s:%v", netInterface, netPort+1))
server.FileListener = ln2
if err != nil {
return nil, err
return nil, err
}
- server.Logger.Debugw("Loading Agreement", "path", configDir+agreementFile)
if server.Agreement, err = os.ReadFile(configDir + agreementFile); err != nil {
return nil, err
}
msg := t.GetField(fieldData)
ID := t.GetField(fieldUserID)
- reply := *NewTransaction(
+ reply := NewTransaction(
tranServerMsg,
&ID.Data,
NewField(fieldData, msg.Data),
reply.Fields = append(reply.Fields, NewField(fieldQuotingMsg, t.GetField(fieldQuotingMsg).Data))
}
- res = append(res, reply)
+ res = append(res, *reply)
id, _ := byteToInt(ID.Data)
- otherClient := cc.Server.Clients[uint16(id)]
- if otherClient == nil {
- return res, errors.New("ohno")
+ otherClient, ok := cc.Server.Clients[uint16(id)]
+ if !ok {
+ return res, errors.New("invalid client ID")
}
// Respond with auto reply if other client has it enabled
})
}
}
+
+func TestHandleSendInstantMsg(t *testing.T) {
+ type args struct {
+ cc *ClientConn
+ t *Transaction
+ }
+ tests := []struct {
+ name string
+ args args
+ wantRes []Transaction
+ wantErr assert.ErrorAssertionFunc
+ }{
+ {
+ name: "when client 1 sends a message to client 2",
+ args: args{
+ cc: &ClientConn{
+ ID: &[]byte{0, 1},
+ UserName: []byte("User1"),
+ Server: &Server{
+ Clients: map[uint16]*ClientConn{
+ uint16(2): {
+ AutoReply: []byte(nil),
+ },
+ },
+ },
+ },
+ t: NewTransaction(
+ tranSendInstantMsg,
+ &[]byte{0, 1},
+ NewField(fieldData, []byte("hai")),
+ NewField(fieldUserID, []byte{0, 2}),
+ ),
+ },
+ wantRes: []Transaction{
+ *NewTransaction(
+ tranServerMsg,
+ &[]byte{0, 2},
+ NewField(fieldData, []byte("hai")),
+ NewField(fieldUserName, []byte("User1")),
+ NewField(fieldUserID, []byte{0, 1}),
+ NewField(fieldOptions, []byte{0, 1}),
+ ),
+ {
+ clientID: &[]byte{0, 1},
+ Flags: 0x00,
+ IsReply: 0x01,
+ Type: []byte{0x0, 0x6c},
+ ID: []byte{0, 0, 0, 0},
+ ErrorCode: []byte{0, 0, 0, 0},
+ Fields: []Field(nil),
+ },
+ },
+ wantErr: assert.NoError,
+ },
+ {
+ name: "when client 2 has autoreply enabled",
+ args: args{
+ cc: &ClientConn{
+ ID: &[]byte{0, 1},
+ UserName: []byte("User1"),
+ Server: &Server{
+ Clients: map[uint16]*ClientConn{
+ uint16(2): {
+ ID: &[]byte{0, 2},
+ UserName: []byte("User2"),
+ AutoReply: []byte("autohai"),
+ },
+ },
+ },
+ },
+ t: NewTransaction(
+ tranSendInstantMsg,
+ &[]byte{0, 1},
+ NewField(fieldData, []byte("hai")),
+ NewField(fieldUserID, []byte{0, 2}),
+ ),
+ },
+ wantRes: []Transaction{
+ *NewTransaction(
+ tranServerMsg,
+ &[]byte{0, 2},
+ NewField(fieldData, []byte("hai")),
+ NewField(fieldUserName, []byte("User1")),
+ NewField(fieldUserID, []byte{0, 1}),
+ NewField(fieldOptions, []byte{0, 1}),
+ ),
+ *NewTransaction(
+ tranServerMsg,
+ &[]byte{0, 1},
+ NewField(fieldData, []byte("autohai")),
+ NewField(fieldUserName, []byte("User2")),
+ NewField(fieldUserID, []byte{0, 2}),
+ NewField(fieldOptions, []byte{0, 1}),
+ ),
+ {
+ clientID: &[]byte{0, 1},
+ Flags: 0x00,
+ IsReply: 0x01,
+ Type: []byte{0x0, 0x6c},
+ ID: []byte{0, 0, 0, 0},
+ ErrorCode: []byte{0, 0, 0, 0},
+ Fields: []Field(nil),
+ },
+ },
+ wantErr: assert.NoError,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ gotRes, err := HandleSendInstantMsg(tt.args.cc, tt.args.t)
+ if !tt.wantErr(t, err, fmt.Sprintf("HandleSendInstantMsg(%v, %v)", tt.args.cc, tt.args.t)) {
+ return
+ }
+
+ tranAssertEqual(t, tt.wantRes, gotRes)
+ })
+ }
+}