build(deps): bump github.com/nats-io/nats.go from 1.49.0 to 1.50.0

Bumps [github.com/nats-io/nats.go](https://github.com/nats-io/nats.go) from 1.49.0 to 1.50.0.
- [Release notes](https://github.com/nats-io/nats.go/releases)
- [Commits](https://github.com/nats-io/nats.go/compare/v1.49.0...v1.50.0)

---
updated-dependencies:
- dependency-name: github.com/nats-io/nats.go
  dependency-version: 1.50.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2026-04-08 14:46:05 +00:00
committed by Ralf Haferkamp
parent d029201b83
commit b78d3ed42b
41 changed files with 364 additions and 94 deletions

4
go.mod
View File

@@ -56,7 +56,7 @@ require (
github.com/mna/pigeon v1.3.0
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/nats-io/nats-server/v2 v2.12.6
github.com/nats-io/nats.go v1.49.0
github.com/nats-io/nats.go v1.50.0
github.com/oklog/run v1.2.0
github.com/olekukonko/tablewriter v1.1.4
github.com/onsi/ginkgo v1.16.5
@@ -259,7 +259,7 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/juliangruber/go-intersect v1.1.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.18.4 // indirect
github.com/klauspost/compress v1.18.5 // indirect
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
github.com/klauspost/crc32 v1.3.0 // indirect
github.com/kovidgoyal/go-parallel v1.1.1 // indirect

8
go.sum
View File

@@ -721,8 +721,8 @@ github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU=
github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
@@ -904,8 +904,8 @@ github.com/nats-io/jwt/v2 v2.8.1 h1:V0xpGuD/N8Mi+fQNDynXohVvp7ZztevW5io8CUWlPmU=
github.com/nats-io/jwt/v2 v2.8.1/go.mod h1:nWnOEEiVMiKHQpnAy4eXlizVEtSfzacZ1Q43LIRavZg=
github.com/nats-io/nats-server/v2 v2.12.6 h1:Egbx9Vl7Ch8wTtpXPGqbehkZ+IncKqShUxvrt1+Enc8=
github.com/nats-io/nats-server/v2 v2.12.6/go.mod h1:4HPlrvtmSO3yd7KcElDNMx9kv5EBJBnJJzQPptXlheo=
github.com/nats-io/nats.go v1.49.0 h1:yh/WvY59gXqYpgl33ZI+XoVPKyut/IcEaqtsiuTJpoE=
github.com/nats-io/nats.go v1.49.0/go.mod h1:fDCn3mN5cY8HooHwE2ukiLb4p4G4ImmzvXyJt+tGwdw=
github.com/nats-io/nats.go v1.50.0 h1:5zAeQrTvyrKrWLJ0fu02W3br8ym57qf7csDzgLOpcds=
github.com/nats-io/nats.go v1.50.0/go.mod h1:26HypzazeOkyO3/mqd1zZd53STJN0EjCYF9Uy2ZOBno=
github.com/nats-io/nkeys v0.4.15 h1:JACV5jRVO9V856KOapQ7x+EY8Jo3qw1vJt/9Jpwzkk4=
github.com/nats-io/nkeys v0.4.15/go.mod h1:CpMchTXC9fxA5zrMo4KpySxNjiDVvr8ANOSZdiNfUrs=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=

View File

@@ -31,6 +31,9 @@ builds:
- mips64le
goarm:
- 7
ignore:
- goos: windows
goarch: arm
-
id: "s2d"
binary: s2d
@@ -57,6 +60,9 @@ builds:
- mips64le
goarm:
- 7
ignore:
- goos: windows
goarch: arm
-
id: "s2sx"
binary: s2sx
@@ -84,6 +90,9 @@ builds:
- mips64le
goarm:
- 7
ignore:
- goos: windows
goarch: arm
archives:
-
@@ -91,7 +100,7 @@ archives:
name_template: "s2-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
format_overrides:
- goos: windows
format: zip
formats: ['zip']
files:
- unpack/*
- s2/LICENSE

View File

@@ -26,6 +26,12 @@ This package will support the current Go version and 2 versions back.
Use the links above for more information on each.
# changelog
* Feb 9th, 2026 [1.18.4](https://github.com/klauspost/compress/releases/tag/v1.18.4)
* gzhttp: Add zstandard to server handler wrapper https://github.com/klauspost/compress/pull/1121
* zstd: Add ResetWithOptions to encoder/decoder https://github.com/klauspost/compress/pull/1122
* gzhttp: preserve qvalue when extra parameters follow in Accept-Encoding by @analytically in https://github.com/klauspost/compress/pull/1116
* Jan 16th, 2026 [1.18.3](https://github.com/klauspost/compress/releases/tag/v1.18.3)
* Downstream CVE-2025-61728. See [golang/go#77102](https://github.com/golang/go/issues/77102).
@@ -691,3 +697,4 @@ This code is licensed under the same conditions as the original Go code. See LIC

View File

@@ -407,8 +407,8 @@ func histogramSplit(b []byte, h []uint16) {
for i, t := range x {
v0 := &h[t]
v1 := &h[y[i]]
v3 := &h[w[i]]
v2 := &h[z[i]]
v3 := &h[w[i]]
*v0++
*v1++
*v2++

View File

@@ -1,5 +1,4 @@
//go:build !amd64
// +build !amd64
package flate

View File

@@ -1,5 +1,4 @@
//go:build amd64 && !appengine && !noasm && gc
// +build amd64,!appengine,!noasm,gc
// This file contains the specialisation of Decoder.Decompress4X
// and Decoder.Decompress1X that use an asm implementation of thir main loops.

View File

@@ -1,5 +1,4 @@
//go:build !amd64 || appengine || !gc || noasm
// +build !amd64 appengine !gc noasm
// This file contains a generic implementation of Decoder.Decompress4X.
package huff0

View File

@@ -1,5 +1,4 @@
//go:build amd64 && !appengine && !noasm && gc
// +build amd64,!appengine,!noasm,gc
package cpuinfo

View File

@@ -4,7 +4,6 @@
// license that can be found in the LICENSE file.
//go:build (!amd64 && !arm64) || appengine || !gc || noasm
// +build !amd64,!arm64 appengine !gc noasm
package s2

View File

@@ -1,5 +1,4 @@
//go:build !appengine && !noasm && gc
// +build !appengine,!noasm,gc
package s2

View File

@@ -1,5 +1,4 @@
//go:build !amd64 || appengine || !gc || noasm
// +build !amd64 appengine !gc noasm
package s2

View File

@@ -78,6 +78,7 @@ func (b *blockEnc) initNewEncode() {
b.recentOffsets = [3]uint32{1, 4, 8}
b.litEnc.Reuse = huff0.ReusePolicyNone
b.coders.setPrev(nil, nil, nil)
b.dictLitEnc = nil
}
// reset will reset the block for a new encode, but in the same stream,

View File

@@ -21,7 +21,7 @@ type fastBase struct {
crc *xxhash.Digest
tmp [8]byte
blk *blockEnc
lastDictID uint32
lastDict *dict
lowMem bool
}

View File

@@ -479,10 +479,13 @@ func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) {
if d == nil {
return
}
dictChanged := d != e.lastDict
// Init or copy dict table
if len(e.dictTable) != len(e.table) || d.id != e.lastDictID {
if len(e.dictTable) != len(e.table) || dictChanged {
if len(e.dictTable) != len(e.table) {
e.dictTable = make([]prevEntry, len(e.table))
} else {
clear(e.dictTable)
}
end := int32(len(d.content)) - 8 + e.maxMatchOff
for i := e.maxMatchOff; i < end; i += 4 {
@@ -510,13 +513,14 @@ func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) {
offset: i + 3,
}
}
e.lastDictID = d.id
}
// Init or copy dict table
if len(e.dictLongTable) != len(e.longTable) || d.id != e.lastDictID {
// Init or copy dict long table
if len(e.dictLongTable) != len(e.longTable) || dictChanged {
if len(e.dictLongTable) != len(e.longTable) {
e.dictLongTable = make([]prevEntry, len(e.longTable))
} else {
clear(e.dictLongTable)
}
if len(d.content) >= 8 {
cv := load6432(d.content, 0)
@@ -538,8 +542,8 @@ func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) {
off++
}
}
e.lastDictID = d.id
}
e.lastDict = d
// Reset table to initial state
copy(e.longTable[:], e.dictLongTable)

View File

@@ -1102,10 +1102,13 @@ func (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) {
if d == nil {
return
}
dictChanged := d != e.lastDict
// Init or copy dict table
if len(e.dictTable) != len(e.table) || d.id != e.lastDictID {
if len(e.dictTable) != len(e.table) || dictChanged {
if len(e.dictTable) != len(e.table) {
e.dictTable = make([]tableEntry, len(e.table))
} else {
clear(e.dictTable)
}
end := int32(len(d.content)) - 8 + e.maxMatchOff
for i := e.maxMatchOff; i < end; i += 4 {
@@ -1133,14 +1136,15 @@ func (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) {
offset: i + 3,
}
}
e.lastDictID = d.id
e.allDirty = true
}
// Init or copy dict table
if len(e.dictLongTable) != len(e.longTable) || d.id != e.lastDictID {
// Init or copy dict long table
if len(e.dictLongTable) != len(e.longTable) || dictChanged {
if len(e.dictLongTable) != len(e.longTable) {
e.dictLongTable = make([]prevEntry, len(e.longTable))
} else {
clear(e.dictLongTable)
}
if len(d.content) >= 8 {
cv := load6432(d.content, 0)
@@ -1162,9 +1166,9 @@ func (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) {
off++
}
}
e.lastDictID = d.id
e.allDirty = true
}
e.lastDict = d
// Reset table to initial state
{

View File

@@ -1040,15 +1040,18 @@ func (e *doubleFastEncoder) Reset(d *dict, singleBlock bool) {
// ResetDict will reset and set a dictionary if not nil
func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) {
allDirty := e.allDirty
dictChanged := d != e.lastDict
e.fastEncoderDict.Reset(d, singleBlock)
if d == nil {
return
}
// Init or copy dict table
if len(e.dictLongTable) != len(e.longTable) || d.id != e.lastDictID {
if len(e.dictLongTable) != len(e.longTable) || dictChanged {
if len(e.dictLongTable) != len(e.longTable) {
e.dictLongTable = make([]tableEntry, len(e.longTable))
} else {
clear(e.dictLongTable)
}
if len(d.content) >= 8 {
cv := load6432(d.content, 0)
@@ -1065,7 +1068,6 @@ func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) {
}
}
}
e.lastDictID = d.id
allDirty = true
}
// Reset table to initial state

View File

@@ -805,9 +805,11 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) {
}
// Init or copy dict table
if len(e.dictTable) != len(e.table) || d.id != e.lastDictID {
if len(e.dictTable) != len(e.table) || d != e.lastDict {
if len(e.dictTable) != len(e.table) {
e.dictTable = make([]tableEntry, len(e.table))
} else {
clear(e.dictTable)
}
if true {
end := e.maxMatchOff + int32(len(d.content)) - 8
@@ -827,7 +829,7 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) {
}
}
}
e.lastDictID = d.id
e.lastDict = d
e.allDirty = true
}

View File

@@ -138,11 +138,18 @@ func (e *Encoder) Reset(w io.Writer) {
func (e *Encoder) ResetWithOptions(w io.Writer, opts ...EOption) error {
e.o.resetOpt = true
defer func() { e.o.resetOpt = false }()
hadDict := e.o.dict != nil
for _, o := range opts {
if err := o(&e.o); err != nil {
return err
}
}
hasDict := e.o.dict != nil
if hadDict != hasDict {
// Dict presence changed — encoder type must be recreated.
e.state.encoder = nil
e.init = sync.Once{}
}
e.Reset(w)
return nil
}
@@ -448,6 +455,12 @@ func (e *Encoder) Close() error {
if s.encoder == nil {
return nil
}
if s.w == nil {
if len(s.filling) == 0 && !s.headerWritten && !s.eofWritten && s.nInput == 0 {
return nil
}
return errors.New("zstd: encoder has no writer")
}
err := e.nextBlock(true)
if err != nil {
if errors.Is(s.err, ErrEncoderClosed) {

View File

@@ -42,6 +42,7 @@ func (o *encoderOptions) setDefault() {
level: SpeedDefault,
allLitEntropy: false,
lowMem: false,
fullZero: true,
}
}

View File

@@ -1,5 +1,4 @@
//go:build amd64 && !appengine && !noasm && gc
// +build amd64,!appengine,!noasm,gc
package zstd

View File

@@ -1,5 +1,4 @@
//go:build !amd64 || appengine || !gc || noasm
// +build !amd64 appengine !gc noasm
package zstd

View File

@@ -1,5 +1,4 @@
//go:build (!amd64 && !arm64) || appengine || !gc || purego || noasm
// +build !amd64,!arm64 appengine !gc purego noasm
package xxhash

View File

@@ -1,5 +1,4 @@
//go:build amd64 && !appengine && !noasm && gc
// +build amd64,!appengine,!noasm,gc
// Copyright 2019+ Klaus Post. All rights reserved.
// License information can be found in the LICENSE file.

View File

@@ -1,5 +1,4 @@
//go:build !amd64 || appengine || !gc || noasm
// +build !amd64 appengine !gc noasm
// Copyright 2019+ Klaus Post. All rights reserved.
// License information can be found in the LICENSE file.

View File

@@ -1,5 +1,4 @@
//go:build amd64 && !appengine && !noasm && gc
// +build amd64,!appengine,!noasm,gc
package zstd

View File

@@ -1,5 +1,4 @@
//go:build !amd64 || appengine || !gc || noasm
// +build !amd64 appengine !gc noasm
package zstd

147
vendor/github.com/nats-io/nats.go/CLAUDE.md generated vendored Normal file
View File

@@ -0,0 +1,147 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Official Go client library for the NATS messaging system. Provides core pub/sub, request/reply, JetStream (streams, consumers, KV, object store), and a micro services framework. Module path: `github.com/nats-io/nats.go`.
## Build and Test Commands
This project uses a **dual module** setup: `go.mod` for production (minimal deps) and `go_test.mod` for testing (includes nats-server, protobuf). Always use `-modfile=go_test.mod` when running tests or any command that needs test dependencies.
```bash
# Build
go build ./...
# Run all tests (race detector + internal_testing tag, sequential)
go test -modfile=go_test.mod -race -v -p=1 ./... --failfast -vet=off -tags=internal_testing
# Run NoRace tests (must be run separately, without -race flag)
go test -modfile=go_test.mod -v -run=TestNoRace -p=1 ./... --failfast -vet=off
# Run a specific test
go test -modfile=go_test.mod -race -run TestName ./... -tags=internal_testing
# Run tests for a specific package
go test -modfile=go_test.mod -race ./jetstream/... --failfast
go test -modfile=go_test.mod -race ./micro/... --failfast
# Coverage
./scripts/cov.sh
# Formatting
go fmt ./...
# Vet
go vet -modfile=go_test.mod ./...
# Static analysis (as CI does it)
staticcheck -modfile=go_test.mod ./...
# Linting (golangci-lint runs only on jetstream/)
golangci-lint run --timeout 5m0s ./jetstream/...
# Spell check
find . -type f -name "*.go" | xargs misspell -error -locale US
# Update test dependencies (never change go.mod for test deps)
go mod tidy -modfile=go_test.mod
```
## Important Build Tags
- **`internal_testing`** -- Exposes internal test helpers (e.g., `AddMsgFilter`, `CloseTCPConn`) from `testing_internal.go`. Required for many tests in `./test/`.
- **`skip_no_race_tests`** -- Skips the NoRace tests. Used by coverage scripts.
- **`!race && !skip_no_race_tests`** -- NoRace tests in `test/norace_test.go` only run when the race detector is OFF.
- **`compat`** -- Compatibility tests in `test/compat_test.go`.
## CI Pipeline (ci.yaml)
1. **lint** -- `go fmt`, `go vet`, `staticcheck`, `misspell` (all packages), `golangci-lint` (jetstream only).
2. **test** -- Matrix of Go 1.24 and 1.25. Runs NoRace tests first (`-run=TestNoRace` without `-race`), then full race-enabled tests with `-tags=internal_testing`.
## Project Structure
```
nats.go # Core connection, pub/sub, request/reply (~6500 lines)
parser.go # Client-side protocol parser
ws.go # WebSocket transport support
js.go # Legacy JetStream API (deprecated, see jetstream/)
jsm.go # Legacy JetStream management
kv.go # Legacy KeyValue API
object.go # Legacy Object Store API
enc.go # EncodedConn (deprecated)
netchan.go # Go channel bindings
timer.go # Internal timer utilities
context.go # Context-aware request methods
nats_iter.go # Go 1.23+ iterator support (go:build go1.23)
testing_internal.go # Internal test hooks (go:build internal_testing)
jetstream/ # New JetStream API (preferred over legacy)
jetstream.go # Top-level JetStream interface
stream.go # Stream management
stream_config.go # Stream configuration types
consumer.go # Consumer management
consumer_config.go # Consumer configuration types
pull.go # Pull consumer implementation
push.go # Push consumer (deprecated)
ordered.go # Ordered consumer
publish.go # JetStream publish methods
kv.go # KeyValue store
object.go # Object store
message.go # JetStream message types
errors.go # JetStream error types
test/ # Integration tests (package test, uses nats-server)
micro/ # Micro services framework
service.go # Service interface and implementation
request.go # Request handling
test/ # Integration tests
internal/
parser/ # NATS protocol parser (used by core client)
syncx/ # Concurrent map utility
encoders/
builtin/ # Default encoders (JSON, GOB, string)
protobuf/ # Protocol Buffers encoder
test/ # Integration tests for core package (package test)
helper_test.go # Server setup helpers (RunDefaultServer, RunBasicJetStreamServer, etc.)
norace_test.go # Tests that cannot run with -race (build tag guarded)
js_internal_test.go # Tests requiring internal_testing tag
configs/ # NATS server config files for tests
bench/ # Benchmarking utilities
examples/ # Example command-line tools (nats-pub, nats-sub, etc.)
scripts/cov.sh # Coverage collection script
```
## Test Architecture
- **Root `nats_test.go`** (package `nats`) -- White-box unit tests with access to unexported internals.
- **`test/`** (package `test`) -- Black-box integration tests. Tests start an embedded nats-server using helpers from `test/helper_test.go`. These require `-modfile=go_test.mod` since nats-server is a test-only dependency.
- **`jetstream/test/`** (package `test`) -- Integration tests for the new JetStream API, also use embedded nats-server.
- **`micro/test/`** (package `test`) -- Integration tests for the micro services framework.
- **NoRace tests** -- Prefixed `TestNoRace*`, guarded by `//go:build !race && !skip_no_race_tests`. Must be run separately without `-race`.
- Tests always run with `-p=1` (no parallel packages) because they start embedded servers on shared ports.
## Code Conventions
- **License header** -- Every `.go` file starts with the Apache 2.0 license header (Copyright year range).
- **Error variables** -- Exported errors defined as `var Err... = errors.New("nats: ...")` in `nats.go`. JetStream errors in `jetstream/errors.go` follow the same pattern.
- **Options pattern** -- Connection options use functional options: `nats.Connect(url, nats.Name("myapp"), nats.MaxReconnects(5))`. JetStream and micro use similar patterns.
- **No external dependencies in production** -- Only `klauspost/compress`, `nkeys`, `nuid` in `go.mod`. Test deps (nats-server, protobuf) are isolated in `go_test.mod`. PRs adding dependencies are scrutinized heavily.
- **Commits require sign-off** -- Use `git commit -s` (DCO: `Signed-off-by`).
- **US English spelling** -- Enforced by `misspell -locale US` in CI.
- **Interface-driven design** -- JetStream and micro packages define interfaces (`JetStream`, `Stream`, `Consumer`, `Service`) with concrete unexported implementations.
## Key Types
- `nats.Conn` -- Core connection, handles all NATS protocol operations.
- `nats.Msg` -- Message type for pub/sub and request/reply.
- `nats.Subscription` -- Represents a subscription (sync, async, or channel-based).
- `jetstream.JetStream` -- Entry point for new JetStream API (created via `jetstream.New(nc)`).
- `jetstream.Stream`, `jetstream.Consumer` -- Stream and consumer management.
- `micro.Service` -- Micro service instance (created via `micro.AddService(nc, config)`).

View File

@@ -23,7 +23,7 @@ A [Go](http://golang.org) client for the [NATS messaging system](https://nats.io
go get github.com/nats-io/nats.go@latest
# To get a specific version:
go get github.com/nats-io/nats.go@v1.49.0
go get github.com/nats-io/nats.go@v1.50.0
# Note that the latest major version for NATS Server is v2:
go get github.com/nats-io/nats-server/v2@latest

View File

@@ -1,22 +1,22 @@
module github.com/nats-io/nats.go
go 1.24.0
go 1.25.0
require (
github.com/golang/protobuf v1.4.2
github.com/klauspost/compress v1.18.2
github.com/nats-io/jwt/v2 v2.8.0
github.com/nats-io/nats-server/v2 v2.12.3
github.com/nats-io/nkeys v0.4.12
github.com/golang/protobuf v1.5.4
github.com/klauspost/compress v1.18.5
github.com/nats-io/jwt/v2 v2.8.1
github.com/nats-io/nats-server/v2 v2.12.6
github.com/nats-io/nkeys v0.4.15
github.com/nats-io/nuid v1.0.1
google.golang.org/protobuf v1.23.0
google.golang.org/protobuf v1.33.0
)
require (
github.com/antithesishq/antithesis-sdk-go v0.5.0-default-no-op // indirect
github.com/google/go-tpm v0.9.7 // indirect
github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op // indirect
github.com/google/go-tpm v0.9.8 // indirect
github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/time v0.14.0 // indirect
golang.org/x/crypto v0.49.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/time v0.15.0 // indirect
)

View File

@@ -1,5 +1,5 @@
github.com/antithesishq/antithesis-sdk-go v0.5.0-default-no-op h1:Ucf+QxEKMbPogRO5guBNe5cgd9uZgfoJLOYs8WWhtjM=
github.com/antithesishq/antithesis-sdk-go v0.5.0-default-no-op/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl3v2yvUZjmKncl7U91fup7E=
github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op h1:kpBdlEPbRvff0mDD1gk7o9BhI16b9p5yYAXRlidpqJE=
github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl3v2yvUZjmKncl7U91fup7E=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
@@ -7,32 +7,34 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA=
github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76 h1:KGuD/pM2JpL9FAYvBrnBBeENKZNh6eNtjqytV6TYjnk=
github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=
github.com/nats-io/jwt/v2 v2.8.0 h1:K7uzyz50+yGZDO5o772eRE7atlcSEENpL7P+b74JV1g=
github.com/nats-io/jwt/v2 v2.8.0/go.mod h1:me11pOkwObtcBNR8AiMrUbtVOUGkqYjMQZ6jnSdVUIA=
github.com/nats-io/nats-server/v2 v2.12.3 h1:KRv+1n7lddMVgkJPQer+pt36TcO0ENxjilBmeWdjcHs=
github.com/nats-io/nats-server/v2 v2.12.3/go.mod h1:MQXjG9WjyXKz9koWzUc3jYUMKD8x3CLmTNy91IQQz3Y=
github.com/nats-io/nkeys v0.4.12 h1:nssm7JKOG9/x4J8II47VWCL1Ds29avyiQDRn0ckMvDc=
github.com/nats-io/nkeys v0.4.12/go.mod h1:MT59A1HYcjIcyQDJStTfaOY6vhy9XTUjOFo+SVsvpBg=
github.com/nats-io/jwt/v2 v2.8.1 h1:V0xpGuD/N8Mi+fQNDynXohVvp7ZztevW5io8CUWlPmU=
github.com/nats-io/jwt/v2 v2.8.1/go.mod h1:nWnOEEiVMiKHQpnAy4eXlizVEtSfzacZ1Q43LIRavZg=
github.com/nats-io/nats-server/v2 v2.12.6 h1:Egbx9Vl7Ch8wTtpXPGqbehkZ+IncKqShUxvrt1+Enc8=
github.com/nats-io/nats-server/v2 v2.12.6/go.mod h1:4HPlrvtmSO3yd7KcElDNMx9kv5EBJBnJJzQPptXlheo=
github.com/nats-io/nkeys v0.4.15 h1:JACV5jRVO9V856KOapQ7x+EY8Jo3qw1vJt/9Jpwzkk4=
github.com/nats-io/nkeys v0.4.15/go.mod h1:CpMchTXC9fxA5zrMo4KpySxNjiDVvr8ANOSZdiNfUrs=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -41,3 +43,5 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=

View File

@@ -500,8 +500,8 @@ func validateConsumerName(name string) error {
if name == "" {
return fmt.Errorf("%w: name is required", ErrInvalidConsumerName)
}
if strings.ContainsAny(name, ">*. /\\") {
return fmt.Errorf("%w: '%s'", ErrInvalidConsumerName, name)
if strings.ContainsAny(name, ">*. /\\\t\r\n") {
return fmt.Errorf("%w: %q", ErrInvalidConsumerName, name)
}
return nil
}

View File

@@ -316,6 +316,22 @@ type (
// MaxConsumers is the maximum number of consumers allowed for this
// account.
MaxConsumers int `json:"max_consumers"`
// MaxAckPending is the maximum number of outstanding ACKs any consumer
// may configure.
MaxAckPending int `json:"max_ack_pending"`
// MemoryMaxStreamBytes is is the maximum size any single memory based
// stream may be.
MemoryMaxStreamBytes int64 `json:"memory_max_stream_bytes"`
// StoreMaxStreamBytes is the maximum size any single storage based
// stream may be.
StoreMaxStreamBytes int64 `json:"storage_max_stream_bytes"`
// MaxBytesRequired indicates if max bytes is required to be set for
// streams in this account.
MaxBytesRequired bool `json:"max_bytes_required"`
}
jetStream struct {
@@ -966,8 +982,8 @@ func validateStreamName(stream string) error {
if stream == "" {
return ErrStreamNameRequired
}
if strings.ContainsAny(stream, ">*. /\\") {
return fmt.Errorf("%w: '%s'", ErrInvalidStreamName, stream)
if strings.ContainsAny(stream, ">*. /\\\t\r\n") {
return fmt.Errorf("%w: %q", ErrInvalidStreamName, stream)
}
return nil
}

View File

@@ -19,6 +19,7 @@ import (
"fmt"
"reflect"
"regexp"
"slices"
"strconv"
"strings"
"sync"
@@ -170,15 +171,20 @@ type (
// argument. It can be configured with the same options as Watch.
WatchFiltered(ctx context.Context, keys []string, opts ...WatchOpt) (KeyWatcher, error)
// Keys will return all keys.
// Deprecated: Use ListKeys instead to avoid memory issues.
// Keys will return all keys, filtering out any duplicates.
// For large datasets, this can be memory-heavy as all keys are loaded
// into memory. Use ListKeys for a streaming alternative.
Keys(ctx context.Context, opts ...WatchOpt) ([]string, error)
// ListKeys will return KeyLister, allowing to retrieve all keys from
// the key value store in a streaming fashion (on a channel).
// Note: On buckets with a large number of keys and frequent writes,
// duplicate keys may be reported during listing.
ListKeys(ctx context.Context, opts ...WatchOpt) (KeyLister, error)
// ListKeysFiltered returns a KeyLister for filtered keys in the bucket.
// Note: On buckets with a large number of keys and frequent writes,
// duplicate keys may be reported during listing.
ListKeysFiltered(ctx context.Context, filters ...string) (KeyLister, error)
// History will return all historical values for the key (up to
@@ -1363,7 +1369,7 @@ func (kv *kvs) WatchAll(ctx context.Context, opts ...WatchOpt) (KeyWatcher, erro
return kv.Watch(ctx, AllKeys, opts...)
}
// Keys will return all keys.
// Keys will return all keys, filtering out any duplicates.
func (kv *kvs) Keys(ctx context.Context, opts ...WatchOpt) ([]string, error) {
opts = append(opts, IgnoreDeletes(), MetaOnly())
watcher, err := kv.WatchAll(ctx, opts...)
@@ -1382,7 +1388,8 @@ func (kv *kvs) Keys(ctx context.Context, opts ...WatchOpt) ([]string, error) {
if len(keys) == 0 {
return nil, ErrNoKeysFound
}
return keys, nil
slices.Sort(keys)
return slices.Compact(keys), nil
}
type keyLister struct {
@@ -1391,6 +1398,8 @@ type keyLister struct {
}
// ListKeys will return all keys.
// Note: On buckets with a large number of keys and frequent writes,
// duplicate keys may be reported during listing.
func (kv *kvs) ListKeys(ctx context.Context, opts ...WatchOpt) (KeyLister, error) {
opts = append(opts, IgnoreDeletes(), MetaOnly())
watcher, err := kv.WatchAll(ctx, opts...)
@@ -1418,6 +1427,8 @@ func (kv *kvs) ListKeys(ctx context.Context, opts ...WatchOpt) (KeyLister, error
}
// ListKeysFiltered returns a KeyLister for filtered keys in the bucket.
// Note: On buckets with a large number of keys and frequent writes,
// duplicate keys may be reported during listing.
func (kv *kvs) ListKeysFiltered(ctx context.Context, filters ...string) (KeyLister, error) {
watcher, err := kv.WatchFiltered(ctx, filters, IgnoreDeletes(), MetaOnly())
if err != nil {

View File

@@ -116,22 +116,28 @@ func (c *orderedConsumer) Consume(handler MessageHandler, opts ...PullConsumeOpt
c.subscription = sub
internalHandler := func(serial int) func(msg Msg) {
return func(msg Msg) {
c.Lock()
// handler is a noop if message was delivered for a consumer with different serial
if serial != c.serial {
c.Unlock()
return
}
meta, err := msg.Metadata()
if err != nil {
c.errHandler(serial)(c.currentSub, err)
currentSub := c.currentSub
c.Unlock()
c.errHandler(serial)(currentSub, err)
return
}
dseq := meta.Sequence.Consumer
if dseq != c.cursor.deliverSeq+1 {
c.Unlock()
c.errHandler(serial)(sub, errOrderedSequenceMismatch)
return
}
c.cursor.deliverSeq = dseq
c.cursor.streamSeq = meta.Sequence.Stream
c.Unlock()
handler(msg)
}
}
@@ -371,10 +377,10 @@ func (s *orderedSubscription) Drain() {
if !s.closed.CompareAndSwap(0, 1) {
return
}
s.consumer.Lock()
defer s.consumer.Unlock()
if s.consumer.currentSub != nil {
s.consumer.currentConsumer.Lock()
s.consumer.currentSub.Drain()
s.consumer.currentConsumer.Unlock()
}
close(s.done)
}

View File

@@ -1085,6 +1085,10 @@ func (s *pullSubscription) cleanup() {
if s.subscription == nil || !s.subscription.IsValid() {
return
}
if s.consumer != nil {
nc := s.consumer.js.conn
nc.RemoveStatusListener(s.connStatusChanged)
}
if s.hbMonitor != nil {
s.hbMonitor.Stop()
}

View File

@@ -367,8 +367,10 @@ type Tier struct {
// APIStats reports on API calls to JetStream for this account.
type APIStats struct {
Total uint64 `json:"total"`
Errors uint64 `json:"errors"`
Level int `json:"level"`
Total uint64 `json:"total"`
Errors uint64 `json:"errors"`
Inflight uint64 `json:"inflight,omitempty"`
}
// AccountLimits includes the JetStream limits of the current account.

View File

@@ -19,6 +19,7 @@ import (
"fmt"
"reflect"
"regexp"
"slices"
"strconv"
"strings"
"sync"
@@ -68,10 +69,13 @@ type KeyValue interface {
// WatchFiltered will watch for any updates to keys that match the keys
// argument. It can be configured with the same options as Watch.
WatchFiltered(keys []string, opts ...WatchOpt) (KeyWatcher, error)
// Keys will return all keys.
// Deprecated: Use ListKeys instead to avoid memory issues.
// Keys will return all keys, filtering out any duplicates.
// For large datasets, this can be memory-heavy as all keys are loaded
// into memory. Use ListKeys for a streaming alternative.
Keys(opts ...WatchOpt) ([]string, error)
// ListKeys will return all keys in a channel.
// Note: On buckets with a large number of keys and frequent writes,
// duplicate keys may be reported during listing.
ListKeys(opts ...WatchOpt) (KeyLister, error)
// History will return all historical values for the key.
History(key string, opts ...WatchOpt) ([]KeyValueEntry, error)
@@ -867,7 +871,7 @@ func (kv *kvs) PurgeDeletes(opts ...PurgeOpt) error {
return nil
}
// Keys() will return all keys.
// Keys will return all keys, filtering out any duplicates.
func (kv *kvs) Keys(opts ...WatchOpt) ([]string, error) {
opts = append(opts, IgnoreDeletes(), MetaOnly())
watcher, err := kv.WatchAll(opts...)
@@ -886,7 +890,8 @@ func (kv *kvs) Keys(opts ...WatchOpt) ([]string, error) {
if len(keys) == 0 {
return nil, ErrNoKeysFound
}
return keys, nil
slices.Sort(keys)
return slices.Compact(keys), nil
}
type keyLister struct {
@@ -895,6 +900,8 @@ type keyLister struct {
}
// ListKeys will return all keys.
// Note: On buckets with a large number of keys and frequent writes,
// duplicate keys may be reported during listing.
func (kv *kvs) ListKeys(opts ...WatchOpt) (KeyLister, error) {
opts = append(opts, IgnoreDeletes(), MetaOnly())
watcher, err := kv.WatchAll(opts...)

View File

@@ -1,4 +1,4 @@
// Copyright 2012-2024 The NATS Authors
// Copyright 2012-2026 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@@ -38,6 +38,7 @@ import (
"strings"
"sync"
"sync/atomic"
"syscall"
"time"
"github.com/nats-io/nkeys"
@@ -48,7 +49,7 @@ import (
// Default Constants
const (
Version = "1.49.0"
Version = "1.50.0"
DefaultURL = "nats://127.0.0.1:4222"
DefaultPort = 4222
DefaultMaxReconnect = 60
@@ -150,6 +151,7 @@ var (
ErrMaxConnectionsExceeded = errors.New("nats: server maximum connections exceeded")
ErrMaxAccountConnectionsExceeded = errors.New("nats: maximum account active connections exceeded")
ErrConnectionNotTLS = errors.New("nats: connection is not tls")
ErrTLS = errors.New("nats: tls error")
ErrMaxSubscriptionsExceeded = errors.New("nats: server maximum subscriptions exceeded")
ErrWebSocketHeadersAlreadySet = errors.New("nats: websocket connection headers already set")
ErrServerNotInPool = errors.New("nats: selected server is not in the pool")
@@ -2342,7 +2344,7 @@ func (nc *Conn) makeTLSConn() error {
nc.conn = tls.Client(nc.conn, tlsCopy)
conn := nc.conn.(*tls.Conn)
if err := conn.Handshake(); err != nil {
return err
return fmt.Errorf("%w: %w", ErrTLS, err)
}
nc.bindToNewConn()
return nil
@@ -2585,6 +2587,31 @@ func (nc *Conn) setup() {
copy(pub, _HPUB_P_)
}
// tlsHandshakeEOF wraps an error with context when it occurs right after
// a completed TLS handshake, which typically indicates the remote side
// rejected the client certificate (e.g. an mTLS proxy like nginx).
// Depending on timing, the error may be io.EOF (read from closed conn)
// or a "broken pipe"/"connection reset" (write to closed conn).
func (nc *Conn) tlsHandshakeEOF(err error) error {
tlsConn, ok := nc.conn.(*tls.Conn)
if !ok || !tlsConn.ConnectionState().HandshakeComplete {
return err
}
if errors.Is(err, io.EOF) || isConnClosedError(err) {
return fmt.Errorf("%w: connection closed by remote after TLS handshake: %w", ErrTLS, err)
}
return err
}
// isConnClosedError reports whether the error indicates the remote
// side closed the connection (broken pipe or connection reset).
// NOTE: On Windows, connection resets use WSAECONNRESET which may not
// match syscall.ECONNRESET. In that case, the error will not be
// detected here but will still be returned unwrapped by the caller.
func isConnClosedError(err error) bool {
return errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET)
}
// Process a connected connection and initialize properly.
func (nc *Conn) processConnectInit() error {
// Set our deadline for the whole connect process
@@ -2605,14 +2632,14 @@ func (nc *Conn) processConnectInit() error {
// Process the INFO protocol received from the server
err := nc.processExpectedInfo()
if err != nil {
return err
return nc.tlsHandshakeEOF(err)
}
// Send the CONNECT protocol along with the initial PING protocol.
// Wait for the PONG response (or any error that we get from the server).
err = nc.sendConnect()
if err != nil {
return err
return nc.tlsHandshakeEOF(err)
}
// Reset the number of PING sent out

View File

@@ -85,6 +85,7 @@ type websocketReader struct {
nl bool
dc *wsDecompressor
nc *Conn
closeErr error
}
type wsDecompressor struct {
@@ -202,6 +203,15 @@ func (r *websocketReader) Read(p []byte) (int, error) {
return r.drainPending(p), nil
}
// If we have a deferred close error (from a previous Read that
// had both data frames and a close frame), return it now that
// pending data has been drained.
if r.closeErr != nil {
err := r.closeErr
r.closeErr = nil
return 0, err
}
// Get some data from the underlying reader.
n, err := r.r.Read(p)
if err != nil {
@@ -285,6 +295,13 @@ func (r *websocketReader) Read(p []byte) (int, error) {
if wsIsControlFrame(frameType) {
pos, err = r.handleControlFrame(frameType, buf, pos, rem)
if err != nil {
// If we already have pending data (e.g. a -ERR message
// that arrived before this close frame), defer the error
// so the pending data can be returned to the caller first.
if len(r.pending) > 0 {
r.closeErr = err
break
}
return 0, err
}
rem = 0

8
vendor/modules.txt vendored
View File

@@ -880,8 +880,8 @@ github.com/justinas/alice
# github.com/kevinburke/ssh_config v1.2.0
## explicit
github.com/kevinburke/ssh_config
# github.com/klauspost/compress v1.18.4
## explicit; go 1.23
# github.com/klauspost/compress v1.18.5
## explicit; go 1.24
github.com/klauspost/compress
github.com/klauspost/compress/flate
github.com/klauspost/compress/fse
@@ -1177,8 +1177,8 @@ github.com/nats-io/nats-server/v2/server/stree
github.com/nats-io/nats-server/v2/server/sysmem
github.com/nats-io/nats-server/v2/server/thw
github.com/nats-io/nats-server/v2/server/tpm
# github.com/nats-io/nats.go v1.49.0
## explicit; go 1.24.0
# github.com/nats-io/nats.go v1.50.0
## explicit; go 1.25.0
github.com/nats-io/nats.go
github.com/nats-io/nats.go/encoders/builtin
github.com/nats-io/nats.go/internal/parser