get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/test/maxpayload_test.go (about)

     1  // Copyright 2015-2019 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 test
    15  
    16  import (
    17  	"fmt"
    18  	"net"
    19  	"runtime"
    20  	"strings"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/nats-io/jwt/v2"
    25  	"github.com/nats-io/nats.go"
    26  	"github.com/nats-io/nkeys"
    27  )
    28  
    29  func TestMaxPayload(t *testing.T) {
    30  	srv, opts := RunServerWithConfig("./configs/override.conf")
    31  	defer srv.Shutdown()
    32  
    33  	endpoint := fmt.Sprintf("%s:%d", opts.Host, opts.Port)
    34  	nc, err := nats.Connect(fmt.Sprintf("nats://%s/", endpoint))
    35  	if err != nil {
    36  		t.Fatalf("Could not connect to server: %v", err)
    37  	}
    38  	defer nc.Close()
    39  
    40  	size := 4 * 1024 * 1024
    41  	big := sizedBytes(size)
    42  	err = nc.Publish("foo", big)
    43  
    44  	if err != nats.ErrMaxPayload {
    45  		t.Fatalf("Expected a Max Payload error")
    46  	}
    47  
    48  	conn, err := net.DialTimeout("tcp", endpoint, nc.Opts.Timeout)
    49  	if err != nil {
    50  		t.Fatalf("Could not make a raw connection to the server: %v", err)
    51  	}
    52  	defer conn.Close()
    53  	info := make([]byte, 512)
    54  	_, err = conn.Read(info)
    55  	if err != nil {
    56  		t.Fatalf("Expected an info message to be sent by the server: %s", err)
    57  	}
    58  	pub := fmt.Sprintf("PUB bar %d\r\n", size)
    59  	_, err = conn.Write([]byte(pub))
    60  	if err != nil {
    61  		t.Fatalf("Could not publish event to the server: %s", err)
    62  	}
    63  
    64  	errMsg := make([]byte, 35)
    65  	_, err = conn.Read(errMsg)
    66  	if err != nil {
    67  		t.Fatalf("Expected an error message to be sent by the server: %s", err)
    68  	}
    69  
    70  	if !strings.Contains(string(errMsg), "Maximum Payload Violation") {
    71  		t.Errorf("Received wrong error message (%v)\n", string(errMsg))
    72  	}
    73  
    74  	// Client proactively omits sending the message so server
    75  	// does not close the connection.
    76  	if nc.IsClosed() {
    77  		t.Errorf("Expected connection to not be closed.")
    78  	}
    79  
    80  	// On the other hand client which did not proactively omitted
    81  	// publishing the bytes following what is suggested by server
    82  	// in the info message has its connection closed.
    83  	_, err = conn.Write(big)
    84  	if err == nil && runtime.GOOS != "windows" {
    85  		t.Errorf("Expected error due to maximum payload transgression.")
    86  	}
    87  
    88  	// On windows, the previous write will not fail because the connection
    89  	// is not fully closed at this stage.
    90  	if runtime.GOOS == "windows" {
    91  		// Issuing a PING and not expecting the PONG.
    92  		_, err = conn.Write([]byte("PING\r\n"))
    93  		if err == nil {
    94  			conn.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
    95  			_, err = conn.Read(big)
    96  			if err == nil {
    97  				t.Errorf("Expected closed connection due to maximum payload transgression.")
    98  			}
    99  		}
   100  	}
   101  }
   102  
   103  func TestMaxPayloadOverrun(t *testing.T) {
   104  	opts := DefaultTestOptions
   105  	opts.Port = -1
   106  	opts.MaxPayload = 10000
   107  	s := RunServer(&opts)
   108  	defer s.Shutdown()
   109  
   110  	// Overrun a int32
   111  	c := createClientConn(t, "127.0.0.1", opts.Port)
   112  	defer c.Close()
   113  
   114  	send, expect := setupConn(t, c)
   115  	send("PUB foo 199380988\r\n")
   116  	expect(errRe)
   117  
   118  	// Now overrun an int64, parseSize will have returned -1,
   119  	// so we get disconnected.
   120  	c = createClientConn(t, "127.0.0.1", opts.Port)
   121  	defer c.Close()
   122  
   123  	send, _ = setupConn(t, c)
   124  	send("PUB foo 18446744073709551615123\r\n")
   125  	expectDisconnect(t, c)
   126  }
   127  
   128  func TestAsyncInfoWithSmallerMaxPayload(t *testing.T) {
   129  	s, opts := runOperatorServer(t)
   130  	defer s.Shutdown()
   131  
   132  	const testMaxPayload = 522
   133  
   134  	okp, _ := nkeys.FromSeed(oSeed)
   135  	akp, _ := nkeys.CreateAccount()
   136  	apub, _ := akp.PublicKey()
   137  	nac := jwt.NewAccountClaims(apub)
   138  	nac.Limits.Payload = testMaxPayload
   139  	ajwt, err := nac.Encode(okp)
   140  	if err != nil {
   141  		t.Fatalf("Error generating account JWT: %v", err)
   142  	}
   143  	if err := s.AccountResolver().Store(apub, ajwt); err != nil {
   144  		t.Fatalf("Account Resolver returned an error: %v", err)
   145  	}
   146  
   147  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
   148  	nc, err := nats.Connect(url, createUserCreds(t, s, akp))
   149  	if err != nil {
   150  		t.Fatalf("Error on connect: %v", err)
   151  	}
   152  	nc.Flush()
   153  	defer nc.Close()
   154  
   155  	if mp := nc.MaxPayload(); mp != testMaxPayload {
   156  		t.Fatalf("Expected MaxPayload of %d, got %d", testMaxPayload, mp)
   157  	}
   158  }