github.com/nats-io/nats-server/v2@v2.11.0-preview.2/server/client_test.go (about) 1 // Copyright 2012-2022 The NATS Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package server 15 16 import ( 17 "bufio" 18 "bytes" 19 "encoding/json" 20 "fmt" 21 "io" 22 "math" 23 "net" 24 "net/url" 25 "reflect" 26 "regexp" 27 "runtime" 28 "strings" 29 "sync" 30 "sync/atomic" 31 "testing" 32 "time" 33 34 "crypto/tls" 35 36 "github.com/nats-io/jwt/v2" 37 "github.com/nats-io/nats.go" 38 "github.com/nats-io/nkeys" 39 ) 40 41 type serverInfo struct { 42 ID string `json:"server_id"` 43 Host string `json:"host"` 44 Port uint `json:"port"` 45 Version string `json:"version"` 46 AuthRequired bool `json:"auth_required"` 47 TLSRequired bool `json:"tls_required"` 48 MaxPayload int64 `json:"max_payload"` 49 Headers bool `json:"headers"` 50 ConnectURLs []string `json:"connect_urls,omitempty"` 51 LameDuckMode bool `json:"ldm,omitempty"` 52 CID uint64 `json:"client_id,omitempty"` 53 } 54 55 type testAsyncClient struct { 56 *client 57 parseAsync func(string) 58 quitCh chan bool 59 } 60 61 func (c *testAsyncClient) close() { 62 c.client.closeConnection(ClientClosed) 63 c.quitCh <- true 64 } 65 66 func (c *testAsyncClient) parse(proto []byte) error { 67 err := c.client.parse(proto) 68 c.client.flushClients(0) 69 return err 70 } 71 72 func (c *testAsyncClient) parseAndClose(proto []byte) { 73 c.client.parse(proto) 74 c.client.flushClients(0) 75 c.closeConnection(ClientClosed) 76 } 77 78 func createClientAsync(ch chan *client, s *Server, cli net.Conn) { 79 // Normally, those type of clients are used against non running servers. 80 // However, some don't, which would then cause the writeLoop to be 81 // started twice for the same client (since createClient() start both 82 // read and write loop if it is detected as running). 83 startWriteLoop := !s.isRunning() 84 if startWriteLoop { 85 s.grWG.Add(1) 86 } 87 go func() { 88 c := s.createClient(cli) 89 // Must be here to suppress +OK 90 c.opts.Verbose = false 91 if startWriteLoop { 92 go c.writeLoop() 93 } 94 ch <- c 95 }() 96 } 97 98 func newClientForServer(s *Server) (*testAsyncClient, *bufio.Reader, string) { 99 cli, srv := net.Pipe() 100 cr := bufio.NewReaderSize(cli, maxBufSize) 101 ch := make(chan *client) 102 createClientAsync(ch, s, srv) 103 // So failing tests don't just hang. 104 cli.SetReadDeadline(time.Now().Add(10 * time.Second)) 105 l, _ := cr.ReadString('\n') 106 // Grab client 107 c := <-ch 108 parse, quitCh := genAsyncParser(c) 109 asyncClient := &testAsyncClient{ 110 client: c, 111 parseAsync: parse, 112 quitCh: quitCh, 113 } 114 return asyncClient, cr, l 115 } 116 117 func genAsyncParser(c *client) (func(string), chan bool) { 118 pab := make(chan []byte, 16) 119 pas := func(cs string) { pab <- []byte(cs) } 120 quit := make(chan bool) 121 go func() { 122 for { 123 select { 124 case cs := <-pab: 125 c.parse(cs) 126 c.flushClients(0) 127 case <-quit: 128 return 129 } 130 } 131 }() 132 return pas, quit 133 } 134 135 var defaultServerOptions = Options{ 136 Host: "127.0.0.1", 137 Port: -1, 138 Trace: true, 139 Debug: true, 140 DisableShortFirstPing: true, 141 NoLog: true, 142 NoSigs: true, 143 } 144 145 func rawSetup(serverOptions Options) (*Server, *testAsyncClient, *bufio.Reader, string) { 146 s := New(&serverOptions) 147 c, cr, l := newClientForServer(s) 148 return s, c, cr, l 149 } 150 151 func setUpClientWithResponse() (*testAsyncClient, string) { 152 _, c, _, l := rawSetup(defaultServerOptions) 153 return c, l 154 } 155 156 func setupClient() (*Server, *testAsyncClient, *bufio.Reader) { 157 s, c, cr, _ := rawSetup(defaultServerOptions) 158 return s, c, cr 159 } 160 161 func checkClientsCount(t *testing.T, s *Server, expected int) { 162 t.Helper() 163 checkFor(t, 2*time.Second, 15*time.Millisecond, func() error { 164 if nc := s.NumClients(); nc != expected { 165 return fmt.Errorf("The number of expected connections was %v, got %v", expected, nc) 166 } 167 return nil 168 }) 169 } 170 171 func checkAccClientsCount(t *testing.T, acc *Account, expected int) { 172 t.Helper() 173 checkFor(t, 4*time.Second, 10*time.Millisecond, func() error { 174 if nc := acc.NumConnections(); nc != expected { 175 return fmt.Errorf("Expected account %q to have %v clients, got %v", 176 acc.Name, expected, nc) 177 } 178 return nil 179 }) 180 } 181 182 func TestAsyncClientWithRunningServer(t *testing.T) { 183 o := DefaultOptions() 184 s := RunServer(o) 185 defer s.Shutdown() 186 187 c, _, _ := newClientForServer(s) 188 defer c.close() 189 190 buf := make([]byte, 1000000) 191 writeLoopTxt := fmt.Sprintf("writeLoop(%p)", c.client) 192 checkFor(t, time.Second, 15*time.Millisecond, func() error { 193 n := runtime.Stack(buf, true) 194 if count := strings.Count(string(buf[:n]), writeLoopTxt); count != 1 { 195 return fmt.Errorf("writeLoop for client should have been started only once: %v", count) 196 } 197 return nil 198 }) 199 } 200 201 func TestClientCreateAndInfo(t *testing.T) { 202 s, c, _, l := rawSetup(defaultServerOptions) 203 defer c.close() 204 205 if c.cid != 1 { 206 t.Fatalf("Expected cid of 1 vs %d\n", c.cid) 207 } 208 if c.state != OP_START { 209 t.Fatal("Expected state to be OP_START") 210 } 211 212 if !strings.HasPrefix(l, "INFO ") { 213 t.Fatalf("INFO response incorrect: %s\n", l) 214 } 215 // Make sure payload is proper json 216 var info serverInfo 217 err := json.Unmarshal([]byte(l[5:]), &info) 218 if err != nil { 219 t.Fatalf("Could not parse INFO json: %v\n", err) 220 } 221 // Sanity checks 222 if info.MaxPayload != MAX_PAYLOAD_SIZE || 223 info.AuthRequired || info.TLSRequired || 224 int(info.Port) != s.opts.Port { 225 t.Fatalf("INFO inconsistent: %+v\n", info) 226 } 227 } 228 229 func TestClientNoResponderSupport(t *testing.T) { 230 opts := defaultServerOptions 231 s := New(&opts) 232 233 c, _, _ := newClientForServer(s) 234 defer c.close() 235 236 // Force header support if you want to do no_responders. Make sure headers are set. 237 if err := c.parse([]byte("CONNECT {\"no_responders\":true}\r\n")); err == nil { 238 t.Fatalf("Expected error") 239 } 240 241 c, cr, _ := newClientForServer(s) 242 defer c.close() 243 244 c.parseAsync("CONNECT {\"headers\":true, \"no_responders\":true}\r\nSUB reply 1\r\nPUB foo reply 2\r\nok\r\n") 245 246 l, err := cr.ReadString('\n') 247 if err != nil { 248 t.Fatalf("Error receiving msg from server: %v\n", err) 249 } 250 251 am := hmsgPat.FindAllStringSubmatch(l, -1) 252 if len(am) == 0 { 253 t.Fatalf("Did not get a match for %q", l) 254 } 255 checkPayload(cr, []byte("NATS/1.0 503\r\n\r\n"), t) 256 } 257 258 func TestServerHeaderSupport(t *testing.T) { 259 opts := defaultServerOptions 260 s := New(&opts) 261 262 c, _, l := newClientForServer(s) 263 defer c.close() 264 265 if !strings.HasPrefix(l, "INFO ") { 266 t.Fatalf("INFO response incorrect: %s\n", l) 267 } 268 var info serverInfo 269 if err := json.Unmarshal([]byte(l[5:]), &info); err != nil { 270 t.Fatalf("Could not parse INFO json: %v\n", err) 271 } 272 if !info.Headers { 273 t.Fatalf("Expected by default for header support to be enabled") 274 } 275 276 opts.NoHeaderSupport = true 277 opts.Port = -1 278 s = New(&opts) 279 280 c, _, l = newClientForServer(s) 281 defer c.close() 282 283 if err := json.Unmarshal([]byte(l[5:]), &info); err != nil { 284 t.Fatalf("Could not parse INFO json: %v\n", err) 285 } 286 if info.Headers { 287 t.Fatalf("Expected header support to be disabled") 288 } 289 } 290 291 // This test specifically is not testing how headers are encoded in a raw msg. 292 // It wants to make sure the serve and clients agreement on when to use headers 293 // is bi-directional and functions properly. 294 func TestClientHeaderSupport(t *testing.T) { 295 opts := defaultServerOptions 296 s := New(&opts) 297 298 c, _, _ := newClientForServer(s) 299 defer c.close() 300 301 // Even though the server supports headers we need to explicitly say we do in the 302 // CONNECT. If we do not we should get an error. 303 if err := c.parse([]byte("CONNECT {}\r\nHPUB foo 0 2\r\nok\r\n")); err != ErrMsgHeadersNotSupported { 304 t.Fatalf("Expected to receive an error, got %v", err) 305 } 306 307 // This should succeed. 308 c, _, _ = newClientForServer(s) 309 defer c.close() 310 311 if err := c.parse([]byte("CONNECT {\"headers\":true}\r\nHPUB foo 0 2\r\nok\r\n")); err != nil { 312 t.Fatalf("Unexpected error %v", err) 313 } 314 315 // Now start a server without support. 316 opts.NoHeaderSupport = true 317 opts.Port = -1 318 s = New(&opts) 319 320 c, _, _ = newClientForServer(s) 321 defer c.close() 322 if err := c.parse([]byte("CONNECT {\"headers\":true}\r\nHPUB foo 0 2\r\nok\r\n")); err != ErrMsgHeadersNotSupported { 323 t.Fatalf("Expected to receive an error, got %v", err) 324 } 325 } 326 327 var hmsgPat = regexp.MustCompile(`HMSG\s+([^\s]+)\s+([^\s]+)\s+(([^\s]+)[^\S\r\n]+)?(\d+)[^\S\r\n]+(\d+)\r\n`) 328 329 func TestClientHeaderDeliverMsg(t *testing.T) { 330 opts := defaultServerOptions 331 s := New(&opts) 332 333 c, cr, _ := newClientForServer(s) 334 defer c.close() 335 336 connect := "CONNECT {\"headers\":true}" 337 subOp := "SUB foo 1" 338 pubOp := "HPUB foo 12 14\r\nName:Derek\r\nOK\r\n" 339 cmd := strings.Join([]string{connect, subOp, pubOp}, "\r\n") 340 341 c.parseAsync(cmd) 342 l, err := cr.ReadString('\n') 343 if err != nil { 344 t.Fatalf("Error receiving msg from server: %v\n", err) 345 } 346 347 am := hmsgPat.FindAllStringSubmatch(l, -1) 348 if len(am) == 0 { 349 t.Fatalf("Did not get a match for %q", l) 350 } 351 matches := am[0] 352 if len(matches) != 7 { 353 t.Fatalf("Did not get correct # matches: %d vs %d\n", len(matches), 7) 354 } 355 if matches[SUB_INDEX] != "foo" { 356 t.Fatalf("Did not get correct subject: '%s'\n", matches[SUB_INDEX]) 357 } 358 if matches[SID_INDEX] != "1" { 359 t.Fatalf("Did not get correct sid: '%s'\n", matches[SID_INDEX]) 360 } 361 if matches[HDR_INDEX] != "12" { 362 t.Fatalf("Did not get correct msg length: '%s'\n", matches[HDR_INDEX]) 363 } 364 if matches[TLEN_INDEX] != "14" { 365 t.Fatalf("Did not get correct msg length: '%s'\n", matches[TLEN_INDEX]) 366 } 367 checkPayload(cr, []byte("Name:Derek\r\nOK\r\n"), t) 368 } 369 370 var smsgPat = regexp.MustCompile(`^MSG\s+([^\s]+)\s+([^\s]+)\s+(([^\s]+)[^\S\r\n]+)?(\d+)\r\n`) 371 372 func TestClientHeaderDeliverStrippedMsg(t *testing.T) { 373 opts := defaultServerOptions 374 s := New(&opts) 375 376 c, _, _ := newClientForServer(s) 377 defer c.close() 378 379 b, br, _ := newClientForServer(s) 380 defer b.close() 381 382 // Does not support headers 383 b.parseAsync("SUB foo 1\r\nPING\r\n") 384 if _, err := br.ReadString('\n'); err != nil { 385 t.Fatalf("Error receiving msg from server: %v\n", err) 386 } 387 388 connect := "CONNECT {\"headers\":true}" 389 pubOp := "HPUB foo 12 14\r\nName:Derek\r\nOK\r\n" 390 cmd := strings.Join([]string{connect, pubOp}, "\r\n") 391 c.parseAsync(cmd) 392 // Read from 'b' client. 393 l, err := br.ReadString('\n') 394 if err != nil { 395 t.Fatalf("Error receiving msg from server: %v\n", err) 396 } 397 am := smsgPat.FindAllStringSubmatch(l, -1) 398 if len(am) == 0 { 399 t.Fatalf("Did not get a correct match for %q", l) 400 } 401 matches := am[0] 402 if len(matches) != 6 { 403 t.Fatalf("Did not get correct # matches: %d vs %d\n", len(matches), 6) 404 } 405 if matches[SUB_INDEX] != "foo" { 406 t.Fatalf("Did not get correct subject: '%s'\n", matches[SUB_INDEX]) 407 } 408 if matches[SID_INDEX] != "1" { 409 t.Fatalf("Did not get correct sid: '%s'\n", matches[SID_INDEX]) 410 } 411 if matches[LEN_INDEX] != "2" { 412 t.Fatalf("Did not get correct msg length: '%s'\n", matches[LEN_INDEX]) 413 } 414 checkPayload(br, []byte("OK\r\n"), t) 415 if br.Buffered() != 0 { 416 t.Fatalf("Expected no extra bytes to be buffered, got %d", br.Buffered()) 417 } 418 } 419 420 func TestClientHeaderDeliverQueueSubStrippedMsg(t *testing.T) { 421 opts := defaultServerOptions 422 s := New(&opts) 423 424 c, _, _ := newClientForServer(s) 425 defer c.close() 426 427 b, br, _ := newClientForServer(s) 428 defer b.close() 429 430 // Does not support headers 431 b.parseAsync("SUB foo bar 1\r\nPING\r\n") 432 if _, err := br.ReadString('\n'); err != nil { 433 t.Fatalf("Error receiving msg from server: %v\n", err) 434 } 435 436 connect := "CONNECT {\"headers\":true}" 437 pubOp := "HPUB foo 12 14\r\nName:Derek\r\nOK\r\n" 438 cmd := strings.Join([]string{connect, pubOp}, "\r\n") 439 c.parseAsync(cmd) 440 // Read from 'b' client. 441 l, err := br.ReadString('\n') 442 if err != nil { 443 t.Fatalf("Error receiving msg from server: %v\n", err) 444 } 445 am := smsgPat.FindAllStringSubmatch(l, -1) 446 if len(am) == 0 { 447 t.Fatalf("Did not get a correct match for %q", l) 448 } 449 matches := am[0] 450 if len(matches) != 6 { 451 t.Fatalf("Did not get correct # matches: %d vs %d\n", len(matches), 6) 452 } 453 if matches[SUB_INDEX] != "foo" { 454 t.Fatalf("Did not get correct subject: '%s'\n", matches[SUB_INDEX]) 455 } 456 if matches[SID_INDEX] != "1" { 457 t.Fatalf("Did not get correct sid: '%s'\n", matches[SID_INDEX]) 458 } 459 if matches[LEN_INDEX] != "2" { 460 t.Fatalf("Did not get correct msg length: '%s'\n", matches[LEN_INDEX]) 461 } 462 checkPayload(br, []byte("OK\r\n"), t) 463 } 464 465 func TestNonTLSConnectionState(t *testing.T) { 466 _, c, _ := setupClient() 467 defer c.close() 468 state := c.GetTLSConnectionState() 469 if state != nil { 470 t.Error("GetTLSConnectionState() returned non-nil") 471 } 472 } 473 474 func TestClientConnect(t *testing.T) { 475 _, c, _ := setupClient() 476 defer c.close() 477 478 // Basic Connect setting flags 479 connectOp := []byte("CONNECT {\"verbose\":true,\"pedantic\":true,\"tls_required\":false,\"echo\":false}\r\n") 480 err := c.parse(connectOp) 481 if err != nil { 482 t.Fatalf("Received error: %v\n", err) 483 } 484 if c.state != OP_START { 485 t.Fatalf("Expected state of OP_START vs %d\n", c.state) 486 } 487 if !reflect.DeepEqual(c.opts, ClientOpts{Verbose: true, Pedantic: true, Echo: false}) { 488 t.Fatalf("Did not parse connect options correctly: %+v\n", c.opts) 489 } 490 491 // Test that we can capture user/pass 492 connectOp = []byte("CONNECT {\"user\":\"derek\",\"pass\":\"foo\"}\r\n") 493 c.opts = defaultOpts 494 err = c.parse(connectOp) 495 if err != nil { 496 t.Fatalf("Received error: %v\n", err) 497 } 498 if c.state != OP_START { 499 t.Fatalf("Expected state of OP_START vs %d\n", c.state) 500 } 501 if !reflect.DeepEqual(c.opts, ClientOpts{Echo: true, Verbose: true, Pedantic: true, Username: "derek", Password: "foo"}) { 502 t.Fatalf("Did not parse connect options correctly: %+v\n", c.opts) 503 } 504 505 // Test that we can capture client name 506 connectOp = []byte("CONNECT {\"user\":\"derek\",\"pass\":\"foo\",\"name\":\"router\"}\r\n") 507 c.opts = defaultOpts 508 err = c.parse(connectOp) 509 if err != nil { 510 t.Fatalf("Received error: %v\n", err) 511 } 512 if c.state != OP_START { 513 t.Fatalf("Expected state of OP_START vs %d\n", c.state) 514 } 515 516 if !reflect.DeepEqual(c.opts, ClientOpts{Echo: true, Verbose: true, Pedantic: true, Username: "derek", Password: "foo", Name: "router"}) { 517 t.Fatalf("Did not parse connect options correctly: %+v\n", c.opts) 518 } 519 520 // Test that we correctly capture auth tokens 521 connectOp = []byte("CONNECT {\"auth_token\":\"YZZ222\",\"name\":\"router\"}\r\n") 522 c.opts = defaultOpts 523 err = c.parse(connectOp) 524 if err != nil { 525 t.Fatalf("Received error: %v\n", err) 526 } 527 if c.state != OP_START { 528 t.Fatalf("Expected state of OP_START vs %d\n", c.state) 529 } 530 531 if !reflect.DeepEqual(c.opts, ClientOpts{Echo: true, Verbose: true, Pedantic: true, Token: "YZZ222", Name: "router"}) { 532 t.Fatalf("Did not parse connect options correctly: %+v\n", c.opts) 533 } 534 } 535 536 func TestClientConnectProto(t *testing.T) { 537 _, c, r := setupClient() 538 defer c.close() 539 540 // Basic Connect setting flags, proto should be zero (original proto) 541 connectOp := []byte("CONNECT {\"verbose\":true,\"pedantic\":true,\"tls_required\":false}\r\n") 542 err := c.parse(connectOp) 543 if err != nil { 544 t.Fatalf("Received error: %v\n", err) 545 } 546 if c.state != OP_START { 547 t.Fatalf("Expected state of OP_START vs %d\n", c.state) 548 } 549 if !reflect.DeepEqual(c.opts, ClientOpts{Echo: true, Verbose: true, Pedantic: true, Protocol: ClientProtoZero}) { 550 t.Fatalf("Did not parse connect options correctly: %+v\n", c.opts) 551 } 552 553 // ProtoInfo 554 connectOp = []byte(fmt.Sprintf("CONNECT {\"verbose\":true,\"pedantic\":true,\"tls_required\":false,\"protocol\":%d}\r\n", ClientProtoInfo)) 555 err = c.parse(connectOp) 556 if err != nil { 557 t.Fatalf("Received error: %v\n", err) 558 } 559 if c.state != OP_START { 560 t.Fatalf("Expected state of OP_START vs %d\n", c.state) 561 } 562 if !reflect.DeepEqual(c.opts, ClientOpts{Echo: true, Verbose: true, Pedantic: true, Protocol: ClientProtoInfo}) { 563 t.Fatalf("Did not parse connect options correctly: %+v\n", c.opts) 564 } 565 if c.opts.Protocol != ClientProtoInfo { 566 t.Fatalf("Protocol should have been set to %v, but is set to %v", ClientProtoInfo, c.opts.Protocol) 567 } 568 569 // Illegal Option 570 connectOp = []byte("CONNECT {\"protocol\":22}\r\n") 571 wg := sync.WaitGroup{} 572 wg.Add(1) 573 // The client here is using a pipe, we need to be dequeuing 574 // data otherwise the server would be blocked trying to send 575 // the error back to it. 576 go func() { 577 defer wg.Done() 578 for { 579 if _, _, err := r.ReadLine(); err != nil { 580 return 581 } 582 } 583 }() 584 err = c.parse(connectOp) 585 if err == nil { 586 t.Fatalf("Expected to receive an error\n") 587 } 588 if err != ErrBadClientProtocol { 589 t.Fatalf("Expected err of %q, got %q\n", ErrBadClientProtocol, err) 590 } 591 wg.Wait() 592 } 593 594 func TestRemoteAddress(t *testing.T) { 595 rc := &client{} 596 597 // though in reality this will panic if it does not, adding coverage anyway 598 if rc.RemoteAddress() != nil { 599 t.Errorf("RemoteAddress() did not handle nil connection correctly") 600 } 601 602 _, c, _ := setupClient() 603 defer c.close() 604 addr := c.RemoteAddress() 605 606 if addr.Network() != "pipe" { 607 t.Errorf("RemoteAddress() returned invalid network: %s", addr.Network()) 608 } 609 610 if addr.String() != "pipe" { 611 t.Errorf("RemoteAddress() returned invalid string: %s", addr.String()) 612 } 613 } 614 615 func TestClientPing(t *testing.T) { 616 _, c, cr := setupClient() 617 defer c.close() 618 619 // PING 620 pingOp := "PING\r\n" 621 c.parseAsync(pingOp) 622 l, err := cr.ReadString('\n') 623 if err != nil { 624 t.Fatalf("Error receiving info from server: %v\n", err) 625 } 626 if !strings.HasPrefix(l, "PONG\r\n") { 627 t.Fatalf("PONG response incorrect: %s\n", l) 628 } 629 } 630 631 var msgPat = regexp.MustCompile(`MSG\s+([^\s]+)\s+([^\s]+)\s+(([^\s]+)[^\S\r\n]+)?(\d+)\r\n`) 632 633 const ( 634 SUB_INDEX = 1 635 SID_INDEX = 2 636 REPLY_INDEX = 4 637 LEN_INDEX = 5 638 HDR_INDEX = 5 639 TLEN_INDEX = 6 640 ) 641 642 func grabPayload(cr *bufio.Reader, expected int) []byte { 643 d := make([]byte, expected) 644 n, _ := cr.Read(d) 645 cr.ReadString('\n') 646 return d[:n] 647 } 648 649 func checkPayload(cr *bufio.Reader, expected []byte, t *testing.T) { 650 t.Helper() 651 // Read in payload 652 d := make([]byte, len(expected)) 653 n, err := cr.Read(d) 654 if err != nil { 655 t.Fatalf("Error receiving msg payload from server: %v\n", err) 656 } 657 if n != len(expected) { 658 t.Fatalf("Did not read correct amount of bytes: %d vs %d\n", n, len(expected)) 659 } 660 if !bytes.Equal(d, expected) { 661 t.Fatalf("Did not read correct payload:: <%s>\n", d) 662 } 663 } 664 665 func TestClientSimplePubSub(t *testing.T) { 666 _, c, cr := setupClient() 667 defer c.close() 668 // SUB/PUB 669 c.parseAsync("SUB foo 1\r\nPUB foo 5\r\nhello\r\nPING\r\n") 670 l, err := cr.ReadString('\n') 671 if err != nil { 672 t.Fatalf("Error receiving msg from server: %v\n", err) 673 } 674 matches := msgPat.FindAllStringSubmatch(l, -1)[0] 675 if len(matches) != 6 { 676 t.Fatalf("Did not get correct # matches: %d vs %d\n", len(matches), 6) 677 } 678 if matches[SUB_INDEX] != "foo" { 679 t.Fatalf("Did not get correct subject: '%s'\n", matches[SUB_INDEX]) 680 } 681 if matches[SID_INDEX] != "1" { 682 t.Fatalf("Did not get correct sid: '%s'\n", matches[SID_INDEX]) 683 } 684 if matches[LEN_INDEX] != "5" { 685 t.Fatalf("Did not get correct msg length: '%s'\n", matches[LEN_INDEX]) 686 } 687 checkPayload(cr, []byte("hello\r\n"), t) 688 } 689 690 func TestClientPubSubNoEcho(t *testing.T) { 691 _, c, cr := setupClient() 692 defer c.close() 693 // Specify no echo 694 connectOp := []byte("CONNECT {\"echo\":false}\r\n") 695 err := c.parse(connectOp) 696 if err != nil { 697 t.Fatalf("Received error: %v\n", err) 698 } 699 // SUB/PUB 700 c.parseAsync("SUB foo 1\r\nPUB foo 5\r\nhello\r\nPING\r\n") 701 l, err := cr.ReadString('\n') 702 if err != nil { 703 t.Fatalf("Error receiving msg from server: %v\n", err) 704 } 705 // We should not receive anything but a PONG since we specified no echo. 706 if !strings.HasPrefix(l, "PONG\r\n") { 707 t.Fatalf("PONG response incorrect: %q\n", l) 708 } 709 } 710 711 func TestClientSimplePubSubWithReply(t *testing.T) { 712 _, c, cr := setupClient() 713 defer c.close() 714 715 // SUB/PUB 716 c.parseAsync("SUB foo 1\r\nPUB foo bar 5\r\nhello\r\nPING\r\n") 717 l, err := cr.ReadString('\n') 718 if err != nil { 719 t.Fatalf("Error receiving msg from server: %v\n", err) 720 } 721 matches := msgPat.FindAllStringSubmatch(l, -1)[0] 722 if len(matches) != 6 { 723 t.Fatalf("Did not get correct # matches: %d vs %d\n", len(matches), 6) 724 } 725 if matches[SUB_INDEX] != "foo" { 726 t.Fatalf("Did not get correct subject: '%s'\n", matches[SUB_INDEX]) 727 } 728 if matches[SID_INDEX] != "1" { 729 t.Fatalf("Did not get correct sid: '%s'\n", matches[SID_INDEX]) 730 } 731 if matches[REPLY_INDEX] != "bar" { 732 t.Fatalf("Did not get correct reply subject: '%s'\n", matches[REPLY_INDEX]) 733 } 734 if matches[LEN_INDEX] != "5" { 735 t.Fatalf("Did not get correct msg length: '%s'\n", matches[LEN_INDEX]) 736 } 737 } 738 739 func TestClientNoBodyPubSubWithReply(t *testing.T) { 740 _, c, cr := setupClient() 741 defer c.close() 742 743 // SUB/PUB 744 c.parseAsync("SUB foo 1\r\nPUB foo bar 0\r\n\r\nPING\r\n") 745 l, err := cr.ReadString('\n') 746 if err != nil { 747 t.Fatalf("Error receiving msg from server: %v\n", err) 748 } 749 matches := msgPat.FindAllStringSubmatch(l, -1)[0] 750 if len(matches) != 6 { 751 t.Fatalf("Did not get correct # matches: %d vs %d\n", len(matches), 6) 752 } 753 if matches[SUB_INDEX] != "foo" { 754 t.Fatalf("Did not get correct subject: '%s'\n", matches[SUB_INDEX]) 755 } 756 if matches[SID_INDEX] != "1" { 757 t.Fatalf("Did not get correct sid: '%s'\n", matches[SID_INDEX]) 758 } 759 if matches[REPLY_INDEX] != "bar" { 760 t.Fatalf("Did not get correct reply subject: '%s'\n", matches[REPLY_INDEX]) 761 } 762 if matches[LEN_INDEX] != "0" { 763 t.Fatalf("Did not get correct msg length: '%s'\n", matches[LEN_INDEX]) 764 } 765 } 766 767 func TestClientPubWithQueueSub(t *testing.T) { 768 _, c, cr := setupClient() 769 defer c.close() 770 771 num := 100 772 773 // Queue SUB/PUB 774 subs := []byte("SUB foo g1 1\r\nSUB foo g1 2\r\n") 775 pubs := []byte("PUB foo bar 5\r\nhello\r\n") 776 op := []byte{} 777 op = append(op, subs...) 778 for i := 0; i < num; i++ { 779 op = append(op, pubs...) 780 } 781 782 go c.parseAndClose(op) 783 784 var n1, n2, received int 785 for ; ; received++ { 786 l, err := cr.ReadString('\n') 787 if err != nil { 788 break 789 } 790 matches := msgPat.FindAllStringSubmatch(l, -1)[0] 791 792 // Count which sub 793 switch matches[SID_INDEX] { 794 case "1": 795 n1++ 796 case "2": 797 n2++ 798 } 799 checkPayload(cr, []byte("hello\r\n"), t) 800 } 801 if received != num { 802 t.Fatalf("Received wrong # of msgs: %d vs %d\n", received, num) 803 } 804 // Threshold for randomness for now 805 if n1 < 20 || n2 < 20 { 806 t.Fatalf("Received wrong # of msgs per subscriber: %d - %d\n", n1, n2) 807 } 808 } 809 810 func TestSplitSubjectQueue(t *testing.T) { 811 cases := []struct { 812 name string 813 sq string 814 wantSubject []byte 815 wantQueue []byte 816 wantErr bool 817 }{ 818 {name: "single subject", 819 sq: "foo", wantSubject: []byte("foo"), wantQueue: nil}, 820 {name: "subject and queue", 821 sq: "foo bar", wantSubject: []byte("foo"), wantQueue: []byte("bar")}, 822 {name: "subject and queue with surrounding spaces", 823 sq: " foo bar ", wantSubject: []byte("foo"), wantQueue: []byte("bar")}, 824 {name: "subject and queue with extra spaces in the middle", 825 sq: "foo bar", wantSubject: []byte("foo"), wantQueue: []byte("bar")}, 826 {name: "subject, queue, and extra token", 827 sq: "foo bar fizz", wantSubject: []byte(nil), wantQueue: []byte(nil), wantErr: true}, 828 } 829 830 for _, c := range cases { 831 t.Run(c.name, func(t *testing.T) { 832 sub, que, err := splitSubjectQueue(c.sq) 833 if err == nil && c.wantErr { 834 t.Fatal("Expected error, but got nil") 835 } 836 if err != nil && !c.wantErr { 837 t.Fatalf("Expected nil error, but got %v", err) 838 } 839 840 if !reflect.DeepEqual(sub, c.wantSubject) { 841 t.Fatalf("Expected to get subject %#v, but instead got %#v", c.wantSubject, sub) 842 } 843 if !reflect.DeepEqual(que, c.wantQueue) { 844 t.Fatalf("Expected to get queue %#v, but instead got %#v", c.wantQueue, que) 845 } 846 }) 847 } 848 } 849 850 func TestTypeString(t *testing.T) { 851 cases := []struct { 852 intType int 853 stringType string 854 }{ 855 { 856 intType: CLIENT, 857 stringType: "Client", 858 }, 859 { 860 intType: ROUTER, 861 stringType: "Router", 862 }, 863 { 864 intType: GATEWAY, 865 stringType: "Gateway", 866 }, 867 { 868 intType: LEAF, 869 stringType: "Leafnode", 870 }, 871 { 872 intType: JETSTREAM, 873 stringType: "JetStream", 874 }, 875 { 876 intType: ACCOUNT, 877 stringType: "Account", 878 }, 879 { 880 intType: SYSTEM, 881 stringType: "System", 882 }, 883 { 884 intType: -1, 885 stringType: "Unknown Type", 886 }, 887 } 888 for _, cs := range cases { 889 c := &client{kind: cs.intType} 890 typeStringVal := c.kindString() 891 892 if typeStringVal != cs.stringType { 893 t.Fatalf("Expected typeString value %q, but instead received %q", cs.stringType, typeStringVal) 894 } 895 } 896 } 897 898 func TestQueueSubscribePermissions(t *testing.T) { 899 cases := []struct { 900 name string 901 perms *SubjectPermission 902 subject string 903 queue string 904 want string 905 }{ 906 { 907 name: "plain subscription on foo", 908 perms: &SubjectPermission{Allow: []string{"foo"}}, 909 subject: "foo", 910 want: "+OK\r\n", 911 }, 912 { 913 name: "queue subscribe with allowed group", 914 perms: &SubjectPermission{Allow: []string{"foo bar"}}, 915 subject: "foo", 916 queue: "bar", 917 want: "+OK\r\n", 918 }, 919 { 920 name: "queue subscribe with wildcard allowed group", 921 perms: &SubjectPermission{Allow: []string{"foo bar.*"}}, 922 subject: "foo", 923 queue: "bar.fizz", 924 want: "+OK\r\n", 925 }, 926 { 927 name: "queue subscribe with full wildcard subject and subgroup", 928 perms: &SubjectPermission{Allow: []string{"> bar.>"}}, 929 subject: "whizz", 930 queue: "bar.bang", 931 want: "+OK\r\n", 932 }, 933 { 934 name: "plain subscribe with full wildcard subject and subgroup", 935 perms: &SubjectPermission{Allow: []string{"> bar.>"}}, 936 subject: "whizz", 937 want: "-ERR 'Permissions Violation for Subscription to \"whizz\"'\r\n", 938 }, 939 { 940 name: "deny plain subscription on foo", 941 perms: &SubjectPermission{Allow: []string{">"}, Deny: []string{"foo"}}, 942 subject: "foo", 943 queue: "bar", 944 want: "-ERR 'Permissions Violation for Subscription to \"foo\" using queue \"bar\"'\r\n", 945 }, 946 { 947 name: "allow plain subscription, except foo", 948 perms: &SubjectPermission{Allow: []string{">"}, Deny: []string{"foo"}}, 949 subject: "bar", 950 want: "+OK\r\n", 951 }, 952 { 953 name: "deny everything", 954 perms: &SubjectPermission{Allow: []string{">"}, Deny: []string{">"}}, 955 subject: "foo", 956 queue: "bar", 957 want: "-ERR 'Permissions Violation for Subscription to \"foo\" using queue \"bar\"'\r\n", 958 }, 959 { 960 name: "can only subscribe to queues v1", 961 perms: &SubjectPermission{Allow: []string{"> v1.>"}}, 962 subject: "foo", 963 queue: "v1.prod", 964 want: "+OK\r\n", 965 }, 966 { 967 name: "cannot subscribe to queues, plain subscribe ok", 968 perms: &SubjectPermission{Allow: []string{">"}, Deny: []string{"> >"}}, 969 subject: "foo", 970 want: "+OK\r\n", 971 }, 972 { 973 name: "cannot subscribe to queues, queue subscribe not ok", 974 perms: &SubjectPermission{Deny: []string{"> >"}}, 975 subject: "foo", 976 queue: "bar", 977 want: "-ERR 'Permissions Violation for Subscription to \"foo\" using queue \"bar\"'\r\n", 978 }, 979 { 980 name: "deny all queue subscriptions on dev or stg only", 981 perms: &SubjectPermission{Deny: []string{"> *.dev", "> *.stg"}}, 982 subject: "foo", 983 queue: "bar", 984 want: "+OK\r\n", 985 }, 986 { 987 name: "allow only queue subscription on dev or stg", 988 perms: &SubjectPermission{Allow: []string{"> *.dev", "> *.stg"}}, 989 subject: "foo", 990 queue: "bar", 991 want: "-ERR 'Permissions Violation for Subscription to \"foo\" using queue \"bar\"'\r\n", 992 }, 993 { 994 name: "deny queue subscriptions with subject foo", 995 perms: &SubjectPermission{Deny: []string{"foo >"}}, 996 subject: "foo", 997 queue: "bar", 998 want: "-ERR 'Permissions Violation for Subscription to \"foo\" using queue \"bar\"'\r\n", 999 }, 1000 { 1001 name: "plain sub is allowed, but queue subscribe with queue not in list", 1002 perms: &SubjectPermission{Allow: []string{"foo bar"}}, 1003 subject: "foo", 1004 queue: "fizz", 1005 want: "-ERR 'Permissions Violation for Subscription to \"foo\" using queue \"fizz\"'\r\n", 1006 }, 1007 { 1008 name: "allow plain sub, but do queue subscribe", 1009 perms: &SubjectPermission{Allow: []string{"foo"}}, 1010 subject: "foo", 1011 queue: "bar", 1012 want: "+OK\r\n", 1013 }, 1014 } 1015 for _, c := range cases { 1016 t.Run(c.name, func(t *testing.T) { 1017 _, client, r := setupClient() 1018 defer client.close() 1019 1020 client.RegisterUser(&User{ 1021 Permissions: &Permissions{Subscribe: c.perms}, 1022 }) 1023 connect := []byte("CONNECT {\"verbose\":true}\r\n") 1024 qsub := []byte(fmt.Sprintf("SUB %s %s 1\r\n", c.subject, c.queue)) 1025 1026 go client.parseAndClose(append(connect, qsub...)) 1027 1028 var buf bytes.Buffer 1029 if _, err := io.Copy(&buf, r); err != nil { 1030 t.Fatal(err) 1031 } 1032 1033 // Extra OK is from the successful CONNECT. 1034 want := "+OK\r\n" + c.want 1035 if got := buf.String(); got != want { 1036 t.Fatalf("Expected to receive %q, but instead received %q", want, got) 1037 } 1038 }) 1039 } 1040 } 1041 1042 func TestClientPubWithQueueSubNoEcho(t *testing.T) { 1043 opts := DefaultOptions() 1044 s := RunServer(opts) 1045 defer s.Shutdown() 1046 1047 nc1, err := nats.Connect(fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)) 1048 if err != nil { 1049 t.Fatalf("Error on connect: %v", err) 1050 } 1051 defer nc1.Close() 1052 1053 // Grab the client from server and set no echo by hand. 1054 s.mu.Lock() 1055 lc := len(s.clients) 1056 c := s.clients[s.gcid] 1057 s.mu.Unlock() 1058 1059 if lc != 1 { 1060 t.Fatalf("Expected only 1 client but got %d\n", lc) 1061 } 1062 if c == nil { 1063 t.Fatal("Expected to retrieve client\n") 1064 } 1065 c.mu.Lock() 1066 c.echo = false 1067 c.mu.Unlock() 1068 1069 // Queue sub on nc1. 1070 _, err = nc1.QueueSubscribe("foo", "bar", func(*nats.Msg) {}) 1071 if err != nil { 1072 t.Fatalf("Error on subscribe: %v", err) 1073 } 1074 nc1.Flush() 1075 1076 nc2, err := nats.Connect(fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)) 1077 if err != nil { 1078 t.Fatalf("Error on connect: %v", err) 1079 } 1080 defer nc2.Close() 1081 1082 n := int32(0) 1083 cb := func(m *nats.Msg) { 1084 atomic.AddInt32(&n, 1) 1085 } 1086 1087 _, err = nc2.QueueSubscribe("foo", "bar", cb) 1088 if err != nil { 1089 t.Fatalf("Error on subscribe: %v", err) 1090 } 1091 nc2.Flush() 1092 1093 // Now publish 100 messages on nc1 which does not allow echo. 1094 for i := 0; i < 100; i++ { 1095 nc1.Publish("foo", []byte("Hello")) 1096 } 1097 nc1.Flush() 1098 nc2.Flush() 1099 1100 checkFor(t, 5*time.Second, 10*time.Millisecond, func() error { 1101 num := atomic.LoadInt32(&n) 1102 if num != int32(100) { 1103 return fmt.Errorf("Expected all the msgs to be received by nc2, got %d\n", num) 1104 } 1105 return nil 1106 }) 1107 } 1108 1109 func TestClientUnSub(t *testing.T) { 1110 _, c, cr := setupClient() 1111 defer c.close() 1112 1113 num := 1 1114 1115 // SUB/PUB 1116 subs := []byte("SUB foo 1\r\nSUB foo 2\r\n") 1117 unsub := []byte("UNSUB 1\r\n") 1118 pub := []byte("PUB foo bar 5\r\nhello\r\n") 1119 1120 op := []byte{} 1121 op = append(op, subs...) 1122 op = append(op, unsub...) 1123 op = append(op, pub...) 1124 1125 go c.parseAndClose(op) 1126 1127 var received int 1128 for ; ; received++ { 1129 l, err := cr.ReadString('\n') 1130 if err != nil { 1131 break 1132 } 1133 matches := msgPat.FindAllStringSubmatch(l, -1)[0] 1134 if matches[SID_INDEX] != "2" { 1135 t.Fatalf("Received msg on unsubscribed subscription!\n") 1136 } 1137 checkPayload(cr, []byte("hello\r\n"), t) 1138 } 1139 if received != num { 1140 t.Fatalf("Received wrong # of msgs: %d vs %d\n", received, num) 1141 } 1142 } 1143 1144 func TestClientUnSubMax(t *testing.T) { 1145 _, c, cr := setupClient() 1146 defer c.close() 1147 1148 num := 10 1149 exp := 5 1150 1151 // SUB/PUB 1152 subs := []byte("SUB foo 1\r\n") 1153 unsub := []byte("UNSUB 1 5\r\n") 1154 pub := []byte("PUB foo bar 5\r\nhello\r\n") 1155 1156 op := []byte{} 1157 op = append(op, subs...) 1158 op = append(op, unsub...) 1159 for i := 0; i < num; i++ { 1160 op = append(op, pub...) 1161 } 1162 1163 go c.parseAndClose(op) 1164 1165 var received int 1166 for ; ; received++ { 1167 l, err := cr.ReadString('\n') 1168 if err != nil { 1169 break 1170 } 1171 matches := msgPat.FindAllStringSubmatch(l, -1)[0] 1172 if matches[SID_INDEX] != "1" { 1173 t.Fatalf("Received msg on unsubscribed subscription!\n") 1174 } 1175 checkPayload(cr, []byte("hello\r\n"), t) 1176 } 1177 if received != exp { 1178 t.Fatalf("Received wrong # of msgs: %d vs %d\n", received, exp) 1179 } 1180 } 1181 1182 func TestClientAutoUnsubExactReceived(t *testing.T) { 1183 _, c, _ := setupClient() 1184 defer c.close() 1185 1186 // SUB/PUB 1187 subs := []byte("SUB foo 1\r\n") 1188 unsub := []byte("UNSUB 1 1\r\n") 1189 pub := []byte("PUB foo bar 2\r\nok\r\n") 1190 1191 op := []byte{} 1192 op = append(op, subs...) 1193 op = append(op, unsub...) 1194 op = append(op, pub...) 1195 1196 c.parse(op) 1197 1198 // We should not have any subscriptions in place here. 1199 if len(c.subs) != 0 { 1200 t.Fatalf("Wrong number of subscriptions: expected 0, got %d\n", len(c.subs)) 1201 } 1202 } 1203 1204 func TestClientUnsubAfterAutoUnsub(t *testing.T) { 1205 _, c, _ := setupClient() 1206 defer c.close() 1207 1208 // SUB/UNSUB/UNSUB 1209 subs := []byte("SUB foo 1\r\n") 1210 asub := []byte("UNSUB 1 1\r\n") 1211 unsub := []byte("UNSUB 1\r\n") 1212 1213 op := []byte{} 1214 op = append(op, subs...) 1215 op = append(op, asub...) 1216 op = append(op, unsub...) 1217 1218 c.parse(op) 1219 1220 // We should not have any subscriptions in place here. 1221 if len(c.subs) != 0 { 1222 t.Fatalf("Wrong number of subscriptions: expected 0, got %d\n", len(c.subs)) 1223 } 1224 } 1225 1226 func TestClientRemoveSubsOnDisconnect(t *testing.T) { 1227 s, c, _ := setupClient() 1228 defer c.close() 1229 subs := []byte("SUB foo 1\r\nSUB bar 2\r\n") 1230 1231 c.parse(subs) 1232 1233 if s.NumSubscriptions() != 2 { 1234 t.Fatalf("Should have 2 subscriptions, got %d\n", s.NumSubscriptions()) 1235 } 1236 c.closeConnection(ClientClosed) 1237 checkExpectedSubs(t, 0, s) 1238 } 1239 1240 func TestClientDoesNotAddSubscriptionsWhenConnectionClosed(t *testing.T) { 1241 _, c, _ := setupClient() 1242 c.close() 1243 subs := []byte("SUB foo 1\r\nSUB bar 2\r\n") 1244 1245 c.parse(subs) 1246 1247 if c.acc.sl.Count() != 0 { 1248 t.Fatalf("Should have no subscriptions after close, got %d\n", c.acc.sl.Count()) 1249 } 1250 } 1251 1252 func TestClientMapRemoval(t *testing.T) { 1253 s, c, _ := setupClient() 1254 c.close() 1255 1256 checkClientsCount(t, s, 0) 1257 } 1258 1259 func TestAuthorizationTimeout(t *testing.T) { 1260 serverOptions := DefaultOptions() 1261 serverOptions.Authorization = "my_token" 1262 serverOptions.AuthTimeout = 0.4 1263 s := RunServer(serverOptions) 1264 defer s.Shutdown() 1265 1266 conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", serverOptions.Host, serverOptions.Port)) 1267 if err != nil { 1268 t.Fatalf("Error dialing server: %v\n", err) 1269 } 1270 defer conn.Close() 1271 client := bufio.NewReaderSize(conn, maxBufSize) 1272 if _, err := client.ReadString('\n'); err != nil { 1273 t.Fatalf("Error receiving info from server: %v\n", err) 1274 } 1275 time.Sleep(3 * secondsToDuration(serverOptions.AuthTimeout)) 1276 l, err := client.ReadString('\n') 1277 if err != nil { 1278 t.Fatalf("Error receiving info from server: %v\n", err) 1279 } 1280 if !strings.Contains(l, "Authentication Timeout") { 1281 t.Fatalf("Authentication Timeout response incorrect: %q\n", l) 1282 } 1283 } 1284 1285 // This is from bug report #18 1286 func TestTwoTokenPubMatchSingleTokenSub(t *testing.T) { 1287 _, c, cr := setupClient() 1288 defer c.close() 1289 test := "PUB foo.bar 5\r\nhello\r\nSUB foo 1\r\nPING\r\nPUB foo.bar 5\r\nhello\r\nPING\r\n" 1290 c.parseAsync(test) 1291 l, err := cr.ReadString('\n') 1292 if err != nil { 1293 t.Fatalf("Error receiving info from server: %v\n", err) 1294 } 1295 if !strings.HasPrefix(l, "PONG\r\n") { 1296 t.Fatalf("PONG response incorrect: %q\n", l) 1297 } 1298 // Expect just a pong, no match should exist here.. 1299 l, _ = cr.ReadString('\n') 1300 if !strings.HasPrefix(l, "PONG\r\n") { 1301 t.Fatalf("PONG response was expected, got: %q\n", l) 1302 } 1303 } 1304 1305 func TestUnsubRace(t *testing.T) { 1306 opts := DefaultOptions() 1307 s := RunServer(opts) 1308 defer s.Shutdown() 1309 1310 url := fmt.Sprintf("nats://%s:%d", 1311 s.getOpts().Host, 1312 s.Addr().(*net.TCPAddr).Port, 1313 ) 1314 nc, err := nats.Connect(url) 1315 if err != nil { 1316 t.Fatalf("Error creating client to %s: %v\n", url, err) 1317 } 1318 defer nc.Close() 1319 1320 ncp, err := nats.Connect(url) 1321 if err != nil { 1322 t.Fatalf("Error creating client: %v\n", err) 1323 } 1324 defer ncp.Close() 1325 1326 sub, _ := nc.Subscribe("foo", func(m *nats.Msg) { 1327 // Just eat it.. 1328 }) 1329 nc.Flush() 1330 1331 var wg sync.WaitGroup 1332 1333 wg.Add(1) 1334 1335 go func() { 1336 for i := 0; i < 10000; i++ { 1337 ncp.Publish("foo", []byte("hello")) 1338 } 1339 wg.Done() 1340 }() 1341 1342 time.Sleep(5 * time.Millisecond) 1343 1344 sub.Unsubscribe() 1345 1346 wg.Wait() 1347 } 1348 1349 func TestClientCloseTLSConnection(t *testing.T) { 1350 opts, err := ProcessConfigFile("./configs/tls.conf") 1351 if err != nil { 1352 t.Fatalf("Error processing config file: %v", err) 1353 } 1354 opts.TLSTimeout = 100 1355 opts.NoLog = true 1356 opts.NoSigs = true 1357 s := RunServer(opts) 1358 defer s.Shutdown() 1359 1360 endpoint := fmt.Sprintf("%s:%d", opts.Host, opts.Port) 1361 conn, err := net.DialTimeout("tcp", endpoint, 2*time.Second) 1362 if err != nil { 1363 t.Fatalf("Unexpected error on dial: %v", err) 1364 } 1365 defer conn.Close() 1366 br := bufio.NewReaderSize(conn, 100) 1367 if _, err := br.ReadString('\n'); err != nil { 1368 t.Fatalf("Unexpected error reading INFO: %v", err) 1369 } 1370 1371 tlsConn := tls.Client(conn, &tls.Config{InsecureSkipVerify: true}) 1372 defer tlsConn.Close() 1373 if err := tlsConn.Handshake(); err != nil { 1374 t.Fatalf("Unexpected error during handshake: %v", err) 1375 } 1376 br = bufio.NewReaderSize(tlsConn, 100) 1377 connectOp := []byte("CONNECT {\"user\":\"derek\",\"pass\":\"foo\",\"verbose\":false,\"pedantic\":false,\"tls_required\":true}\r\n") 1378 if _, err := tlsConn.Write(connectOp); err != nil { 1379 t.Fatalf("Unexpected error writing CONNECT: %v", err) 1380 } 1381 if _, err := tlsConn.Write([]byte("PING\r\n")); err != nil { 1382 t.Fatalf("Unexpected error writing PING: %v", err) 1383 } 1384 if _, err := br.ReadString('\n'); err != nil { 1385 t.Fatalf("Unexpected error reading PONG: %v", err) 1386 } 1387 1388 // Check that client is registered. 1389 checkClientsCount(t, s, 1) 1390 var cli *client 1391 s.mu.Lock() 1392 for _, c := range s.clients { 1393 cli = c 1394 break 1395 } 1396 s.mu.Unlock() 1397 if cli == nil { 1398 t.Fatal("Did not register client on time") 1399 } 1400 // Test GetTLSConnectionState 1401 state := cli.GetTLSConnectionState() 1402 if state == nil { 1403 t.Error("GetTLSConnectionState() returned nil") 1404 } 1405 1406 // Test RemoteAddress 1407 addr := cli.RemoteAddress() 1408 if addr == nil { 1409 t.Error("RemoteAddress() returned nil") 1410 } 1411 1412 if addr.(*net.TCPAddr).IP.String() != "127.0.0.1" { 1413 t.Error("RemoteAddress() returned incorrect ip " + addr.String()) 1414 } 1415 1416 // Fill the buffer. We want to timeout on write so that nc.Close() 1417 // would block due to a write that cannot complete. 1418 buf := make([]byte, 64*1024) 1419 done := false 1420 for !done { 1421 cli.nc.SetWriteDeadline(time.Now().Add(time.Second)) 1422 if _, err := cli.nc.Write(buf); err != nil { 1423 done = true 1424 } 1425 cli.nc.SetWriteDeadline(time.Time{}) 1426 } 1427 ch := make(chan bool) 1428 go func() { 1429 select { 1430 case <-ch: 1431 return 1432 case <-time.After(3 * time.Second): 1433 fmt.Println("!!!! closeConnection is blocked, test will hang !!!") 1434 return 1435 } 1436 }() 1437 // Close the client 1438 cli.closeConnection(ClientClosed) 1439 ch <- true 1440 } 1441 1442 // This tests issue #558 1443 func TestWildcardCharsInLiteralSubjectWorks(t *testing.T) { 1444 opts := DefaultOptions() 1445 s := RunServer(opts) 1446 defer s.Shutdown() 1447 1448 nc, err := nats.Connect(fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)) 1449 if err != nil { 1450 t.Fatalf("Error on connect: %v", err) 1451 } 1452 defer nc.Close() 1453 1454 ch := make(chan bool, 1) 1455 // This subject is a literal even though it contains `*` and `>`, 1456 // they are not treated as wildcards. 1457 subj := "foo.bar,*,>,baz" 1458 cb := func(_ *nats.Msg) { 1459 ch <- true 1460 } 1461 for i := 0; i < 2; i++ { 1462 sub, err := nc.Subscribe(subj, cb) 1463 if err != nil { 1464 t.Fatalf("Error on subscribe: %v", err) 1465 } 1466 if err := nc.Flush(); err != nil { 1467 t.Fatalf("Error on flush: %v", err) 1468 } 1469 if err := nc.LastError(); err != nil { 1470 t.Fatalf("Server reported error: %v", err) 1471 } 1472 if err := nc.Publish(subj, []byte("msg")); err != nil { 1473 t.Fatalf("Error on publish: %v", err) 1474 } 1475 select { 1476 case <-ch: 1477 case <-time.After(time.Second): 1478 t.Fatalf("Should have received the message") 1479 } 1480 if err := sub.Unsubscribe(); err != nil { 1481 t.Fatalf("Error on unsubscribe: %v", err) 1482 } 1483 } 1484 } 1485 1486 // This test ensures that coalescing into the fixed-size output 1487 // queues works as expected. When bytes are queued up, they should 1488 // not overflow a buffer until the capacity is exceeded, at which 1489 // point a new buffer should be added. 1490 func TestClientOutboundQueueCoalesce(t *testing.T) { 1491 opts := DefaultOptions() 1492 s := RunServer(opts) 1493 defer s.Shutdown() 1494 1495 nc, err := nats.Connect(fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)) 1496 if err != nil { 1497 t.Fatalf("Error on connect: %v", err) 1498 } 1499 defer nc.Close() 1500 1501 clients := s.GlobalAccount().getClients() 1502 if len(clients) != 1 { 1503 t.Fatal("Expecting a client to exist") 1504 } 1505 client := clients[0] 1506 client.mu.Lock() 1507 defer client.mu.Unlock() 1508 1509 // First up, queue something small into the queue. 1510 client.queueOutbound([]byte{1, 2, 3, 4, 5}) 1511 1512 if len(client.out.nb) != 1 { 1513 t.Fatal("Expecting a single queued buffer") 1514 } 1515 if l := len(client.out.nb[0]); l != 5 { 1516 t.Fatalf("Expecting only 5 bytes in the first queued buffer, found %d instead", l) 1517 } 1518 1519 // Then queue up a few more bytes, but not enough 1520 // to overflow into the next buffer. 1521 client.queueOutbound([]byte{6, 7, 8, 9, 10}) 1522 1523 if len(client.out.nb) != 1 { 1524 t.Fatal("Expecting a single queued buffer") 1525 } 1526 if l := len(client.out.nb[0]); l != 10 { 1527 t.Fatalf("Expecting 10 bytes in the first queued buffer, found %d instead", l) 1528 } 1529 1530 // Finally, queue up something that is guaranteed 1531 // to overflow. 1532 b := nbPoolSmall.Get().(*[nbPoolSizeSmall]byte)[:] 1533 b = b[:cap(b)] 1534 client.queueOutbound(b) 1535 if len(client.out.nb) != 2 { 1536 t.Fatal("Expecting buffer to have overflowed") 1537 } 1538 if l := len(client.out.nb[0]); l != cap(b) { 1539 t.Fatalf("Expecting %d bytes in the first queued buffer, found %d instead", cap(b), l) 1540 } 1541 if l := len(client.out.nb[1]); l != 10 { 1542 t.Fatalf("Expecting 10 bytes in the second queued buffer, found %d instead", l) 1543 } 1544 } 1545 1546 func TestClientTraceRace(t *testing.T) { 1547 opts := DefaultOptions() 1548 s := RunServer(opts) 1549 defer s.Shutdown() 1550 1551 // Activate trace logging 1552 s.SetLogger(&DummyLogger{}, false, true) 1553 1554 nc1, err := nats.Connect(fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)) 1555 if err != nil { 1556 t.Fatalf("Error on connect: %v", err) 1557 } 1558 defer nc1.Close() 1559 total := 10000 1560 count := 0 1561 ch := make(chan bool, 1) 1562 if _, err := nc1.Subscribe("foo", func(_ *nats.Msg) { 1563 count++ 1564 if count == total { 1565 ch <- true 1566 } 1567 }); err != nil { 1568 t.Fatalf("Error on subscribe: %v", err) 1569 } 1570 nc2, err := nats.Connect(fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)) 1571 if err != nil { 1572 t.Fatalf("Error on connect: %v", err) 1573 } 1574 defer nc2.Close() 1575 1576 wg := sync.WaitGroup{} 1577 wg.Add(1) 1578 go func() { 1579 defer wg.Done() 1580 for i := 0; i < total; i++ { 1581 nc1.Publish("bar", []byte("hello")) 1582 } 1583 }() 1584 for i := 0; i < total; i++ { 1585 nc2.Publish("foo", []byte("hello")) 1586 } 1587 if err := wait(ch); err != nil { 1588 t.Fatal("Did not get all our messages") 1589 } 1590 wg.Wait() 1591 } 1592 1593 func TestClientUserInfo(t *testing.T) { 1594 pnkey := "UD6AYQSOIN2IN5OGC6VQZCR4H3UFMIOXSW6NNS6N53CLJA4PB56CEJJI" 1595 c := &client{ 1596 cid: 1024, 1597 opts: ClientOpts{ 1598 Nkey: pnkey, 1599 }, 1600 } 1601 got := c.getAuthUser() 1602 expected := `Nkey "UD6AYQSOIN2IN5OGC6VQZCR4H3UFMIOXSW6NNS6N53CLJA4PB56CEJJI"` 1603 if got != expected { 1604 t.Errorf("Expected %q, got %q", expected, got) 1605 } 1606 1607 c = &client{ 1608 cid: 1024, 1609 opts: ClientOpts{ 1610 Username: "foo", 1611 }, 1612 } 1613 got = c.getAuthUser() 1614 expected = `User "foo"` 1615 if got != expected { 1616 t.Errorf("Expected %q, got %q", expected, got) 1617 } 1618 1619 c = &client{ 1620 cid: 1024, 1621 opts: ClientOpts{}, 1622 } 1623 got = c.getAuthUser() 1624 expected = `User "N/A"` 1625 if got != expected { 1626 t.Errorf("Expected %q, got %q", expected, got) 1627 } 1628 } 1629 1630 type captureWarnLogger struct { 1631 DummyLogger 1632 warn chan string 1633 } 1634 1635 func (l *captureWarnLogger) Warnf(format string, v ...any) { 1636 select { 1637 case l.warn <- fmt.Sprintf(format, v...): 1638 default: 1639 } 1640 } 1641 1642 func TestReadloopWarning(t *testing.T) { 1643 readLoopReportThreshold = 100 * time.Millisecond 1644 defer func() { readLoopReportThreshold = readLoopReport }() 1645 1646 opts := DefaultOptions() 1647 s := RunServer(opts) 1648 defer s.Shutdown() 1649 1650 l := &captureWarnLogger{warn: make(chan string, 1)} 1651 s.SetLogger(l, false, false) 1652 1653 url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port) 1654 nc := natsConnect(t, url) 1655 defer nc.Close() 1656 natsSubSync(t, nc, "foo") 1657 natsFlush(t, nc) 1658 cid, _ := nc.GetClientID() 1659 1660 sender := natsConnect(t, url) 1661 defer sender.Close() 1662 1663 wg := sync.WaitGroup{} 1664 wg.Add(1) 1665 c := s.getClient(cid) 1666 c.mu.Lock() 1667 go func() { 1668 defer wg.Done() 1669 time.Sleep(250 * time.Millisecond) 1670 c.mu.Unlock() 1671 }() 1672 1673 natsPub(t, sender, "foo", make([]byte, 100)) 1674 natsFlush(t, sender) 1675 1676 select { 1677 case warn := <-l.warn: 1678 if !strings.Contains(warn, "Readloop") { 1679 t.Fatalf("unexpected warning: %v", warn) 1680 } 1681 case <-time.After(2 * time.Second): 1682 t.Fatalf("No warning printed") 1683 } 1684 wg.Wait() 1685 } 1686 1687 func TestTraceMsg(t *testing.T) { 1688 c := &client{} 1689 // Enable message trace 1690 c.trace = true 1691 1692 cases := []struct { 1693 Desc string 1694 Msg []byte 1695 Wanted string 1696 MaxTracedMsgLen int 1697 }{ 1698 { 1699 Desc: "normal length", 1700 Msg: []byte(fmt.Sprintf("normal%s", CR_LF)), 1701 Wanted: " - <<- MSG_PAYLOAD: [\"normal\"]", 1702 MaxTracedMsgLen: 10, 1703 }, 1704 { 1705 Desc: "over length", 1706 Msg: []byte(fmt.Sprintf("over length%s", CR_LF)), 1707 Wanted: " - <<- MSG_PAYLOAD: [\"over lengt...\"]", 1708 MaxTracedMsgLen: 10, 1709 }, 1710 { 1711 Desc: "unlimited length", 1712 Msg: []byte(fmt.Sprintf("unlimited length%s", CR_LF)), 1713 Wanted: " - <<- MSG_PAYLOAD: [\"unlimited length\"]", 1714 MaxTracedMsgLen: 0, 1715 }, 1716 { 1717 Desc: "negative max traced msg len", 1718 Msg: []byte(fmt.Sprintf("negative max traced msg len%s", CR_LF)), 1719 Wanted: " - <<- MSG_PAYLOAD: [\"negative max traced msg len\"]", 1720 MaxTracedMsgLen: -1, 1721 }, 1722 } 1723 1724 for _, ut := range cases { 1725 c.srv = &Server{ 1726 opts: &Options{MaxTracedMsgLen: ut.MaxTracedMsgLen}, 1727 } 1728 c.srv.SetLogger(&DummyLogger{}, true, true) 1729 1730 c.traceMsg(ut.Msg) 1731 1732 got := c.srv.logging.logger.(*DummyLogger).Msg 1733 if !reflect.DeepEqual(ut.Wanted, got) { 1734 t.Errorf("Desc: %s. Msg %q. Traced msg want: %s, got: %s", ut.Desc, ut.Msg, ut.Wanted, got) 1735 } 1736 } 1737 } 1738 1739 func TestClientMaxPending(t *testing.T) { 1740 opts := DefaultOptions() 1741 opts.MaxPending = math.MaxInt32 + 1 1742 s := RunServer(opts) 1743 defer s.Shutdown() 1744 1745 nc := natsConnect(t, fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)) 1746 defer nc.Close() 1747 1748 sub := natsSubSync(t, nc, "foo") 1749 natsPub(t, nc, "foo", []byte("msg")) 1750 natsNexMsg(t, sub, 100*time.Millisecond) 1751 } 1752 1753 func TestResponsePermissions(t *testing.T) { 1754 for i, test := range []struct { 1755 name string 1756 perms *ResponsePermission 1757 }{ 1758 {"max_msgs", &ResponsePermission{MaxMsgs: 2, Expires: time.Hour}}, 1759 {"no_expire_limit", &ResponsePermission{MaxMsgs: 3, Expires: -1 * time.Millisecond}}, 1760 {"expire", &ResponsePermission{MaxMsgs: 1000, Expires: 100 * time.Millisecond}}, 1761 {"no_msgs_limit", &ResponsePermission{MaxMsgs: -1, Expires: 100 * time.Millisecond}}, 1762 } { 1763 t.Run(test.name, func(t *testing.T) { 1764 opts := DefaultOptions() 1765 u1 := &User{ 1766 Username: "service", 1767 Password: "pwd", 1768 Permissions: &Permissions{Response: test.perms}, 1769 } 1770 u2 := &User{Username: "ivan", Password: "pwd"} 1771 opts.Users = []*User{u1, u2} 1772 s := RunServer(opts) 1773 defer s.Shutdown() 1774 1775 svcNC := natsConnect(t, fmt.Sprintf("nats://service:pwd@%s:%d", opts.Host, opts.Port)) 1776 defer svcNC.Close() 1777 reqSub := natsSubSync(t, svcNC, "request") 1778 natsFlush(t, svcNC) 1779 1780 nc := natsConnect(t, fmt.Sprintf("nats://ivan:pwd@%s:%d", opts.Host, opts.Port)) 1781 defer nc.Close() 1782 1783 replySub := natsSubSync(t, nc, "reply") 1784 1785 natsPubReq(t, nc, "request", "reply", []byte("req1")) 1786 1787 req1 := natsNexMsg(t, reqSub, 100*time.Millisecond) 1788 1789 checkFailed := func(t *testing.T) { 1790 t.Helper() 1791 if reply, err := replySub.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout { 1792 if reply != nil { 1793 t.Fatalf("Expected to receive timeout, got reply=%q", reply.Data) 1794 } else { 1795 t.Fatalf("Unexpected error: %v", err) 1796 } 1797 } 1798 } 1799 1800 switch i { 1801 case 0: 1802 // Should allow only 2 replies... 1803 for i := 0; i < 10; i++ { 1804 natsPub(t, svcNC, req1.Reply, []byte("reply")) 1805 } 1806 natsNexMsg(t, replySub, 100*time.Millisecond) 1807 natsNexMsg(t, replySub, 100*time.Millisecond) 1808 // The next should fail... 1809 checkFailed(t) 1810 case 1: 1811 // Expiration is set to -1ms, which should count as infinite... 1812 natsPub(t, svcNC, req1.Reply, []byte("reply")) 1813 // Sleep a bit before next send 1814 time.Sleep(50 * time.Millisecond) 1815 natsPub(t, svcNC, req1.Reply, []byte("reply")) 1816 // Make sure we receive both 1817 natsNexMsg(t, replySub, 100*time.Millisecond) 1818 natsNexMsg(t, replySub, 100*time.Millisecond) 1819 case 2: 1820 fallthrough 1821 case 3: 1822 // Expire set to 100ms so make sure we wait more between 1823 // next publish 1824 natsPub(t, svcNC, req1.Reply, []byte("reply")) 1825 time.Sleep(200 * time.Millisecond) 1826 natsPub(t, svcNC, req1.Reply, []byte("reply")) 1827 // Should receive one, and fail on the other 1828 natsNexMsg(t, replySub, 100*time.Millisecond) 1829 checkFailed(t) 1830 } 1831 // When testing expiration, sleep before sending next reply 1832 if i >= 2 { 1833 time.Sleep(400 * time.Millisecond) 1834 } 1835 }) 1836 } 1837 } 1838 1839 func TestPingNotSentTooSoon(t *testing.T) { 1840 opts := DefaultOptions() 1841 s := RunServer(opts) 1842 defer s.Shutdown() 1843 1844 doneCh := make(chan bool, 1) 1845 wg := sync.WaitGroup{} 1846 wg.Add(1) 1847 go func() { 1848 defer wg.Done() 1849 for { 1850 s.Connz(nil) 1851 select { 1852 case <-doneCh: 1853 return 1854 case <-time.After(time.Millisecond): 1855 } 1856 } 1857 }() 1858 1859 for i := 0; i < 100; i++ { 1860 nc, err := nats.Connect(s.ClientURL()) 1861 if err != nil { 1862 t.Fatalf("Error on connect: %v", err) 1863 } 1864 nc.Close() 1865 } 1866 close(doneCh) 1867 wg.Wait() 1868 1869 c, br, _ := newClientForServer(s) 1870 defer c.close() 1871 connectOp := []byte("CONNECT {\"user\":\"ivan\",\"pass\":\"bar\"}\r\n") 1872 c.parse(connectOp) 1873 1874 // Since client has not send PING, having server try to send RTT ping 1875 // to client should not do anything 1876 if c.sendRTTPing() { 1877 t.Fatalf("RTT ping should not have been sent") 1878 } 1879 // Speed up detection of time elapsed by moving the c.start to more than 1880 // 2 secs in the past. 1881 c.mu.Lock() 1882 c.start = time.Unix(0, c.start.UnixNano()-int64(maxNoRTTPingBeforeFirstPong+time.Second)) 1883 c.mu.Unlock() 1884 1885 errCh := make(chan error, 1) 1886 go func() { 1887 l, _ := br.ReadString('\n') 1888 if l != "PING\r\n" { 1889 errCh <- fmt.Errorf("expected to get PING, got %s", l) 1890 return 1891 } 1892 errCh <- nil 1893 }() 1894 if !c.sendRTTPing() { 1895 t.Fatalf("RTT ping should have been sent") 1896 } 1897 wg.Wait() 1898 if e := <-errCh; e != nil { 1899 t.Fatal(e.Error()) 1900 } 1901 } 1902 1903 func TestClientCheckUseOfGWReplyPrefix(t *testing.T) { 1904 opts := DefaultOptions() 1905 s := RunServer(opts) 1906 defer s.Shutdown() 1907 1908 ech := make(chan error, 1) 1909 nc, err := nats.Connect(s.ClientURL(), 1910 nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, e error) { 1911 ech <- e 1912 })) 1913 if err != nil { 1914 t.Fatalf("Error on connect: %v", err) 1915 } 1916 defer nc.Close() 1917 1918 // Expect to fail if publish on gateway reply prefix 1919 nc.Publish(gwReplyPrefix+"anything", []byte("should fail")) 1920 1921 // Wait for publish violation error 1922 select { 1923 case e := <-ech: 1924 if e == nil || !strings.Contains(strings.ToLower(e.Error()), "violation for publish") { 1925 t.Fatalf("Expected violation error, got %v", e) 1926 } 1927 case <-time.After(time.Second): 1928 t.Fatalf("Did not receive permissions violation error") 1929 } 1930 1931 // Now publish a message with a reply set to the prefix, 1932 // it should be rejected too. 1933 nc.PublishRequest("foo", gwReplyPrefix+"anything", []byte("should fail")) 1934 1935 // Wait for publish violation error with reply 1936 select { 1937 case e := <-ech: 1938 if e == nil || !strings.Contains(strings.ToLower(e.Error()), "violation for publish with reply") { 1939 t.Fatalf("Expected violation error, got %v", e) 1940 } 1941 case <-time.After(time.Second): 1942 t.Fatalf("Did not receive permissions violation error") 1943 } 1944 } 1945 1946 func TestNoClientLeakOnSlowConsumer(t *testing.T) { 1947 opts := DefaultOptions() 1948 s := RunServer(opts) 1949 defer s.Shutdown() 1950 1951 c, err := net.Dial("tcp", fmt.Sprintf("%s:%d", opts.Host, opts.Port)) 1952 if err != nil { 1953 t.Fatalf("Error connecting: %v", err) 1954 } 1955 defer c.Close() 1956 1957 cr := bufio.NewReader(c) 1958 1959 // Wait for INFO... 1960 line, _, _ := cr.ReadLine() 1961 var info serverInfo 1962 if err = json.Unmarshal(line[5:], &info); err != nil { 1963 t.Fatalf("Could not parse INFO json: %v\n", err) 1964 } 1965 1966 // Send our connect 1967 if _, err := c.Write([]byte("CONNECT {\"verbose\": false}\r\nSUB foo 1\r\nPING\r\n")); err != nil { 1968 t.Fatalf("Error sending CONNECT and SUB: %v", err) 1969 } 1970 // Wait for PONG 1971 line, _, _ = cr.ReadLine() 1972 if string(line) != "PONG" { 1973 t.Fatalf("Expected 'PONG' but got %q", line) 1974 } 1975 1976 // Get the client from server map 1977 cli := s.GetClient(info.CID) 1978 if cli == nil { 1979 t.Fatalf("No client registered") 1980 } 1981 // Change the write deadline to very low value 1982 cli.mu.Lock() 1983 cli.out.wdl = time.Nanosecond 1984 cli.mu.Unlock() 1985 1986 nc := natsConnect(t, s.ClientURL()) 1987 defer nc.Close() 1988 1989 // Send some messages to cause write deadline error on "cli" 1990 payload := make([]byte, 1000) 1991 for i := 0; i < 100; i++ { 1992 natsPub(t, nc, "foo", payload) 1993 } 1994 natsFlush(t, nc) 1995 nc.Close() 1996 1997 // Now make sure that the number of clients goes to 0. 1998 checkClientsCount(t, s, 0) 1999 } 2000 2001 func TestClientSlowConsumerWithoutConnect(t *testing.T) { 2002 opts := DefaultOptions() 2003 opts.WriteDeadline = 100 * time.Millisecond 2004 s := RunServer(opts) 2005 defer s.Shutdown() 2006 2007 url := fmt.Sprintf("127.0.0.1:%d", opts.Port) 2008 c, err := net.Dial("tcp", url) 2009 if err != nil { 2010 t.Fatalf("Error on dial: %v", err) 2011 } 2012 defer c.Close() 2013 c.Write([]byte("SUB foo 1\r\n")) 2014 2015 payload := make([]byte, 10000) 2016 nc, err := nats.Connect(url) 2017 if err != nil { 2018 t.Fatalf("Error on connect: %v", err) 2019 } 2020 defer nc.Close() 2021 for i := 0; i < 10000; i++ { 2022 nc.Publish("foo", payload) 2023 } 2024 nc.Flush() 2025 checkFor(t, time.Second, 15*time.Millisecond, func() error { 2026 // Expect slow consumer.. 2027 if n := atomic.LoadInt64(&s.slowConsumers); n != 1 { 2028 return fmt.Errorf("Expected 1 slow consumer, got: %v", n) 2029 } 2030 if n := s.scStats.clients.Load(); n != 1 { 2031 return fmt.Errorf("Expected 1 slow consumer, got: %v", n) 2032 } 2033 return nil 2034 }) 2035 varz, err := s.Varz(nil) 2036 if err != nil { 2037 t.Fatal(err) 2038 } 2039 if varz.SlowConsumersStats.Clients != 1 { 2040 t.Error("Expected a slow consumer client in varz") 2041 } 2042 } 2043 2044 func TestClientNoSlowConsumerIfConnectExpected(t *testing.T) { 2045 opts := DefaultOptions() 2046 opts.Username = "ivan" 2047 opts.Password = "pass" 2048 // Make it very slow so that the INFO sent to client fails... 2049 opts.WriteDeadline = time.Nanosecond 2050 s := RunServer(opts) 2051 defer s.Shutdown() 2052 2053 // Expect server to close the connection, but will bump the slow 2054 // consumer count. 2055 nc, err := nats.Connect(fmt.Sprintf("nats://ivan:pass@%s:%d", opts.Host, opts.Port)) 2056 if err == nil { 2057 nc.Close() 2058 t.Fatal("Expected connect error") 2059 } 2060 if n := atomic.LoadInt64(&s.slowConsumers); n != 0 { 2061 t.Fatalf("Expected 0 slow consumer, got: %v", n) 2062 } 2063 } 2064 2065 func TestClientStalledDuration(t *testing.T) { 2066 for _, test := range []struct { 2067 name string 2068 pb int64 2069 mp int64 2070 expectedTTL time.Duration 2071 }{ 2072 {"pb above mp", 110, 100, stallClientMaxDuration}, 2073 {"pb equal mp", 100, 100, stallClientMaxDuration}, 2074 {"pb below mp/2", 49, 100, stallClientMinDuration}, 2075 {"pb equal mp/2", 50, 100, stallClientMinDuration}, 2076 {"pb at 55% of mp", 55, 100, stallClientMinDuration + 1*stallClientMinDuration}, 2077 {"pb at 60% of mp", 60, 100, stallClientMinDuration + 2*stallClientMinDuration}, 2078 {"pb at 70% of mp", 70, 100, stallClientMinDuration + 4*stallClientMinDuration}, 2079 {"pb at 80% of mp", 80, 100, stallClientMinDuration + 6*stallClientMinDuration}, 2080 {"pb at 90% of mp", 90, 100, stallClientMinDuration + 8*stallClientMinDuration}, 2081 {"pb at 99% of mp", 99, 100, stallClientMinDuration + 9*stallClientMinDuration}, 2082 } { 2083 t.Run(test.name, func(t *testing.T) { 2084 if ttl := stallDuration(test.pb, test.mp); ttl != test.expectedTTL { 2085 t.Fatalf("For pb=%v mp=%v, expected TTL to be %v, got %v", test.pb, test.mp, test.expectedTTL, ttl) 2086 } 2087 }) 2088 } 2089 } 2090 2091 func TestClientIPv6Address(t *testing.T) { 2092 opts := DefaultOptions() 2093 opts.Host = "0.0.0.0" 2094 s := RunServer(opts) 2095 defer s.Shutdown() 2096 2097 nc, err := nats.Connect(fmt.Sprintf("nats://[::1]:%v", opts.Port)) 2098 // Travis may not accept IPv6, in that case, skip the test. 2099 if err != nil { 2100 t.Skipf("Skipping test because could not connect: %v", err) 2101 } 2102 defer nc.Close() 2103 2104 cid, _ := nc.GetClientID() 2105 c := s.GetClient(cid) 2106 c.mu.Lock() 2107 ncs := c.String() 2108 c.mu.Unlock() 2109 if !strings.HasPrefix(ncs, "[::1]") { 2110 t.Fatalf("Wrong string representation of an IPv6 address: %q", ncs) 2111 } 2112 } 2113 2114 func TestPBNotIncreasedOnMaxPending(t *testing.T) { 2115 opts := DefaultOptions() 2116 opts.MaxPending = 100 2117 s := &Server{opts: opts} 2118 c := &client{srv: s} 2119 c.initClient() 2120 2121 c.mu.Lock() 2122 c.queueOutbound(make([]byte, 200)) 2123 pb := c.out.pb 2124 c.mu.Unlock() 2125 2126 if pb != 0 { 2127 t.Fatalf("c.out.pb should be 0, got %v", pb) 2128 } 2129 } 2130 2131 type testConnWritePartial struct { 2132 net.Conn 2133 partial bool 2134 buf bytes.Buffer 2135 } 2136 2137 func (c *testConnWritePartial) Write(p []byte) (int, error) { 2138 n := len(p) 2139 if c.partial { 2140 n = 15 2141 } 2142 return c.buf.Write(p[:n]) 2143 } 2144 2145 func (c *testConnWritePartial) RemoteAddr() net.Addr { 2146 return nil 2147 } 2148 2149 func (c *testConnWritePartial) SetWriteDeadline(_ time.Time) error { 2150 return nil 2151 } 2152 2153 func TestFlushOutboundNoSliceReuseIfPartial(t *testing.T) { 2154 opts := DefaultOptions() 2155 opts.MaxPending = 1024 2156 s := &Server{opts: opts} 2157 2158 fakeConn := &testConnWritePartial{partial: true} 2159 c := &client{srv: s, nc: fakeConn} 2160 c.initClient() 2161 2162 bufs := [][]byte{ 2163 []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 2164 []byte("------"), 2165 []byte("0123456789"), 2166 } 2167 expected := bytes.Buffer{} 2168 for _, buf := range bufs { 2169 expected.Write(buf) 2170 c.mu.Lock() 2171 c.queueOutbound(buf) 2172 c.flushOutbound() 2173 fakeConn.partial = false 2174 c.mu.Unlock() 2175 } 2176 // Ensure everything is flushed. 2177 for done := false; !done; { 2178 c.mu.Lock() 2179 if c.out.pb > 0 { 2180 c.flushOutbound() 2181 } else { 2182 done = true 2183 } 2184 c.mu.Unlock() 2185 } 2186 if !bytes.Equal(expected.Bytes(), fakeConn.buf.Bytes()) { 2187 t.Fatalf("Expected\n%q\ngot\n%q", expected.String(), fakeConn.buf.String()) 2188 } 2189 } 2190 2191 type captureNoticeLogger struct { 2192 DummyLogger 2193 notices []string 2194 } 2195 2196 func (l *captureNoticeLogger) Noticef(format string, v ...any) { 2197 l.Lock() 2198 l.notices = append(l.notices, fmt.Sprintf(format, v...)) 2199 l.Unlock() 2200 } 2201 2202 func TestCloseConnectionLogsReason(t *testing.T) { 2203 o1 := DefaultOptions() 2204 s1 := RunServer(o1) 2205 defer s1.Shutdown() 2206 2207 l := &captureNoticeLogger{} 2208 s1.SetLogger(l, true, true) 2209 2210 o2 := DefaultOptions() 2211 o2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", o1.Cluster.Port)) 2212 s2 := RunServer(o2) 2213 defer s2.Shutdown() 2214 2215 checkClusterFormed(t, s1, s2) 2216 s2.Shutdown() 2217 2218 checkFor(t, time.Second, 15*time.Millisecond, func() error { 2219 if s1.NumRoutes() != 0 { 2220 return fmt.Errorf("route still connected") 2221 } 2222 return nil 2223 }) 2224 // Now check that s1 has logged that the connection is closed and that the reason is included. 2225 ok := false 2226 l.Lock() 2227 for _, n := range l.notices { 2228 if strings.Contains(n, "connection closed: "+ClientClosed.String()) { 2229 ok = true 2230 break 2231 } 2232 } 2233 l.Unlock() 2234 if !ok { 2235 t.Fatal("Log does not contain closed reason") 2236 } 2237 } 2238 2239 func TestCloseConnectionVeryEarly(t *testing.T) { 2240 for _, test := range []struct { 2241 name string 2242 useTLS bool 2243 }{ 2244 {"no_tls", false}, 2245 {"tls", true}, 2246 } { 2247 t.Run(test.name, func(t *testing.T) { 2248 o := DefaultOptions() 2249 if test.useTLS { 2250 tc := &TLSConfigOpts{ 2251 CertFile: "../test/configs/certs/server-cert.pem", 2252 KeyFile: "../test/configs/certs/server-key.pem", 2253 CaFile: "../test/configs/certs/ca.pem", 2254 } 2255 tlsConfig, err := GenTLSConfig(tc) 2256 if err != nil { 2257 t.Fatalf("Error generating tls config: %v", err) 2258 } 2259 o.TLSConfig = tlsConfig 2260 } 2261 s := RunServer(o) 2262 defer s.Shutdown() 2263 2264 // The issue was with a connection that would break right when 2265 // server was sending the INFO. Creating a bare TCP connection 2266 // and closing it right away won't help reproduce the problem. 2267 // So testing in 2 steps. 2268 2269 // Get a normal TCP connection to the server. 2270 c, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", o.Port)) 2271 if err != nil { 2272 t.Fatalf("Unable to create tcp connection") 2273 } 2274 // Now close it. 2275 c.Close() 2276 2277 // Wait that num clients falls to 0. 2278 checkClientsCount(t, s, 0) 2279 2280 // Call again with this closed connection. Alternatively, we 2281 // would have to call with a fake connection that implements 2282 // net.Conn but returns an error on Write. 2283 s.createClient(c) 2284 2285 // This connection should not have been added to the server. 2286 checkClientsCount(t, s, 0) 2287 }) 2288 } 2289 } 2290 2291 type connAddrString struct { 2292 net.Addr 2293 } 2294 2295 func (a *connAddrString) String() string { 2296 return "[fe80::abc:def:ghi:123%utun0]:4222" 2297 } 2298 2299 type connString struct { 2300 net.Conn 2301 } 2302 2303 func (c *connString) RemoteAddr() net.Addr { 2304 return &connAddrString{} 2305 } 2306 2307 func TestClientConnectionName(t *testing.T) { 2308 s, err := NewServer(DefaultOptions()) 2309 if err != nil { 2310 t.Fatalf("Error creating server: %v", err) 2311 } 2312 l := &DummyLogger{} 2313 s.SetLogger(l, true, true) 2314 2315 for _, test := range []struct { 2316 name string 2317 kind int 2318 kindStr string 2319 ws bool 2320 mqtt bool 2321 }{ 2322 {"client", CLIENT, "cid:", false, false}, 2323 {"ws client", CLIENT, "wid:", true, false}, 2324 {"mqtt client", CLIENT, "mid:", false, true}, 2325 {"route", ROUTER, "rid:", false, false}, 2326 {"gateway", GATEWAY, "gid:", false, false}, 2327 {"leafnode", LEAF, "lid:", false, false}, 2328 } { 2329 t.Run(test.name, func(t *testing.T) { 2330 c := &client{srv: s, nc: &connString{}, kind: test.kind} 2331 if test.ws { 2332 c.ws = &websocket{} 2333 } 2334 if test.mqtt { 2335 c.mqtt = &mqtt{} 2336 } 2337 c.initClient() 2338 2339 if host := "fe80::abc:def:ghi:123%utun0"; host != c.host { 2340 t.Fatalf("expected host to be %q, got %q", host, c.host) 2341 } 2342 if port := uint16(4222); port != c.port { 2343 t.Fatalf("expected port to be %v, got %v", port, c.port) 2344 } 2345 2346 checkLog := func(suffix string) { 2347 t.Helper() 2348 l.Lock() 2349 msg := l.Msg 2350 l.Unlock() 2351 if strings.Contains(msg, "(MISSING)") { 2352 t.Fatalf("conn name was not escaped properly, got MISSING: %s", msg) 2353 } 2354 if !strings.Contains(l.Msg, test.kindStr) { 2355 t.Fatalf("expected kind to be %q, got: %s", test.kindStr, msg) 2356 } 2357 if !strings.HasSuffix(l.Msg, suffix) { 2358 t.Fatalf("expected statement to end with %q, got %s", suffix, msg) 2359 } 2360 } 2361 2362 c.Debugf("debug: %v", 1) 2363 checkLog(" 1") 2364 c.Tracef("trace: %s", "2") 2365 checkLog(" 2") 2366 c.Warnf("warn: %s %d", "3", 4) 2367 checkLog(" 3 4") 2368 c.Errorf("error: %v %s", 5, "6") 2369 checkLog(" 5 6") 2370 }) 2371 } 2372 } 2373 2374 func TestClientLimits(t *testing.T) { 2375 accKp, err := nkeys.CreateAccount() 2376 if err != nil { 2377 t.Fatalf("Error creating account key: %v", err) 2378 } 2379 uKp, err := nkeys.CreateUser() 2380 if err != nil { 2381 t.Fatalf("Error creating user key: %v", err) 2382 } 2383 uPub, err := uKp.PublicKey() 2384 if err != nil { 2385 t.Fatalf("Error obtaining publicKey: %v", err) 2386 } 2387 s, err := NewServer(DefaultOptions()) 2388 if err != nil { 2389 t.Fatalf("Error creating server: %v", err) 2390 } 2391 for _, test := range []struct { 2392 client int32 2393 acc int32 2394 srv int32 2395 expect int32 2396 }{ 2397 // all identical 2398 {1, 1, 1, 1}, 2399 {-1, -1, 0, -1}, 2400 // only one value unlimited 2401 {1, -1, 0, 1}, 2402 {-1, 1, 0, 1}, 2403 {-1, -1, 1, 1}, 2404 // all combinations of distinct values 2405 {1, 2, 3, 1}, 2406 {1, 3, 2, 1}, 2407 {2, 1, 3, 1}, 2408 {2, 3, 1, 1}, 2409 {3, 1, 2, 1}, 2410 {3, 2, 1, 1}, 2411 } { 2412 t.Run("", func(t *testing.T) { 2413 s.opts.MaxPayload = test.srv 2414 s.opts.MaxSubs = int(test.srv) 2415 c := &client{srv: s, acc: &Account{ 2416 limits: limits{mpay: test.acc, msubs: test.acc}, 2417 }} 2418 uc := jwt.NewUserClaims(uPub) 2419 uc.Limits.Subs = int64(test.client) 2420 uc.Limits.Payload = int64(test.client) 2421 c.opts.JWT, err = uc.Encode(accKp) 2422 if err != nil { 2423 t.Fatalf("Error encoding jwt: %v", err) 2424 } 2425 c.applyAccountLimits() 2426 if c.mpay != test.expect { 2427 t.Fatalf("payload %d not as expected %d", c.mpay, test.expect) 2428 } 2429 if c.msubs != test.expect { 2430 t.Fatalf("subscriber %d not as expected %d", c.msubs, test.expect) 2431 } 2432 }) 2433 } 2434 } 2435 2436 func TestClientClampMaxSubsErrReport(t *testing.T) { 2437 maxSubLimitReportThreshold = int64(100 * time.Millisecond) 2438 defer func() { maxSubLimitReportThreshold = defaultMaxSubLimitReportThreshold }() 2439 2440 o1 := DefaultOptions() 2441 o1.MaxSubs = 1 2442 o1.LeafNode.Host = "127.0.0.1" 2443 o1.LeafNode.Port = -1 2444 s1 := RunServer(o1) 2445 defer s1.Shutdown() 2446 2447 l := &captureErrorLogger{errCh: make(chan string, 10)} 2448 s1.SetLogger(l, false, false) 2449 2450 o2 := DefaultOptions() 2451 o2.Cluster.Name = "xyz" 2452 u, _ := url.Parse(fmt.Sprintf("nats://127.0.0.1:%d", o1.LeafNode.Port)) 2453 o2.LeafNode.Remotes = []*RemoteLeafOpts{{URLs: []*url.URL{u}}} 2454 s2 := RunServer(o2) 2455 defer s2.Shutdown() 2456 2457 checkLeafNodeConnected(t, s1) 2458 checkLeafNodeConnected(t, s2) 2459 2460 nc := natsConnect(t, s2.ClientURL()) 2461 defer nc.Close() 2462 natsSubSync(t, nc, "foo") 2463 natsSubSync(t, nc, "bar") 2464 2465 // Make sure we receive only 1 2466 check := func() { 2467 t.Helper() 2468 for i := 0; i < 2; i++ { 2469 select { 2470 case errStr := <-l.errCh: 2471 if i > 0 { 2472 t.Fatalf("Should not have logged a second time: %s", errStr) 2473 } 2474 if !strings.Contains(errStr, "maximum subscriptions") { 2475 t.Fatalf("Unexpected error: %s", errStr) 2476 } 2477 case <-time.After(300 * time.Millisecond): 2478 if i == 0 { 2479 t.Fatal("Error should have been logged") 2480 } 2481 } 2482 } 2483 } 2484 check() 2485 2486 // The above will have waited long enough to clear the report threshold. 2487 // So create two new subs and check again that we get only 1 report. 2488 natsSubSync(t, nc, "baz") 2489 natsSubSync(t, nc, "bat") 2490 check() 2491 } 2492 2493 func TestClientDenySysGroupSub(t *testing.T) { 2494 s := RunServer(DefaultOptions()) 2495 defer s.Shutdown() 2496 2497 nc, err := nats.Connect(s.ClientURL(), nats.ErrorHandler(func(*nats.Conn, *nats.Subscription, error) {})) 2498 require_NoError(t, err) 2499 defer nc.Close() 2500 2501 _, err = nc.QueueSubscribeSync("foo", sysGroup) 2502 require_NoError(t, err) 2503 nc.Flush() 2504 err = nc.LastError() 2505 require_Error(t, err) 2506 require_Contains(t, err.Error(), "Permissions Violation") 2507 } 2508 2509 func TestClientAuthRequiredNoAuthUser(t *testing.T) { 2510 conf := createConfFile(t, []byte(` 2511 listen: 127.0.0.1:-1 2512 accounts: { 2513 A: { users: [ { user: user, password: pass } ] } 2514 } 2515 no_auth_user: user 2516 `)) 2517 2518 s, _ := RunServerWithConfig(conf) 2519 defer s.Shutdown() 2520 2521 nc, err := nats.Connect(s.ClientURL()) 2522 require_NoError(t, err) 2523 defer nc.Close() 2524 2525 if nc.AuthRequired() { 2526 t.Fatalf("Expected AuthRequired to be false due to 'no_auth_user'") 2527 } 2528 } 2529 2530 func TestClientUserInfoReq(t *testing.T) { 2531 conf := createConfFile(t, []byte(` 2532 listen: 127.0.0.1:-1 2533 PERMS = { 2534 publish = { allow: "$SYS.REQ.>", deny: "$SYS.REQ.ACCOUNT.>" } 2535 subscribe = "_INBOX.>" 2536 allow_responses: true 2537 } 2538 accounts: { 2539 A: { users: [ { user: dlc, password: pass, permissions: $PERMS } ] } 2540 $SYS { users = [ { user: "admin", pass: "s3cr3t!" } ] } 2541 } 2542 no_auth_user: dlc 2543 `)) 2544 defer removeFile(t, conf) 2545 2546 s, _ := RunServerWithConfig(conf) 2547 defer s.Shutdown() 2548 2549 nc, err := nats.Connect(s.ClientURL()) 2550 require_NoError(t, err) 2551 defer nc.Close() 2552 2553 resp, err := nc.Request("$SYS.REQ.USER.INFO", nil, time.Second) 2554 require_NoError(t, err) 2555 2556 response := ServerAPIResponse{Data: &UserInfo{}} 2557 err = json.Unmarshal(resp.Data, &response) 2558 require_NoError(t, err) 2559 2560 userInfo := response.Data.(*UserInfo) 2561 2562 dlc := &UserInfo{ 2563 UserID: "dlc", 2564 Account: "A", 2565 Permissions: &Permissions{ 2566 Publish: &SubjectPermission{ 2567 Allow: []string{"$SYS.REQ.>"}, 2568 Deny: []string{"$SYS.REQ.ACCOUNT.>"}, 2569 }, 2570 Subscribe: &SubjectPermission{ 2571 Allow: []string{"_INBOX.>"}, 2572 }, 2573 Response: &ResponsePermission{ 2574 MaxMsgs: DEFAULT_ALLOW_RESPONSE_MAX_MSGS, 2575 Expires: DEFAULT_ALLOW_RESPONSE_EXPIRATION, 2576 }, 2577 }, 2578 } 2579 if !reflect.DeepEqual(dlc, userInfo) { 2580 t.Fatalf("User info for %q did not match", "dlc") 2581 } 2582 2583 // Make sure system users work ok too. 2584 nc, err = nats.Connect(s.ClientURL(), nats.UserInfo("admin", "s3cr3t!")) 2585 require_NoError(t, err) 2586 defer nc.Close() 2587 2588 resp, err = nc.Request("$SYS.REQ.USER.INFO", nil, time.Second) 2589 require_NoError(t, err) 2590 2591 response = ServerAPIResponse{Data: &UserInfo{}} 2592 err = json.Unmarshal(resp.Data, &response) 2593 require_NoError(t, err) 2594 2595 userInfo = response.Data.(*UserInfo) 2596 2597 admin := &UserInfo{ 2598 UserID: "admin", 2599 Account: "$SYS", 2600 } 2601 if !reflect.DeepEqual(admin, userInfo) { 2602 t.Fatalf("User info for %q did not match", "admin") 2603 } 2604 } 2605 2606 func TestTLSClientHandshakeFirst(t *testing.T) { 2607 tmpl := ` 2608 listen: "127.0.0.1:-1" 2609 tls { 2610 cert_file: "../test/configs/certs/server-cert.pem" 2611 key_file: "../test/configs/certs/server-key.pem" 2612 timeout: 1 2613 first: %s 2614 } 2615 ` 2616 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, "true"))) 2617 s, o := RunServerWithConfig(conf) 2618 defer s.Shutdown() 2619 2620 connect := func(tlsfirst, expectedOk bool) { 2621 opts := []nats.Option{nats.RootCAs("../test/configs/certs/ca.pem")} 2622 if tlsfirst { 2623 opts = append(opts, nats.TLSHandshakeFirst()) 2624 } 2625 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", o.Port), opts...) 2626 if expectedOk { 2627 if err != nil { 2628 t.Fatalf("Unexpected error: %v", err) 2629 } 2630 if tlsfirst { 2631 cz, err := s.Connz(nil) 2632 if err != nil { 2633 t.Fatalf("Error getting connz: %v", err) 2634 } 2635 if !cz.Conns[0].TLSFirst { 2636 t.Fatal("Expected TLSFirst boolean to be set, it was not") 2637 } 2638 } 2639 } else if !expectedOk && err == nil { 2640 nc.Close() 2641 t.Fatal("Expected error, got none") 2642 } 2643 } 2644 2645 // Server is TLS first, but client is not, so should fail. 2646 connect(false, false) 2647 2648 // Now client is TLS first too, so should work. 2649 connect(true, true) 2650 2651 // Config reload the server and disable tls first 2652 reloadUpdateConfig(t, s, conf, fmt.Sprintf(tmpl, "false")) 2653 2654 // Now if client wants TLS first, connection should fail. 2655 connect(true, false) 2656 2657 // But if it does not, should be ok. 2658 connect(false, true) 2659 2660 // Config reload the server again and enable tls first 2661 reloadUpdateConfig(t, s, conf, fmt.Sprintf(tmpl, "true")) 2662 2663 // If both client and server are TLS first, this should work. 2664 connect(true, true) 2665 } 2666 2667 func TestTLSClientHandshakeFirstFallbackDelayConfigValues(t *testing.T) { 2668 tmpl := ` 2669 listen: "127.0.0.1:-1" 2670 tls { 2671 cert_file: "../test/configs/certs/server-cert.pem" 2672 key_file: "../test/configs/certs/server-key.pem" 2673 timeout: 1 2674 first: %s 2675 } 2676 ` 2677 for _, test := range []struct { 2678 name string 2679 val string 2680 first bool 2681 delay time.Duration 2682 }{ 2683 {"first as boolean true", "true", true, 0}, 2684 {"first as boolean false", "false", false, 0}, 2685 {"first as string true", "\"true\"", true, 0}, 2686 {"first as string false", "\"false\"", false, 0}, 2687 {"first as string on", "on", true, 0}, 2688 {"first as string off", "off", false, 0}, 2689 {"first as string auto", "auto", true, DEFAULT_TLS_HANDSHAKE_FIRST_FALLBACK_DELAY}, 2690 {"first as string auto_fallback", "auto_fallback", true, DEFAULT_TLS_HANDSHAKE_FIRST_FALLBACK_DELAY}, 2691 {"first as fallback duration", "300ms", true, 300 * time.Millisecond}, 2692 } { 2693 t.Run(test.name, func(t *testing.T) { 2694 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, test.val))) 2695 s, o := RunServerWithConfig(conf) 2696 defer s.Shutdown() 2697 2698 if test.first { 2699 if !o.TLSHandshakeFirst { 2700 t.Fatal("Expected tls first to be true, was not") 2701 } 2702 if test.delay != o.TLSHandshakeFirstFallback { 2703 t.Fatalf("Expected fallback delay to be %v, got %v", test.delay, o.TLSHandshakeFirstFallback) 2704 } 2705 } else { 2706 if o.TLSHandshakeFirst { 2707 t.Fatal("Expected tls first to be false, was not") 2708 } 2709 if o.TLSHandshakeFirstFallback != 0 { 2710 t.Fatalf("Expected fallback delay to be 0, got %v", o.TLSHandshakeFirstFallback) 2711 } 2712 } 2713 }) 2714 } 2715 } 2716 2717 type pauseAfterDial struct { 2718 delay time.Duration 2719 } 2720 2721 func (d *pauseAfterDial) Dial(network, address string) (net.Conn, error) { 2722 c, err := net.Dial(network, address) 2723 if err != nil { 2724 return nil, err 2725 } 2726 time.Sleep(d.delay) 2727 return c, nil 2728 } 2729 2730 func TestTLSClientHandshakeFirstFallbackDelay(t *testing.T) { 2731 // Using certificates with RSA 4K to make sure that the fallback does 2732 // not prevent a client with TLS first to successfully connect. 2733 tmpl := ` 2734 listen: "127.0.0.1:-1" 2735 tls { 2736 cert_file: "./configs/certs/tls/benchmark-server-cert-rsa-4096.pem" 2737 key_file: "./configs/certs/tls/benchmark-server-key-rsa-4096.pem" 2738 timeout: 1 2739 first: %s 2740 } 2741 ` 2742 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, "auto"))) 2743 s, o := RunServerWithConfig(conf) 2744 defer s.Shutdown() 2745 2746 url := fmt.Sprintf("tls://localhost:%d", o.Port) 2747 d := &pauseAfterDial{delay: DEFAULT_TLS_HANDSHAKE_FIRST_FALLBACK_DELAY + 100*time.Millisecond} 2748 2749 // Connect a client without "TLS first" and it should be accepted. 2750 nc, err := nats.Connect(url, 2751 nats.SetCustomDialer(d), 2752 nats.Secure(&tls.Config{ 2753 ServerName: "reuben.nats.io", 2754 MinVersion: tls.VersionTLS12, 2755 }), 2756 nats.RootCAs("./configs/certs/tls/benchmark-ca-cert.pem")) 2757 require_NoError(t, err) 2758 defer nc.Close() 2759 // Check that the TLS first in monitoring is set to false 2760 cs, err := s.Connz(nil) 2761 require_NoError(t, err) 2762 if cs.Conns[0].TLSFirst { 2763 t.Fatal("Expected monitoring ConnInfo.TLSFirst to be false, it was not") 2764 } 2765 nc.Close() 2766 2767 // Wait for the client to be removed 2768 checkClientsCount(t, s, 0) 2769 2770 // Increase the fallback delay with config reload. 2771 reloadUpdateConfig(t, s, conf, fmt.Sprintf(tmpl, "\"1s\"")) 2772 2773 // This time, start the client with "TLS first". 2774 // We will also make sure that we did not wait for the fallback delay 2775 // in order to connect. 2776 start := time.Now() 2777 nc, err = nats.Connect(url, 2778 nats.SetCustomDialer(d), 2779 nats.Secure(&tls.Config{ 2780 ServerName: "reuben.nats.io", 2781 MinVersion: tls.VersionTLS12, 2782 }), 2783 nats.RootCAs("./configs/certs/tls/benchmark-ca-cert.pem"), 2784 nats.TLSHandshakeFirst()) 2785 require_NoError(t, err) 2786 require_True(t, time.Since(start) < 500*time.Millisecond) 2787 defer nc.Close() 2788 2789 // Check that the TLS first in monitoring is set to true. 2790 cs, err = s.Connz(nil) 2791 require_NoError(t, err) 2792 if !cs.Conns[0].TLSFirst { 2793 t.Fatal("Expected monitoring ConnInfo.TLSFirst to be true, it was not") 2794 } 2795 nc.Close() 2796 } 2797 2798 func TestTLSClientHandshakeFirstFallbackDelayAndAllowNonTLS(t *testing.T) { 2799 tmpl := ` 2800 listen: "127.0.0.1:-1" 2801 tls { 2802 cert_file: "../test/configs/certs/server-cert.pem" 2803 key_file: "../test/configs/certs/server-key.pem" 2804 timeout: 1 2805 first: %s 2806 } 2807 allow_non_tls: true 2808 ` 2809 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, "true"))) 2810 s, o := RunServerWithConfig(conf) 2811 defer s.Shutdown() 2812 2813 // We first start with a server that has handshake first set to true 2814 // and allow_non_tls. In that case, only "TLS first" clients should be 2815 // accepted. 2816 url := fmt.Sprintf("tls://localhost:%d", o.Port) 2817 nc, err := nats.Connect(url, 2818 nats.RootCAs("../test/configs/certs/ca.pem"), 2819 nats.TLSHandshakeFirst()) 2820 require_NoError(t, err) 2821 defer nc.Close() 2822 // Check that the TLS first in monitoring is set to true 2823 cs, err := s.Connz(nil) 2824 require_NoError(t, err) 2825 if !cs.Conns[0].TLSFirst { 2826 t.Fatal("Expected monitoring ConnInfo.TLSFirst to be true, it was not") 2827 } 2828 nc.Close() 2829 2830 // Client not using "TLS First" should fail. 2831 nc, err = nats.Connect(url, nats.RootCAs("../test/configs/certs/ca.pem")) 2832 if err == nil { 2833 nc.Close() 2834 t.Fatal("Expected connection to fail, it did not") 2835 } 2836 2837 // And non TLS clients should also fail to connect. 2838 nc, err = nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", o.Port)) 2839 if err == nil { 2840 nc.Close() 2841 t.Fatal("Expected connection to fail, it did not") 2842 } 2843 2844 // Now we will replace TLS first in server with a fallback delay. 2845 reloadUpdateConfig(t, s, conf, fmt.Sprintf(tmpl, "\"25ms\"")) 2846 2847 // Clients with "TLS first" should still be able to connect 2848 nc, err = nats.Connect(url, 2849 nats.RootCAs("../test/configs/certs/ca.pem"), 2850 nats.TLSHandshakeFirst()) 2851 require_NoError(t, err) 2852 defer nc.Close() 2853 2854 checkConnInfo := func(isTLS, isTLSFirst bool) { 2855 t.Helper() 2856 cs, err = s.Connz(nil) 2857 require_NoError(t, err) 2858 conn := cs.Conns[0] 2859 if !isTLS { 2860 if conn.TLSVersion != _EMPTY_ { 2861 t.Fatalf("Being a non TLS client, there should not be TLSVersion set, got %v", conn.TLSVersion) 2862 } 2863 if conn.TLSFirst { 2864 t.Fatal("Being a non TLS client, TLSFirst should not be set, but it was") 2865 } 2866 return 2867 } 2868 if isTLSFirst && !conn.TLSFirst { 2869 t.Fatal("Expected monitoring ConnInfo.TLSFirst to be true, it was not") 2870 } else if !isTLSFirst && conn.TLSFirst { 2871 t.Fatal("Expected monitoring ConnInfo.TLSFirst to be false, it was not") 2872 } 2873 nc.Close() 2874 2875 checkClientsCount(t, s, 0) 2876 } 2877 checkConnInfo(true, true) 2878 2879 // Clients with TLS but not "TLS first" should also be able to connect. 2880 nc, err = nats.Connect(url, nats.RootCAs("../test/configs/certs/ca.pem")) 2881 require_NoError(t, err) 2882 defer nc.Close() 2883 checkConnInfo(true, false) 2884 2885 // And non TLS clients should also be able to connect. 2886 nc, err = nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", o.Port)) 2887 require_NoError(t, err) 2888 defer nc.Close() 2889 checkConnInfo(false, false) 2890 } 2891 2892 func TestTLSClientHandshakeFirstAndInProcessConnection(t *testing.T) { 2893 conf := createConfFile(t, []byte(` 2894 listen: "127.0.0.1:-1" 2895 tls { 2896 cert_file: "../test/configs/certs/server-cert.pem" 2897 key_file: "../test/configs/certs/server-key.pem" 2898 timeout: 1 2899 first: true 2900 } 2901 `)) 2902 s, _ := RunServerWithConfig(conf) 2903 defer s.Shutdown() 2904 2905 // Check that we can create an in process connection that does not use TLS 2906 nc, err := nats.Connect(_EMPTY_, nats.InProcessServer(s)) 2907 require_NoError(t, err) 2908 defer nc.Close() 2909 if nc.TLSRequired() { 2910 t.Fatalf("Shouldn't have required TLS for in-process connection") 2911 } 2912 if _, err = nc.TLSConnectionState(); err == nil { 2913 t.Fatal("Should have got an error retrieving TLS connection state") 2914 } 2915 nc.Close() 2916 2917 // If the client wants TLS, it should get a TLS connection. 2918 nc, err = nats.Connect(_EMPTY_, 2919 nats.InProcessServer(s), 2920 nats.RootCAs("../test/configs/certs/ca.pem")) 2921 require_NoError(t, err) 2922 defer nc.Close() 2923 if _, err = nc.TLSConnectionState(); err != nil { 2924 t.Fatal("Should have not got an error retrieving TLS connection state") 2925 } 2926 // However, the server would not have sent that TLS was required, 2927 // but instead it is available. 2928 if nc.TLSRequired() { 2929 t.Fatalf("Shouldn't have required TLS for in-process connection") 2930 } 2931 nc.Close() 2932 2933 // The in-process connection with TLS and "TLS first" should also be working. 2934 nc, err = nats.Connect(_EMPTY_, 2935 nats.InProcessServer(s), 2936 nats.RootCAs("../test/configs/certs/ca.pem"), 2937 nats.TLSHandshakeFirst()) 2938 require_NoError(t, err) 2939 defer nc.Close() 2940 if !nc.TLSRequired() { 2941 t.Fatalf("The server should have sent that TLS is required") 2942 } 2943 if _, err = nc.TLSConnectionState(); err != nil { 2944 t.Fatal("Should have not got an error retrieving TLS connection state") 2945 } 2946 } 2947 2948 func TestRemoveHeaderIfPrefixPresent(t *testing.T) { 2949 hdr := []byte("NATS/1.0\r\n\r\n") 2950 2951 hdr = genHeader(hdr, "a", "1") 2952 hdr = genHeader(hdr, JSExpectedStream, "my-stream") 2953 hdr = genHeader(hdr, JSExpectedLastSeq, "22") 2954 hdr = genHeader(hdr, "b", "2") 2955 hdr = genHeader(hdr, JSExpectedLastSubjSeq, "24") 2956 hdr = genHeader(hdr, JSExpectedLastMsgId, "1") 2957 hdr = genHeader(hdr, "c", "3") 2958 2959 hdr = removeHeaderIfPrefixPresent(hdr, "Nats-Expected-") 2960 2961 if !bytes.Equal(hdr, []byte("NATS/1.0\r\na: 1\r\nb: 2\r\nc: 3\r\n\r\n")) { 2962 t.Fatalf("Expected headers to be stripped, got %q", hdr) 2963 } 2964 }