Copy disabled (too large)
Download .txt
Showing preview only (12,419K chars total). Download the full file to get everything.
Repository: nats-io/nats-server
Branch: main
Commit: 5b63063e858f
Files: 482
Total size: 11.8 MB
Directory structure:
gitextract_i1v6glus/
├── .coveralls.yml
├── .github/
│ ├── CODEOWNERS
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── config.yml
│ │ ├── defect.yml
│ │ └── proposal.yml
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── actions/
│ │ └── nightly-release/
│ │ └── action.yaml
│ ├── dependabot.yml
│ └── workflows/
│ ├── claude.yml
│ ├── cov.yaml
│ ├── long-tests.yaml
│ ├── mqtt-test.yaml
│ ├── nightly.yaml
│ ├── release.yaml
│ ├── stale-issues.yaml
│ ├── tests.yaml
│ └── vuln.yaml
├── .gitignore
├── .golangci.yml
├── .goreleaser.yml
├── AMBASSADORS.md
├── CODE-OF-CONDUCT.md
├── CONTRIBUTING.md
├── DEPENDENCIES.md
├── GOVERNANCE.md
├── LICENSE
├── MAINTAINERS.md
├── README.md
├── RELEASES.md
├── TODO.md
├── conf/
│ ├── fuzz.go
│ ├── lex.go
│ ├── lex_test.go
│ ├── parse.go
│ └── parse_test.go
├── doc/
│ └── README.md
├── docker/
│ └── Dockerfile.nightly
├── go.mod
├── go.sum
├── internal/
│ ├── antithesis/
│ │ ├── noop.go
│ │ └── test_assert.go
│ ├── fastrand/
│ │ ├── LICENSE
│ │ ├── fastrand.go
│ │ └── fastrand_test.go
│ ├── ldap/
│ │ ├── dn.go
│ │ └── dn_test.go
│ ├── ocsp/
│ │ └── ocsp.go
│ └── testhelper/
│ └── logging.go
├── locksordering.txt
├── logger/
│ ├── log.go
│ ├── log_test.go
│ ├── syslog.go
│ ├── syslog_test.go
│ ├── syslog_windows.go
│ └── syslog_windows_test.go
├── main.go
├── scripts/
│ ├── cov.sh
│ ├── runTestsOnTravis.sh
│ └── updateCopyrights.sh
├── server/
│ ├── README-MQTT.md
│ ├── README.md
│ ├── accounts.go
│ ├── accounts_test.go
│ ├── ats/
│ │ ├── ats.go
│ │ └── ats_test.go
│ ├── auth.go
│ ├── auth_callout.go
│ ├── auth_callout_test.go
│ ├── auth_test.go
│ ├── avl/
│ │ ├── norace_test.go
│ │ ├── seqset.go
│ │ └── seqset_test.go
│ ├── benchmark_publish_test.go
│ ├── certidp/
│ │ ├── certidp.go
│ │ ├── certidp_test.go
│ │ ├── messages.go
│ │ ├── ocsp_responder.go
│ │ └── ocsp_responder_test.go
│ ├── certstore/
│ │ ├── certstore.go
│ │ ├── certstore_other.go
│ │ ├── certstore_windows.go
│ │ └── errors.go
│ ├── certstore_windows_test.go
│ ├── ciphersuites.go
│ ├── client.go
│ ├── client_proxyproto.go
│ ├── client_proxyproto_test.go
│ ├── client_test.go
│ ├── closed_conns_test.go
│ ├── config_check_test.go
│ ├── configs/
│ │ ├── certs/
│ │ │ ├── cert.new.pem
│ │ │ ├── key.new.pem
│ │ │ ├── key.pem
│ │ │ ├── server.pem
│ │ │ └── tls/
│ │ │ ├── benchmark-ca-cert.pem
│ │ │ ├── benchmark-ca-key.pem
│ │ │ ├── benchmark-server-cert-ed25519.pem
│ │ │ ├── benchmark-server-cert-rsa-1024.pem
│ │ │ ├── benchmark-server-cert-rsa-2048.pem
│ │ │ ├── benchmark-server-cert-rsa-4096.pem
│ │ │ ├── benchmark-server-key-ed25519.pem
│ │ │ ├── benchmark-server-key-rsa-1024.pem
│ │ │ ├── benchmark-server-key-rsa-2048.pem
│ │ │ └── benchmark-server-key-rsa-4096.pem
│ │ └── one.creds
│ ├── const.go
│ ├── consumer.go
│ ├── core_benchmarks_test.go
│ ├── cron.go
│ ├── dirstore.go
│ ├── dirstore_test.go
│ ├── disk_avail.go
│ ├── disk_avail_netbsd.go
│ ├── disk_avail_openbsd.go
│ ├── disk_avail_solaris.go
│ ├── disk_avail_wasm.go
│ ├── disk_avail_windows.go
│ ├── elastic/
│ │ └── elastic.go
│ ├── errors.go
│ ├── errors.json
│ ├── errors_gen.go
│ ├── errors_test.go
│ ├── events.go
│ ├── events_test.go
│ ├── filestore.go
│ ├── filestore_test.go
│ ├── gateway.go
│ ├── gateway_test.go
│ ├── gsl/
│ │ ├── gsl.go
│ │ └── gsl_test.go
│ ├── ipqueue.go
│ ├── ipqueue_test.go
│ ├── jetstream.go
│ ├── jetstream_api.go
│ ├── jetstream_batching.go
│ ├── jetstream_batching_test.go
│ ├── jetstream_benchmark_test.go
│ ├── jetstream_cluster.go
│ ├── jetstream_cluster_1_test.go
│ ├── jetstream_cluster_2_test.go
│ ├── jetstream_cluster_3_test.go
│ ├── jetstream_cluster_4_test.go
│ ├── jetstream_cluster_long_test.go
│ ├── jetstream_consumer_test.go
│ ├── jetstream_errors.go
│ ├── jetstream_errors_generated.go
│ ├── jetstream_errors_test.go
│ ├── jetstream_events.go
│ ├── jetstream_helpers_test.go
│ ├── jetstream_jwt_test.go
│ ├── jetstream_leafnode_test.go
│ ├── jetstream_meta_benchmark_test.go
│ ├── jetstream_sourcing_scaling_test.go
│ ├── jetstream_super_cluster_test.go
│ ├── jetstream_test.go
│ ├── jetstream_tpm_test.go
│ ├── jetstream_versioning.go
│ ├── jetstream_versioning_test.go
│ ├── jwt.go
│ ├── jwt_test.go
│ ├── leafnode.go
│ ├── leafnode_proxy_test.go
│ ├── leafnode_test.go
│ ├── log.go
│ ├── log_test.go
│ ├── memstore.go
│ ├── memstore_test.go
│ ├── monitor.go
│ ├── monitor_sort_opts.go
│ ├── monitor_test.go
│ ├── mqtt.go
│ ├── mqtt_ex_bench_test.go
│ ├── mqtt_ex_test_test.go
│ ├── mqtt_test.go
│ ├── msgtrace.go
│ ├── msgtrace_test.go
│ ├── nkey.go
│ ├── nkey_test.go
│ ├── norace_1_test.go
│ ├── norace_2_test.go
│ ├── ocsp.go
│ ├── ocsp_peer.go
│ ├── ocsp_responsecache.go
│ ├── opts.go
│ ├── opts_test.go
│ ├── parser.go
│ ├── parser_fuzz_test.go
│ ├── parser_test.go
│ ├── ping_test.go
│ ├── proto.go
│ ├── pse/
│ │ ├── freebsd.txt
│ │ ├── pse_darwin.go
│ │ ├── pse_dragonfly.go
│ │ ├── pse_freebsd_cgo.go
│ │ ├── pse_freebsd_sysctl.go
│ │ ├── pse_linux.go
│ │ ├── pse_netbsd.go
│ │ ├── pse_openbsd.go
│ │ ├── pse_rumprun.go
│ │ ├── pse_solaris.go
│ │ ├── pse_test.go
│ │ ├── pse_wasm.go
│ │ ├── pse_windows.go
│ │ ├── pse_windows_test.go
│ │ └── pse_zos.go
│ ├── raft.go
│ ├── raft_chain_of_blocks_helpers_test.go
│ ├── raft_helpers_test.go
│ ├── raft_test.go
│ ├── rate_counter.go
│ ├── rate_counter_test.go
│ ├── reload.go
│ ├── reload_test.go
│ ├── ring.go
│ ├── ring_test.go
│ ├── route.go
│ ├── routes_test.go
│ ├── scheduler.go
│ ├── sdm.go
│ ├── sendq.go
│ ├── server.go
│ ├── server_fuzz_test.go
│ ├── server_test.go
│ ├── service.go
│ ├── service_test.go
│ ├── service_windows.go
│ ├── service_windows_test.go
│ ├── signal.go
│ ├── signal_test.go
│ ├── signal_wasm.go
│ ├── signal_windows.go
│ ├── split_test.go
│ ├── store.go
│ ├── store_test.go
│ ├── stream.go
│ ├── stree/
│ │ ├── dump.go
│ │ ├── helper_test.go
│ │ ├── leaf.go
│ │ ├── node.go
│ │ ├── node10.go
│ │ ├── node16.go
│ │ ├── node256.go
│ │ ├── node4.go
│ │ ├── node48.go
│ │ ├── parts.go
│ │ ├── stree.go
│ │ ├── stree_test.go
│ │ └── util.go
│ ├── subject_fuzz_test.go
│ ├── subject_transform.go
│ ├── subject_transform_test.go
│ ├── sublist.go
│ ├── sublist_test.go
│ ├── sysmem/
│ │ ├── mem_bsd.go
│ │ ├── mem_darwin.go
│ │ ├── mem_linux.go
│ │ ├── mem_solaris.go
│ │ ├── mem_wasm.go
│ │ ├── mem_windows.go
│ │ ├── mem_zos.go
│ │ └── sysctl.go
│ ├── test_test.go
│ ├── thw/
│ │ ├── helper_test.go
│ │ ├── thw.go
│ │ └── thw_test.go
│ ├── tpm/
│ │ ├── js_ek_tpm_other.go
│ │ ├── js_ek_tpm_test.go
│ │ └── js_ek_tpm_windows.go
│ ├── trust_test.go
│ ├── util.go
│ ├── util_test.go
│ ├── websocket.go
│ └── websocket_test.go
├── test/
│ ├── accounts_cycles_test.go
│ ├── auth_test.go
│ ├── bench_results.txt
│ ├── bench_test.go
│ ├── client_auth_test.go
│ ├── client_cluster_test.go
│ ├── cluster_test.go
│ ├── cluster_tls_test.go
│ ├── configs/
│ │ ├── certs/
│ │ │ ├── ca.pem
│ │ │ ├── client-cert.pem
│ │ │ ├── client-id-auth-cert.pem
│ │ │ ├── client-id-auth-key.pem
│ │ │ ├── client-key.pem
│ │ │ ├── ocsp/
│ │ │ │ ├── ca-cert.pem
│ │ │ │ ├── ca-key.pem
│ │ │ │ ├── client-cert.pem
│ │ │ │ ├── client-key.pem
│ │ │ │ ├── desgsign/
│ │ │ │ │ ├── ca-cert.pem
│ │ │ │ │ ├── ca-chain-cert.pem
│ │ │ │ │ ├── ca-interm-cert.pem
│ │ │ │ │ ├── ca-interm-key.pem
│ │ │ │ │ ├── ca-key.pem
│ │ │ │ │ ├── server-01-cert.pem
│ │ │ │ │ ├── server-01-key.pem
│ │ │ │ │ ├── server-02-cert.pem
│ │ │ │ │ └── server-02-key.pem
│ │ │ │ ├── gen.sh
│ │ │ │ ├── server-cert.pem
│ │ │ │ ├── server-key.pem
│ │ │ │ ├── server-status-request-cert.pem
│ │ │ │ ├── server-status-request-key.pem
│ │ │ │ ├── server-status-request-url-01-cert.pem
│ │ │ │ ├── server-status-request-url-01-key.pem
│ │ │ │ ├── server-status-request-url-02-cert.pem
│ │ │ │ ├── server-status-request-url-02-key.pem
│ │ │ │ ├── server-status-request-url-03-cert.pem
│ │ │ │ ├── server-status-request-url-03-key.pem
│ │ │ │ ├── server-status-request-url-04-cert.pem
│ │ │ │ ├── server-status-request-url-04-key.pem
│ │ │ │ ├── server-status-request-url-05-cert.pem
│ │ │ │ ├── server-status-request-url-05-key.pem
│ │ │ │ ├── server-status-request-url-06-cert.pem
│ │ │ │ ├── server-status-request-url-06-key.pem
│ │ │ │ ├── server-status-request-url-07-cert.pem
│ │ │ │ ├── server-status-request-url-07-key.pem
│ │ │ │ ├── server-status-request-url-08-cert.pem
│ │ │ │ └── server-status-request-url-08-key.pem
│ │ │ ├── ocsp_peer/
│ │ │ │ └── mini-ca/
│ │ │ │ ├── caocsp/
│ │ │ │ │ ├── caocsp_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ └── caocsp_keypair.pem
│ │ │ │ ├── client1/
│ │ │ │ │ ├── System_bundle.pem
│ │ │ │ │ ├── System_cert.pem
│ │ │ │ │ ├── UserA1_bundle.pem
│ │ │ │ │ ├── UserA1_cert.pem
│ │ │ │ │ ├── UserA2_bundle.pem
│ │ │ │ │ ├── UserA2_cert.pem
│ │ │ │ │ ├── certfile.pem
│ │ │ │ │ └── private/
│ │ │ │ │ ├── System_keypair.pem
│ │ │ │ │ ├── UserA1_keypair.pem
│ │ │ │ │ └── UserA2_keypair.pem
│ │ │ │ ├── client2/
│ │ │ │ │ ├── UserB1_bundle.pem
│ │ │ │ │ ├── UserB1_cert.pem
│ │ │ │ │ ├── UserB2_bundle.pem
│ │ │ │ │ ├── UserB2_cert.pem
│ │ │ │ │ ├── certfile.pem
│ │ │ │ │ └── private/
│ │ │ │ │ ├── UserB1_keypair.pem
│ │ │ │ │ └── UserB2_keypair.pem
│ │ │ │ ├── intermediate1/
│ │ │ │ │ ├── intermediate1_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ └── intermediate1_keypair.pem
│ │ │ │ ├── intermediate2/
│ │ │ │ │ ├── intermediate2_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ └── intermediate2_keypair.pem
│ │ │ │ ├── misc/
│ │ │ │ │ ├── misconfig_TestServer1_bundle.pem
│ │ │ │ │ ├── trust_config1_bundle.pem
│ │ │ │ │ ├── trust_config2_bundle.pem
│ │ │ │ │ └── trust_config3_bundle.pem
│ │ │ │ ├── ocsp1/
│ │ │ │ │ ├── ocsp1_bundle.pem
│ │ │ │ │ ├── ocsp1_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ └── ocsp1_keypair.pem
│ │ │ │ ├── ocsp2/
│ │ │ │ │ ├── ocsp2_bundle.pem
│ │ │ │ │ ├── ocsp2_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ └── ocsp2_keypair.pem
│ │ │ │ ├── root/
│ │ │ │ │ ├── private/
│ │ │ │ │ │ └── root_keypair.pem
│ │ │ │ │ └── root_cert.pem
│ │ │ │ ├── server1/
│ │ │ │ │ ├── TestServer1_bundle.pem
│ │ │ │ │ ├── TestServer1_cert.pem
│ │ │ │ │ ├── TestServer2_bundle.pem
│ │ │ │ │ ├── TestServer2_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ ├── TestServer1_keypair.pem
│ │ │ │ │ └── TestServer2_keypair.pem
│ │ │ │ └── server2/
│ │ │ │ ├── TestServer3_bundle.pem
│ │ │ │ ├── TestServer3_cert.pem
│ │ │ │ ├── TestServer4_bundle.pem
│ │ │ │ ├── TestServer4_cert.pem
│ │ │ │ └── private/
│ │ │ │ ├── TestServer3_keypair.pem
│ │ │ │ └── TestServer4_keypair.pem
│ │ │ ├── rdns/
│ │ │ │ ├── ca.key
│ │ │ │ ├── ca.pem
│ │ │ │ ├── client-a.key
│ │ │ │ ├── client-a.pem
│ │ │ │ ├── client-b.key
│ │ │ │ ├── client-b.pem
│ │ │ │ ├── client-c.key
│ │ │ │ ├── client-c.pem
│ │ │ │ ├── client-d.key
│ │ │ │ ├── client-d.pem
│ │ │ │ ├── client-e.key
│ │ │ │ ├── client-e.pem
│ │ │ │ ├── client-f.key
│ │ │ │ ├── client-f.pem
│ │ │ │ ├── server.key
│ │ │ │ └── server.pem
│ │ │ ├── regenerate_rdns_svid.sh
│ │ │ ├── regenerate_top.sh
│ │ │ ├── sans/
│ │ │ │ ├── ca.pem
│ │ │ │ ├── client-key.pem
│ │ │ │ ├── client.pem
│ │ │ │ ├── dev-email-key.pem
│ │ │ │ ├── dev-email.pem
│ │ │ │ ├── dev-key.pem
│ │ │ │ ├── dev.pem
│ │ │ │ ├── prod-key.pem
│ │ │ │ ├── prod.pem
│ │ │ │ ├── server-key.pem
│ │ │ │ └── server.pem
│ │ │ ├── server-cert.pem
│ │ │ ├── server-iponly.pem
│ │ │ ├── server-key-iponly.pem
│ │ │ ├── server-key-noip.pem
│ │ │ ├── server-key.pem
│ │ │ ├── server-noip.pem
│ │ │ ├── srva-cert.pem
│ │ │ ├── srva-key.pem
│ │ │ ├── srvb-cert.pem
│ │ │ ├── srvb-key.pem
│ │ │ ├── svid/
│ │ │ │ ├── ca.key
│ │ │ │ ├── ca.pem
│ │ │ │ ├── client-a.key
│ │ │ │ ├── client-a.pem
│ │ │ │ ├── client-b.key
│ │ │ │ ├── client-b.pem
│ │ │ │ ├── server.key
│ │ │ │ ├── server.pem
│ │ │ │ ├── svid-user-a.key
│ │ │ │ ├── svid-user-a.pem
│ │ │ │ ├── svid-user-b.key
│ │ │ │ └── svid-user-b.pem
│ │ │ └── tlsauth/
│ │ │ ├── ca.pem
│ │ │ ├── certstore/
│ │ │ │ ├── ca.p12
│ │ │ │ ├── client.p12
│ │ │ │ ├── delete-cert-from-store.ps1
│ │ │ │ ├── ecdsa_server.key
│ │ │ │ ├── ecdsa_server.pem
│ │ │ │ ├── ecdsa_server.pfx
│ │ │ │ ├── expired.p12
│ │ │ │ ├── generate_ecdsa_test_cert.sh
│ │ │ │ ├── import-p12-ca.ps1
│ │ │ │ ├── import-p12-client.ps1
│ │ │ │ ├── import-p12-server.ps1
│ │ │ │ ├── not-expired.p12
│ │ │ │ ├── pkcs12.md
│ │ │ │ └── server.p12
│ │ │ ├── client-key.pem
│ │ │ ├── client.pem
│ │ │ ├── client2-key.pem
│ │ │ ├── client2.pem
│ │ │ ├── server-key.pem
│ │ │ ├── server-no-ou-key.pem
│ │ │ ├── server-no-ou.pem
│ │ │ └── server.pem
│ │ ├── jetstream/
│ │ │ ├── restore_bad_stream/
│ │ │ │ ├── backup.json
│ │ │ │ └── stream.tar.s2
│ │ │ ├── restore_empty_R1F_stream/
│ │ │ │ ├── backup.json
│ │ │ │ └── stream.tar.s2
│ │ │ └── restore_empty_R3F_stream/
│ │ │ ├── backup.json
│ │ │ └── stream.tar.s2
│ │ └── nkeys/
│ │ ├── op.jwt
│ │ ├── sigkeys.txt
│ │ └── test.seed
│ ├── fanout_test.go
│ ├── gateway_test.go
│ ├── gosrv_test.go
│ ├── leafnode_test.go
│ ├── log_test.go
│ ├── maxpayload_test.go
│ ├── monitor_test.go
│ ├── new_routes_test.go
│ ├── norace_test.go
│ ├── ocsp_peer_test.go
│ ├── ocsp_test.go
│ ├── operator_test.go
│ ├── opts_test.go
│ ├── pedantic_test.go
│ ├── pid_test.go
│ ├── ping_test.go
│ ├── port_test.go
│ ├── ports_test.go
│ ├── proto_test.go
│ ├── route_discovery_test.go
│ ├── routes_test.go
│ ├── service_latency_test.go
│ ├── services_test.go
│ ├── system_services_test.go
│ ├── test.go
│ ├── test_test.go
│ ├── tls_test.go
│ ├── user_authorization_test.go
│ └── verbose_test.go
└── util/
├── nats-server-hardened.service
└── nats-server.service
================================================
FILE CONTENTS
================================================
================================================
FILE: .coveralls.yml
================================================
service_name: travis-pro
================================================
FILE: .github/CODEOWNERS
================================================
* @nats-io/server
*.go @nats-io/server-dev
doc/ @nats-io/server-dev
test/ @nats-io/server-dev
locksordering.txt @nats-io/server-dev
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
# NATS.io
community_bridge: nats-io
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: Discussion
url: https://github.com/nats-io/nats-server/discussions
about: Ideal for ideas, feedback, or longer form questions.
- name: Chat
url: https://slack.nats.io
about: Ideal for short, one-off questions, general conversation, and meeting other NATS users!
================================================
FILE: .github/ISSUE_TEMPLATE/defect.yml
================================================
---
name: Defect
description: Report a defect, such as a bug or regression.
labels:
- defect
body:
- type: textarea
id: observed
attributes:
label: Observed behavior
description: Describe the unexpected behavior or performance regression you are observing.
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
description: Describe the expected behavior or performance characteristics.
validations:
required: true
- type: textarea
id: versions
attributes:
label: Server and client version
description: |-
**One of the first things we are likely to ask you is if the defect reproduces on the latest version, so please check that first!**
For the server, use `nats-server --version`, check the startup log output, or the image tag pulled from Docker.
For the CLI client, use `nats --version`.
For language-specific clients, check the version downloaded by the language dependency manager.
validations:
required: true
- type: textarea
id: environment
attributes:
label: Host environment
description: |-
Specify any relevant details about the host environment the server and/or client was running in,
such as operating system, CPU architecture, container runtime, etc.
validations:
required: false
- type: textarea
id: steps
attributes:
label: Steps to reproduce
description: Provide as many concrete steps to reproduce the defect. Please also include stream info and consumer info if this issue is JetStream-related.
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/proposal.yml
================================================
---
name: Proposal
description: Propose an enhancement or new feature.
labels:
- proposal
body:
- type: textarea
id: change
attributes:
label: Proposed change
description: This could be a behavior change, enhanced API, or a new feature.
validations:
required: true
- type: textarea
id: usecase
attributes:
label: Use case
description: What is the use case or general motivation for this proposal?
validations:
required: true
- type: textarea
id: contribute
attributes:
label: Contribution
description: |-
Are you intending or interested in contributing code for this proposal if accepted?
validations:
required: false
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!-- Please make sure to read CONTRIBUTING.md, then delete this notice and replace it with your PR description. The below sign-off certifies that the contribution is your original work and that you license the work to the project under the Apache-2.0 license. We cannot accept contributions without it. -->
Signed-off-by: Your Name <your.email@example.com>
================================================
FILE: .github/actions/nightly-release/action.yaml
================================================
name: Nightly Docker Releaser
description: Builds nightly docker images
inputs:
hub_username:
description: Docker hub username
required: true
hub_password:
description: Docker hub password
required: true
name:
description: The name of the build
default: nightly
required: false
runs:
using: composite
steps:
- name: Log in to Docker Hub
shell: bash
run: docker login -u "${{ inputs.hub_username }}" -p "${{ inputs.hub_password }}"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Generate build metadata
shell: sh
run: |
echo "BUILD_DATE=$(date +%Y%m%d)" >> $GITHUB_ENV
echo "GIT_COMMIT=$(cd ${{ inputs.workdir }}/nats-server && git rev-parse --short HEAD)" >> $GITHUB_ENV
echo "BUILD_NAME=$(echo ${{ inputs.name }} | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9.-]/-/g')" >> $GITHUB_ENV
- name: Build and push Docker images
uses: docker/build-push-action@v6
with:
context: "${{ github.workspace }}/src/github.com/nats-io"
file: "${{ github.workspace }}/src/github.com/nats-io/nats-server/docker/Dockerfile.nightly"
build-args: |
VERSION=nightly-${{ env.BUILD_DATE }}
GIT_COMMIT=${{ env.GIT_COMMIT }}
platforms: linux/amd64,linux/arm64
push: true
tags: |
synadia/nats-server:${{ env.BUILD_NAME }}
synadia/nats-server:${{ env.BUILD_NAME }}-${{ env.BUILD_DATE }}
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
================================================
FILE: .github/workflows/claude.yml
================================================
name: Claude Code
# GITHUB_TOKEN is neutered — all GitHub API access uses the App token instead.
permissions: {}
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
pull_request_target:
types: [opened, reopened]
jobs:
claude:
name: Claude Review
uses: synadia-io/ai-workflows/.github/workflows/claude.yml@v2
if: contains(
fromJson('["OWNER","MEMBER","COLLABORATOR"]'),
github.event.comment.author_association || github.event.pull_request.author_association
)
with:
gh_app_id: ${{ vars.CLAUDE_GH_APP_ID }}
checkout_mode: "base"
review_focus: |
Additionally focus on:
- Performance implications (hot paths, allocations, lock contention)
- Concurrency safety (goroutine leaks, race conditions, deadlocks)
- Raft consensus and JetStream clustering correctness
- Security boundaries (authentication, authorization, TLS handling)
secrets:
claude_oauth_token: ${{ secrets.CLAUDE_OAUTH_TOKEN }}
gh_app_private_key: ${{ secrets.CLAUDE_GH_APP_PRIVATE_KEY }}
================================================
FILE: .github/workflows/cov.yaml
================================================
name: NATS Server Code Coverage
on:
workflow_dispatch: {}
schedule:
- cron: "40 4 * * *"
permissions:
contents: read
jobs:
nightly_coverage:
runs-on: ubuntu-latest
env:
GOPATH: /home/runner/work/nats-server
GO111MODULE: "on"
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
path: src/github.com/nats-io/nats-server
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
cache-dependency-path: src/github.com/nats-io/nats-server/go.sum
- name: Run code coverage
shell: bash --noprofile --norc -x -eo pipefail {0}
run: |
set -e
cd src/github.com/nats-io/nats-server
./scripts/cov.sh upload
set +e
- name: Convert coverage.out to coverage.lcov
# Use commit hash here to avoid a re-tagging attack, as this is a third-party action
# Commit e4612787670fc5b5f49026b8c29c5569921de1db = tag v1.2.0
uses: jandelgado/gcov2lcov-action@e4612787670fc5b5f49026b8c29c5569921de1db
with:
infile: acc.out
working-directory: src/github.com/nats-io/nats-server
- name: Coveralls
# Use commit hash here to avoid a re-tagging attack, as this is a third-party action
# Commit 5cbfd81b66ca5d10c19b062c04de0199c215fb6e = tag v2.3.7
uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e
with:
github-token: ${{ secrets.github_token }}
file: src/github.com/nats-io/nats-server/coverage.lcov
================================================
FILE: .github/workflows/long-tests.yaml
================================================
name: NATS Server Long Tests
on:
# Allow manual trigger (any branch)
workflow_dispatch:
# Run daily at 12:30 on default branch
schedule:
- cron: "30 12 * * *"
permissions:
contents: read
concurrency:
# At most one of these workflow per ref running
group: ${{ github.workflow }}-${{ github.ref }}
# New one cancels in-progress one
cancel-in-progress: true
jobs:
js-long:
name: Long JetStream tests
runs-on: ${{ vars.GHA_WORKER_MEDIUM || 'ubuntu-latest' }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run tests
run: go test -race -v -run='^TestLong.*' ./server -tags=include_js_long_tests -count=1 -vet=off -timeout=60m -shuffle on -p 1 -failfast
================================================
FILE: .github/workflows/mqtt-test.yaml
================================================
name: MQTT External Tests
on: [pull_request]
permissions:
contents: read
jobs:
test:
env:
GOPATH: /home/runner/work/nats-server
GO111MODULE: "on"
runs-on: ${{ vars.GHA_WORKER_SMALL || 'ubuntu-latest' }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
path: src/github.com/nats-io/nats-server
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: stable
cache-dependency-path: src/github.com/nats-io/nats-server/go.sum
- name: Set up testing tools and environment
shell: bash --noprofile --norc -eo pipefail {0}
id: setup
run: |
wget https://github.com/hivemq/mqtt-cli/releases/download/v4.20.0/mqtt-cli-4.20.0.deb
sudo apt install ./mqtt-cli-4.20.0.deb
go install github.com/ConnectEverything/mqtt-test@v0.1.0
- name: Run tests (3 times to detect flappers)
shell: bash --noprofile --norc -eo pipefail {0}
run: |
cd src/github.com/nats-io/nats-server
go test -v --count=3 --run='TestXMQTT' ./server
- name: Run tests with --race
shell: bash --noprofile --norc -eo pipefail {0}
run: |
cd src/github.com/nats-io/nats-server
go test -v --race --failfast --run='TestXMQTT' ./server
- name: Run benchmarks
shell: bash --noprofile --norc -eo pipefail {0}
run: |
cd src/github.com/nats-io/nats-server
go test --run='-' --count=3 --bench 'BenchmarkXMQTT' --benchtime=100x ./server
# TODO: compare benchmarks
================================================
FILE: .github/workflows/nightly.yaml
================================================
name: Docker Nightly
on:
workflow_dispatch:
inputs:
target:
description: "Override source branch (optional)"
type: string
required: false
schedule:
- cron: "40 4 * * *"
permissions:
contents: read
jobs:
run:
runs-on: ${{ vars.GHA_WORKER_RELEASE || 'ubuntu-latest' }}
permissions:
contents: write
steps:
- name: Checkout NATS
uses: actions/checkout@v6
with:
path: src/github.com/nats-io/nats-server
ref: ${{ inputs.target || 'main' }}
fetch-depth: 0
fetch-tags: true
- name: Checkout NSC
uses: actions/checkout@v6
with:
repository: nats-io/nsc
path: src/github.com/nats-io/nsc
fetch-depth: 1
fetch-tags: true
- name: Checkout NATS CLI
uses: actions/checkout@v6
with:
repository: nats-io/natscli
path: src/github.com/nats-io/natscli
fetch-depth: 1
fetch-tags: true
- name: Build Docker nightly
uses: ./src/github.com/nats-io/nats-server/.github/actions/nightly-release
with:
name: ${{ inputs.target || 'nightly' }}
hub_username: "${{ secrets.DOCKER_USERNAME }}"
hub_password: "${{ secrets.DOCKER_PASSWORD }}"
================================================
FILE: .github/workflows/release.yaml
================================================
name: NATS Server Releases
on:
push:
tags:
- v*
permissions:
contents: read
jobs:
run:
name: GitHub Release
runs-on: ${{ vars.GHA_WORKER_RELEASE || 'ubuntu-latest' }}
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: "stable"
- name: Check version matches tag
env:
TRAVIS_TAG: ${{ github.ref_name }}
run: |
go test -race -v -run=TestVersionMatchesTag ./server -ldflags="-X=github.com/nats-io/nats-server/v2/server.serverVersion=$TRAVIS_TAG" -count=1 -vet=off
- name: Install cosign
# Use commit hash here to avoid a re-tagging attack, as this is a third-party action
# Commit ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 = tag v4.1.0
uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22
- name: Install syft
# Use commit hash here to avoid a re-tagging attack, as this is a third-party action
# Commit 57aae528053a48a3f6235f2d9461b05fbcb7366d = tag v0.23.1
uses: anchore/sbom-action/download-syft@57aae528053a48a3f6235f2d9461b05fbcb7366d
with:
syft-version: "v1.42.2"
- name: Create release
uses: goreleaser/goreleaser-action@v7
with:
distribution: goreleaser
version: "~> v2"
args: release --clean
env:
GITHUB_REPOSITORY_NAME: ${{ github.event.repository.name }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/stale-issues.yaml
================================================
name: Stale Issues
on:
schedule:
- cron: "30 1 * * *"
permissions:
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
with:
stale-issue-label: stale
stale-pr-label: stale
days-before-stale: 56 # Mark stale after 8 weeks (56 days) of inactivity
days-before-close: -1 # Disable auto-closing
exempt-all-milestones: true # Any issue/PR within a milestone will be omitted
================================================
FILE: .github/workflows/tests.yaml
================================================
name: NATS Server Tests
on:
push:
pull_request:
workflow_dispatch:
permissions:
contents: read
env:
RACE: ${{ (github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/release/') && github.event_name != 'pull_request') && '-race' || '' }}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/release/') }}
jobs:
signoffs:
name: Sign-offs
runs-on: ${{ vars.GHA_WORKER_SMALL || 'ubuntu-latest' }}
if: github.ref != 'refs/heads/main'
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Check all branch commits are signed off
if: github.event_name != 'pull_request'
run: |
for c in $(git rev-list --no-merges ${{ github.event.before }}..${{ github.event.after }}); do
msg="$(git log -1 --pretty=%B "$c")"
if ! printf '%s\n' "$msg" | grep -q '^Signed-off-by:'; then
echo "::error ::Commit $c has not been signed off in the commit message with a \`Signed-off-by: Your Name <your.email@example.com>\` line"
git log -1 --pretty=format:"%h %s" "$c"
missing=1
fi
done
exit $missing
- name: Check all PR commits are signed off
if: github.event_name == 'pull_request'
run: |
for c in $(git rev-list origin/${{ github.base_ref }}..${{ github.event.pull_request.head.sha }}); do
msg="$(git log -1 --pretty=%B "$c")"
if ! printf '%s\n' "$msg" | grep -q '^Signed-off-by:'; then
echo "::error ::Commit $c has not been signed off in the commit message with a \`Signed-off-by: Your Name <your.email@example.com>\` line"
git log -1 --pretty=format:"%h %s" "$c"
missing=1
fi
done
exit $missing
- name: Check PR description is signed off
if: github.event_name == 'pull_request'
env:
PR_DESC: ${{ github.event.pull_request.body }}
run: |
grep -Pq '^Signed-off-by:\s*(?!Your Name|.*<your\.email@example\.com>)' <<<"$PR_DESC" || {
echo "::error ::Pull request has not been signed off in the PR description with a \`Signed-off-by:\` line"
exit 1
}
lint:
name: Lint
runs-on: ${{ vars.GHA_WORKER_SMALL || 'ubuntu-latest' }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version-file: "go.mod"
- name: Run golangci-lint
# Use commit hash here to avoid a re-tagging attack, as this is a third-party action
# Commit 1481404843c368bc19ca9406f87d6e0fc97bdcfd = tag v7.0.0
uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd
with:
version: v2.9.0
skip-cache: true
skip-save-cache: true
args: --timeout=5m --config=.golangci.yml
build-latest:
name: Build (Latest Go)
runs-on: ${{ vars.GHA_WORKER_SMALL || 'ubuntu-latest' }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Build NATS Server 64-bit
run: GOARCH=amd64 GOOS=linux go build
- name: Build NATS Server 32-bit
run: GOARCH=386 GOOS=linux go build
build-supported:
name: Build (Minimum Go)
runs-on: ${{ vars.GHA_WORKER_SMALL || 'ubuntu-latest' }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version-file: "go.mod"
- name: Build NATS Server 64-bit
run: GOARCH=amd64 GOOS=linux go build
- name: Build NATS Server 32-bit
run: GOARCH=386 GOOS=linux go build
# Using GitHub-supplied workers for Windows for now.
# Note that the below testing steps depend on the Linux build
# only, as the Windows builds take a fair bit longer to set up.
build-windows:
name: Build (Minimum Go, ${{ matrix.os }})
strategy:
fail-fast: false
matrix:
os: [windows-2022, windows-2025]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version-file: "go.mod"
- name: Build NATS Server
run: go build
store:
name: Test Stores
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_MEDIUM || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh store_tests
js-no-cluster:
name: Test JetStream
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh js_tests
raft:
name: Test Raft
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh raft_tests
js-consumers:
name: Test JetStream Consumers
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh js_consumer_tests
js-cluster-1:
name: Test JetStream Cluster 1
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh js_cluster_tests_1
js-cluster-2:
name: Test JetStream Cluster 2
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh js_cluster_tests_2
js-cluster-3:
name: Test JetStream Cluster 3
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh js_cluster_tests_3
js-cluster-4:
name: Test JetStream Cluster 4
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh js_cluster_tests_4
js-supercluster:
name: Test JetStream Supercluster
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh js_super_cluster_tests
no-race-1:
name: Test No-Race 1
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh no_race_1_tests
no-race-2:
name: Test No-Race 2
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh no_race_2_tests
mqtt:
name: Test MQTT
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_MEDIUM || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh mqtt_tests
msgtrace:
name: Test Message Tracing
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_MEDIUM || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh msgtrace_tests
jwt:
name: Test JWT
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh jwt_tests
server-pkg-non-js:
name: Test Remaining Server Tests
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_LARGE || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh srv_pkg_non_js_tests
non-server-pkg:
name: Test Other Packages
needs: [build-latest, build-supported, lint]
runs-on: ${{ vars.GHA_WORKER_MEDIUM || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Run unit tests
run: ./scripts/runTestsOnTravis.sh non_srv_pkg_tests
================================================
FILE: .github/workflows/vuln.yaml
================================================
name: Vulnerability Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: "0 6 * * *"
permissions:
contents: read
security-events: write
jobs:
govulncheck:
runs-on: ${{ vars.GHA_WORKER_SMALL || 'ubuntu-latest' }}
steps:
- name: Run govulncheck
# Use commit hash here to avoid a re-tagging attack, as this is a third-party action
# Commit b625fbe08f3bccbe446d94fbf87fcc875a4f50ee = tag v1.0.4
uses: golang/govulncheck-action@b625fbe08f3bccbe446d94fbf87fcc875a4f50ee
with:
go-package: ./...
output-format: sarif
output-file: govulncheck.sarif
- name: Upload SARIF results
if: github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: govulncheck.sarif
================================================
FILE: .gitignore
================================================
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
dist
# Configuration Files
*.conf
*.cfg
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
# Eclipse
.project
# IntelliJ
.idea/
# Emacs
*~
\#*\#
.\#*
# Visual Studio Code
.vscode
# Mac
.DS_Store
# bin
nats-server
gnatsd
check
# coverage
coverage.out
# Cross compiled binaries
pkg
================================================
FILE: .golangci.yml
================================================
version: "2"
run:
concurrency: 4
modules-download-mode: readonly
issues-exit-code: 1
tests: true
output:
formats:
text:
path: stdout
print-linter-name: true
print-issued-lines: true
linters:
default: none
enable:
- forbidigo
- govet
- ineffassign
- misspell
- staticcheck
- unused
settings:
errcheck:
check-type-assertions: false
check-blank: false
forbidigo:
forbid:
- pattern: ^fmt\.Print(f|ln)?$
govet:
settings:
printf:
funcs:
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
misspell:
locale: US
staticcheck:
checks:
- all
- -QF*
- -ST1003
- -ST1016
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- linters:
- forbidigo
path: main.go
- linters:
- forbidigo
source: "nats-server: v%s"
- linters:
- forbidigo
path: server/opts.go
- linters:
- forbidigo
path: _test.go
paths:
- .github
- doc
- docker
- logos
- scripts
- util
- third_party$
- builtin$
- examples$
formatters:
enable:
- goimports
exclusions:
generated: lax
paths:
- .github
- doc
- docker
- logos
- scripts
- util
- third_party$
- builtin$
- examples$
================================================
FILE: .goreleaser.yml
================================================
project_name: nats-server
version: 2
release:
github:
owner: '{{ envOrDefault "GITHUB_REPOSITORY_OWNER" "nats-io" }}'
name: '{{ envOrDefault "GITHUB_REPOSITORY_NAME" "nats-server" }}'
name_template: "Release {{.Tag}}"
draft: true
changelog:
disable: true
builds:
- main: .
binary: nats-server
flags:
- -trimpath
ldflags:
- -w -X 'github.com/nats-io/nats-server/v2/server.gitCommit={{.ShortCommit}}' -X 'github.com/nats-io/nats-server/v2/server.serverVersion={{.Tag}}'
env:
# This is the toolchain version we use for releases. To override, set the env var, e.g.:
# GORELEASER_TOOLCHAIN="go1.22.8" TARGET='linux_amd64' goreleaser build --snapshot --clean --single-target
- GOTOOLCHAIN={{ envOrDefault "GORELEASER_TOOLCHAIN" "go1.26.1" }}
- GO111MODULE=on
- CGO_ENABLED=0
goos:
- darwin
- linux
- windows
- freebsd
goarch:
- amd64
- arm
- arm64
- 386
- loong64
- mips64le
- s390x
- ppc64le
# RISC-V currently only supported on Linux
- riscv64
goarm:
- 6
- 7
ignore:
- goos: windows
goarch: arm
- goos: darwin
goarch: 386
- goos: freebsd
goarch: arm
- goos: freebsd
goarch: arm64
- goos: freebsd
goarch: 386
- goos: darwin
goarch: riscv64
- goos: windows
goarch: riscv64
- goos: freebsd
goarch: riscv64
mod_timestamp: "{{ .CommitTimestamp }}"
nfpms:
- file_name_template: "{{.ProjectName}}-{{.Tag}}-{{.Arch}}{{if .Arm}}{{.Arm}}{{end}}"
homepage: https://nats.io
description: High-Performance server for NATS, the cloud native messaging system.
maintainer: Ivan Kozlovic <ivan@synadia.com>
license: Apache 2.0
vendor: Synadia Inc.
formats:
- deb
- rpm
mtime: "{{ .CommitDate }}"
contents:
- src: /usr/bin/nats-server
dst: /usr/local/bin/nats-server
type: "symlink"
rpm:
buildhost: synadia.com
archives:
- name_template: "{{.ProjectName}}-{{.Tag}}-{{.Os}}-{{.Arch}}{{if .Arm}}{{.Arm}}{{end}}"
id: targz-archives
wrap_in_directory: true
formats: ["tar.gz"]
format_overrides:
- goos: windows
formats: ["zip"]
builds_info:
owner: root
group: root
mode: 0755
files:
- src: README.md
info:
owner: root
group: root
mode: 0644
mtime: "{{ .CommitDate }}"
- src: LICENSE
info:
owner: root
group: root
mode: 0644
mtime: "{{ .CommitDate }}"
checksum:
name_template: "SHA256SUMS"
algorithm: sha256
sboms:
- artifacts: binary
documents:
[
"{{.ProjectName}}-{{.Tag}}-{{.Os}}-{{.Arch}}{{if .Arm}}{{.Arm}}{{end}}.sbom.spdx.json",
]
================================================
FILE: AMBASSADORS.md
================================================
# Ambassadors
The NATS ambassador program recognizes community members that go above and beyond in their contributions to the community and the ecosystem. Learn more [here](https://nats.io/community#nats-ambassador-program).
- [Maurice van Veen](https://nats.io/community#maurice-van-veen) <contact@mauricevanveen.com>
================================================
FILE: CODE-OF-CONDUCT.md
================================================
## Community Code of Conduct
NATS follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
Thanks for your interest in contributing! This document contains `nats-io/nats-server` specific contributing details. If you are a first-time contributor, please refer to the general [NATS Contributor Guide](https://nats.io/contributing/) to get a comprehensive overview of contributing to the NATS project.
## Getting started
There are three general ways you can contribute to this repo:
- Proposing an enhancement or new feature
- Reporting a bug or regression
- Contributing changes to the source code
For the first two, refer to the [GitHub Issues](https://github.com/nats-io/nats-server/issues/new/choose) which guides you through the available options along with the needed information to collect.
## Contributing changes
_Prior to opening a pull request, it is recommended to open an issue first to ensure the maintainers can review intended changes. This saves time for both you and us. Exceptions to this rule include fixing non-functional source such as code comments, documentation or other supporting files._
Proposing source code changes is done through GitHub's standard pull request workflow.
If your branch is a work-in-progress then please start by creating your pull requests as draft, by clicking the down-arrow next to the `Create pull request` button and instead selecting `Create draft pull request`.
This will defer the automatic process of requesting a review from the NATS team and significantly reduces noise until you are ready. Once you are happy, you can click the `Ready for review` button.
### Guidelines
A good pull request includes:
- A succinct yet descriptive title describing, in a few words, what is fixed/improved/optimised by this change.
- A high-level description of the changes, including an overview of _why_ the changes are relevant or what problem you are trying to solve. Include links to any issues that are related by adding comments like `Resolves #NNN` to your description. See [Linking a Pull Request to an Issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) for more information.
- An up-to-date parent commit. Please make sure you are pulling in the latest `main` branch and rebasing your work on top of it, i.e. `git rebase main`.
- Unit tests where appropriate. Bug fixes will benefit from the addition of regression tests and performance improvements will benefit from the addition of new benchmarks where possible. New features will **NOT** be accepted without suitable test coverage!
- No more commits than necessary. Sometimes having multiple commits is useful for telling a story or isolating changes from one another, but please squash down any unnecessary commits that may just be for clean-up, comments or small changes.
- No additional external dependencies that aren't absolutely essential. Please do everything you can to avoid pulling in additional libraries/dependencies into `go.mod` as we will be very critical of these.
### Sign-off
In order to accept a contribution, you will first need to certify that the contribution is your original work and that you license the work to the project under the [Apache-2.0 license](https://github.com/nats-io/nats-server/blob/main/LICENSE).
This is done by using `Signed-off-by: Your Name <your.email@example.com>` statements, which should appear in **both** your commit messages and your PR description. Please note that we can only accept sign-offs under a legal name. Nicknames and aliases are not permitted.
To perform a sign-off when committing with `git`, use `git commit -s` (or `--signoff`) to add the `Signed-off-by:` trailer to your commit message.
## Get help
If you have questions about the contribution process, please start a [GitHub discussion](https://github.com/nats-io/nats-server/discussions), join the [NATS Slack](https://slack.nats.io/), or send your question to the [NATS Google Group](https://groups.google.com/forum/#!forum/natsio).
================================================
FILE: DEPENDENCIES.md
================================================
# External Dependencies
This file lists the dependencies used in this repository.
| Dependency | License |
|-|-|
| Go | BSD 3-Clause "New" or "Revised" License |
| github.com/nats-io/nats-server/v2 | Apache License 2.0 |
| github.com/google/go-tpm | Apache License 2.0 |
| github.com/klauspost/compress | BSD 3-Clause "New" or "Revised" License |
| github.com/minio/highwayhash | Apache License 2.0 |
| github.com/nats-io/jwt/v2 | Apache License 2.0 |
| github.com/nats-io/nats.go | Apache License 2.0 |
| github.com/nats-io/nkeys | Apache License 2.0 |
| github.com/nats-io/nuid | Apache License 2.0 |
| golang.org/x/crypto | BSD 3-Clause "New" or "Revised" License |
| golang.org/x/sys | BSD 3-Clause "New" or "Revised" License |
| golang.org/x/time | BSD 3-Clause "New" or "Revised" License |
================================================
FILE: GOVERNANCE.md
================================================
# NATS Server Governance
NATS Server is part of the NATS project and is subject to the [NATS Governance](https://github.com/nats-io/nats-general/blob/main/GOVERNANCE.md).
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: MAINTAINERS.md
================================================
# Maintainers
Maintainership is on a per project basis. Reference [NATS Governance Model](https://github.com/nats-io/nats-general/blob/main/GOVERNANCE.md).
### Maintainers
- Derek Collison <derek@nats.io> [@derekcollison](https://github.com/derekcollison)
- Ivan Kozlovic <ivan@nats.io> [@kozlovic](https://github.com/kozlovic)
- Waldemar Quevedo <wally@nats.io> [@wallyqs](https://github.com/wallyqs)
- Oleg Shaldybin <olegsh@google.com> [@olegshaldybin](https://github.com/olegshaldybin)
- R.I. Pienaar <rip@devco.net> [@ripienaar](https://github.com/ripienaar)
================================================
FILE: README.md
================================================
<p align="center">
<img src="logos/nats-horizontal-color.png" width="300" alt="NATS Logo">
</p>
[NATS](https://nats.io) is a simple, secure and performant communications system for digital systems, services and devices. NATS is part of the Cloud Native Computing Foundation ([CNCF](https://cncf.io)). NATS has over [40 client language implementations](https://nats.io/download/), and its server can run on-premise, in the cloud, at the edge, and even on a Raspberry Pi. NATS can secure and simplify design and operation of modern distributed systems.
[![License][License-Image]][License-Url] [![Build][Build-Status-Image]][Build-Status-Url] [![Release][Release-Image]][Release-Url] [![Slack][Slack-Image]][Slack-Url] [![Coverage][Coverage-Image]][Coverage-Url] [![Docker Downloads][Docker-Image]][Docker-Url] [![GitHub Downloads][GitHub-Image]][Somsubhra-URL] [![CII Best Practices][CIIBestPractices-Image]][CIIBestPractices-Url] [![Artifact Hub][ArtifactHub-Image]][ArtifactHub-Url]
## Documentation
- [Official Website](https://nats.io)
- [Official Documentation](https://docs.nats.io)
- [FAQ](https://docs.nats.io/reference/faq)
- Watch [a video overview](https://rethink.synadia.com/episodes/1/) of NATS.
- Watch [this video from SCALE 13x](https://www.youtube.com/watch?v=sm63oAVPqAM) to learn more about its origin story and design philosophy.
## Contact
- [Twitter](https://twitter.com/nats_io): Follow us on Twitter!
- [Google Groups](https://groups.google.com/forum/#!forum/natsio): Where you can ask questions
- [Slack](https://natsio.slack.com): Click [here](https://slack.nats.io) to join. You can ask questions to our maintainers and to the rich and active community.
## Contributing
If you are interested in contributing to NATS, read about our...
- [Contributing guide](./CONTRIBUTING.md)
- [Report issues or propose Pull Requests](https://github.com/nats-io)
[License-Url]: https://www.apache.org/licenses/LICENSE-2.0
[License-Image]: https://img.shields.io/badge/License-Apache2-blue.svg
[Docker-Image]: https://img.shields.io/docker/pulls/_/nats.svg
[Docker-Url]: https://hub.docker.com/_/nats
[Slack-Image]: https://img.shields.io/badge/chat-on%20slack-green
[Slack-Url]: https://slack.nats.io
[Fossa-Url]: https://app.fossa.io/projects/git%2Bgithub.com%2Fnats-io%2Fnats-server?ref=badge_shield
[Fossa-Image]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fnats-io%2Fnats-server.svg?type=shield
[Build-Status-Url]: https://github.com/nats-io/nats-server/actions/workflows/tests.yaml
[Build-Status-Image]: https://github.com/nats-io/nats-server/actions/workflows/tests.yaml/badge.svg?branch=main
[Release-Url]: https://github.com/nats-io/nats-server/releases/latest
[Release-Image]: https://img.shields.io/github/v/release/nats-io/nats-server
[Coverage-Url]: https://coveralls.io/r/nats-io/nats-server?branch=main
[Coverage-image]: https://coveralls.io/repos/github/nats-io/nats-server/badge.svg?branch=main
[ReportCard-Url]: https://goreportcard.com/report/nats-io/nats-server
[ReportCard-Image]: https://goreportcard.com/badge/github.com/nats-io/nats-server
[CIIBestPractices-Url]: https://bestpractices.coreinfrastructure.org/projects/1895
[CIIBestPractices-Image]: https://bestpractices.coreinfrastructure.org/projects/1895/badge
[ArtifactHub-Url]: https://artifacthub.io/packages/helm/nats/nats
[ArtifactHub-Image]: https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/nats
[GitHub-Release]: https://github.com/nats-io/nats-server/releases/
[GitHub-Image]: https://img.shields.io/github/downloads/nats-io/nats-server/total.svg?logo=github
[Somsubhra-url]: https://somsubhra.github.io/github-release-stats/?username=nats-io&repository=nats-server
## Roadmap
The NATS product roadmap can be found [here](https://nats.io/about/#roadmap).
## Adopters
Who uses NATS? See our [list of users](https://nats.io/#who-uses-nats) on [https://nats.io](https://nats.io).
## Security
### Security Audit
A third party security audit was performed by Trail of Bits following engagement by the Open Source Technology Improvement Fund (OSTIF). You can see the [full report from April 2025 here](https://github.com/trailofbits/publications/blob/master/reviews/2025-04-ostif-nats-securityreview.pdf).
### Reporting Security Vulnerabilities
If you've found a vulnerability or a potential vulnerability in the NATS server, please let us know at
[nats-security](mailto:security@nats.io).
## License
Unless otherwise noted, the NATS source files are distributed
under the Apache Version 2.0 license found in the LICENSE file.
================================================
FILE: RELEASES.md
================================================
# Release Workflow
- As of NATS 2.11, the server follows a 6-month release cycle. 2.11 was released in March 2025.
- Version tagging follows semantic versioning with security fixes clearly marked.
- The `main` branch is for active development of features and bug fixes. Release branches are created for preparing patch releases. Releases are tagged with semantic versions
- The current and previous minor series are supported in terms of bug fixes and security patches.
- Binaries are released via [GitHub Releases](https://github.com/nats-io/nats-server/releases) and Docker images are available as an [official image](https://hub.docker.com/_/nats).
- Preview releases for the next minor version, e.g. 2.14.0, become available once feature development is complete.
- Tagged releases as well as nightly Docker images of `main` (for testing) are available in the [synadia/nats-server](https://hub.docker.com/r/synadia/nats-server/tags) Docker repository.
================================================
FILE: TODO.md
================================================
# General
- [ ] Auth for queue groups?
- [ ] Blacklist or ERR escalation to close connection for auth/permissions
- [ ] Protocol updates, MAP, MPUB, etc
- [ ] Multiple listen endpoints
- [ ] Websocket / HTTP2 strategy
- [ ] T series reservations
- [ ] _SYS. server events?
- [ ] No downtime restart
- [ ] Signal based reload of configuration
- [ ] brew, apt-get, rpm, chocately (windows)
- [ ] IOVec pools and writev for high fanout?
- [ ] Modify cluster support for single message across routes between pub/sub and d-queue
- [ ] Memory limits/warnings?
- [ ] Limit number of subscriptions a client can have, total memory usage etc.
- [ ] Multi-tenant accounts with isolation of subject space
- [ ] Pedantic state
- [X] _SYS.> reserved for server events?
- [X] Listen configure key vs addr and port
- [X] Add ENV and variable support to dconf? ucl?
- [X] Buffer pools/sync pools?
- [X] Multiple Authorization / Access
- [X] Write dynamic socket buffer sizes
- [X] Read dynamic socket buffer sizes
- [X] Info updates contain other implicit route servers
- [X] Sublist better at high concurrency, cache uses writelock always currently
- [X] Switch to 1.4/1.5 and use maps vs hashmaps in sublist
- [X] NewSource on Rand to lower lock contention on QueueSubs, or redesign!
- [X] Default sort by cid on connz
- [X] Track last activity time per connection?
- [X] Add total connections to varz so we won't miss spikes, etc.
- [X] Add starttime and uptime to connz list.
- [X] Gossip Protocol for discovery for clustering
- [X] Add in HTTP requests to varz?
- [X] Add favico and help link for monitoring?
- [X] Better user/pass support using bcrypt etc.
- [X] SSL/TLS support
- [X] Add support for / to point to varz, connz, etc..
- [X] Support sort options for /connz via nats-top
- [X] Dropped message statistics (slow consumers)
- [X] Add current time to each monitoring endpoint
- [X] varz uptime do days and only integer secs
- [X] Place version in varz (same info sent to clients)
- [X] Place server ID/UUID in varz
- [X] nats-top equivalent, utils
- [X] Connz report routes (/routez)
- [X] Docker
- [X] Remove reliance on `ps`
- [X] Syslog support
- [X] Client support for language and version
- [X] Fix benchmarks on linux
- [X] Daemon mode? Won't fix
================================================
FILE: conf/fuzz.go
================================================
// Copyright 2020-2025 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build gofuzz
package conf
func Fuzz(data []byte) int {
_, err := Parse(string(data))
if err != nil {
return 0
}
return 1
}
================================================
FILE: conf/lex.go
================================================
// Copyright 2013-2024 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Customized heavily from
// https://github.com/BurntSushi/toml/blob/master/lex.go, which is based on
// Rob Pike's talk: http://cuddle.googlecode.com/hg/talk/lex.html
// The format supported is less restrictive than today's formats.
// Supports mixed Arrays [], nested Maps {}, multiple comment types (# and //)
// Also supports key value assignments using '=' or ':' or whiteSpace()
// e.g. foo = 2, foo : 2, foo 2
// maps can be assigned with no key separator as well
// semicolons as value terminators in key/value assignments are optional
//
// see lex_test.go for more examples.
package conf
import (
"encoding/hex"
"fmt"
"strings"
"unicode"
"unicode/utf8"
)
type itemType int
const (
itemError itemType = iota
itemNIL // used in the parser to indicate no type
itemEOF
itemKey
itemText
itemString
itemBool
itemInteger
itemFloat
itemDatetime
itemArrayStart
itemArrayEnd
itemMapStart
itemMapEnd
itemCommentStart
itemVariable
itemInclude
)
const (
eof = 0
mapStart = '{'
mapEnd = '}'
keySepEqual = '='
keySepColon = ':'
arrayStart = '['
arrayEnd = ']'
arrayValTerm = ','
mapValTerm = ','
commentHashStart = '#'
commentSlashStart = '/'
dqStringStart = '"'
dqStringEnd = '"'
sqStringStart = '\''
sqStringEnd = '\''
optValTerm = ';'
topOptStart = '{'
topOptValTerm = ','
topOptTerm = '}'
blockStart = '('
blockEnd = ')'
mapEndString = string(mapEnd)
)
type stateFn func(lx *lexer) stateFn
type lexer struct {
input string
start int
pos int
width int
line int
state stateFn
items chan item
// A stack of state functions used to maintain context.
// The idea is to reuse parts of the state machine in various places.
// For example, values can appear at the top level or within arbitrarily
// nested arrays. The last state on the stack is used after a value has
// been lexed. Similarly for comments.
stack []stateFn
// Used for processing escapable substrings in double-quoted and raw strings
stringParts []string
stringStateFn stateFn
// lstart is the start position of the current line.
lstart int
// ilstart is the start position of the line from the current item.
ilstart int
}
type item struct {
typ itemType
val string
line int
pos int
}
func (lx *lexer) nextItem() item {
for {
select {
case item := <-lx.items:
return item
default:
lx.state = lx.state(lx)
}
}
}
func lex(input string) *lexer {
lx := &lexer{
input: input,
state: lexTop,
line: 1,
items: make(chan item, 10),
stack: make([]stateFn, 0, 10),
stringParts: []string{},
}
return lx
}
func (lx *lexer) push(state stateFn) {
lx.stack = append(lx.stack, state)
}
func (lx *lexer) pop() stateFn {
if len(lx.stack) == 0 {
return lx.errorf("BUG in lexer: no states to pop.")
}
li := len(lx.stack) - 1
last := lx.stack[li]
lx.stack = lx.stack[0:li]
return last
}
func (lx *lexer) emit(typ itemType) {
val := strings.Join(lx.stringParts, "") + lx.input[lx.start:lx.pos]
// Position of item in line where it started.
pos := lx.pos - lx.ilstart - len(val)
lx.items <- item{typ, val, lx.line, pos}
lx.start = lx.pos
lx.ilstart = lx.lstart
}
func (lx *lexer) emitString() {
var finalString string
if len(lx.stringParts) > 0 {
finalString = strings.Join(lx.stringParts, "") + lx.input[lx.start:lx.pos]
lx.stringParts = []string{}
} else {
finalString = lx.input[lx.start:lx.pos]
}
// Position of string in line where it started.
pos := lx.pos - lx.ilstart - len(finalString)
lx.items <- item{itemString, finalString, lx.line, pos}
lx.start = lx.pos
lx.ilstart = lx.lstart
}
func (lx *lexer) addCurrentStringPart(offset int) {
lx.stringParts = append(lx.stringParts, lx.input[lx.start:lx.pos-offset])
lx.start = lx.pos
}
func (lx *lexer) addStringPart(s string) stateFn {
lx.stringParts = append(lx.stringParts, s)
lx.start = lx.pos
return lx.stringStateFn
}
func (lx *lexer) hasEscapedParts() bool {
return len(lx.stringParts) > 0
}
func (lx *lexer) next() (r rune) {
if lx.pos >= len(lx.input) {
lx.width = 0
return eof
}
if lx.input[lx.pos] == '\n' {
lx.line++
// Mark start position of current line.
lx.lstart = lx.pos
}
r, lx.width = utf8.DecodeRuneInString(lx.input[lx.pos:])
lx.pos += lx.width
return r
}
// ignore skips over the pending input before this point.
func (lx *lexer) ignore() {
lx.start = lx.pos
lx.ilstart = lx.lstart
}
// backup steps back one rune. Can be called only once per call of next.
func (lx *lexer) backup() {
lx.pos -= lx.width
if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' {
lx.line--
}
}
// peek returns but does not consume the next rune in the input.
func (lx *lexer) peek() rune {
r := lx.next()
lx.backup()
return r
}
// errorf stops all lexing by emitting an error and returning `nil`.
// Note that any value that is a character is escaped if it's a special
// character (new lines, tabs, etc.).
func (lx *lexer) errorf(format string, values ...any) stateFn {
for i, value := range values {
if v, ok := value.(rune); ok {
values[i] = escapeSpecial(v)
}
}
// Position of error in current line.
pos := lx.pos - lx.lstart
lx.items <- item{
itemError,
fmt.Sprintf(format, values...),
lx.line,
pos,
}
return nil
}
// lexTop consumes elements at the top level of data structure.
func lexTop(lx *lexer) stateFn {
r := lx.next()
if unicode.IsSpace(r) {
return lexSkip(lx, lexTop)
}
switch r {
case topOptStart:
lx.push(lexTop)
return lexSkip(lx, lexBlockStart)
case commentHashStart:
lx.push(lexTop)
return lexCommentStart
case commentSlashStart:
rn := lx.next()
if rn == commentSlashStart {
lx.push(lexTop)
return lexCommentStart
}
lx.backup()
fallthrough
case eof:
if lx.pos > lx.start {
return lx.errorf("Unexpected EOF.")
}
lx.emit(itemEOF)
return nil
}
// At this point, the only valid item can be a key, so we back up
// and let the key lexer do the rest.
lx.backup()
lx.push(lexTopValueEnd)
return lexKeyStart
}
// lexTopValueEnd is entered whenever a top-level value has been consumed.
// It must see only whitespace, and will turn back to lexTop upon a new line.
// If it sees EOF, it will quit the lexer successfully.
func lexTopValueEnd(lx *lexer) stateFn {
r := lx.next()
switch {
case r == commentHashStart:
// a comment will read to a new line for us.
lx.push(lexTop)
return lexCommentStart
case r == commentSlashStart:
rn := lx.next()
if rn == commentSlashStart {
lx.push(lexTop)
return lexCommentStart
}
lx.backup()
fallthrough
case isWhitespace(r):
return lexTopValueEnd
case isNL(r) || r == eof || r == optValTerm || r == topOptValTerm || r == topOptTerm:
lx.ignore()
return lexTop
}
return lx.errorf("Expected a top-level value to end with a new line, "+
"comment or EOF, but got '%v' instead.", r)
}
func lexBlockStart(lx *lexer) stateFn {
r := lx.next()
if unicode.IsSpace(r) {
return lexSkip(lx, lexBlockStart)
}
switch r {
case topOptStart:
lx.push(lexBlockEnd)
return lexSkip(lx, lexBlockStart)
case topOptTerm:
lx.ignore()
return lx.pop()
case commentHashStart:
lx.push(lexBlockStart)
return lexCommentStart
case commentSlashStart:
rn := lx.next()
if rn == commentSlashStart {
lx.push(lexBlockStart)
return lexCommentStart
}
lx.backup()
fallthrough
case eof:
if lx.pos > lx.start {
return lx.errorf("Unexpected EOF.")
}
lx.emit(itemEOF)
return nil
}
// At this point, the only valid item can be a key, so we back up
// and let the key lexer do the rest.
lx.backup()
lx.push(lexBlockValueEnd)
return lexKeyStart
}
// lexBlockValueEnd is entered whenever a block-level value has been consumed.
// It must see only whitespace, and will turn back to lexBlockStart upon a new line.
// If it sees EOF, it will quit the lexer successfully.
func lexBlockValueEnd(lx *lexer) stateFn {
r := lx.next()
switch {
case r == commentHashStart:
// a comment will read to a new line for us.
lx.push(lexBlockValueEnd)
return lexCommentStart
case r == commentSlashStart:
rn := lx.next()
if rn == commentSlashStart {
lx.push(lexBlockValueEnd)
return lexCommentStart
}
lx.backup()
fallthrough
case isWhitespace(r):
return lexBlockValueEnd
case isNL(r) || r == optValTerm || r == topOptValTerm:
lx.ignore()
return lexBlockStart
case r == topOptTerm:
lx.backup()
return lexBlockEnd
}
return lx.errorf("Expected a block-level value to end with a new line, "+
"comment or EOF, but got '%v' instead.", r)
}
// lexBlockEnd is entered whenever a block-level value has been consumed.
// It must see only whitespace, and will turn back to lexTop upon a "}".
func lexBlockEnd(lx *lexer) stateFn {
r := lx.next()
switch {
case r == commentHashStart:
// a comment will read to a new line for us.
lx.push(lexBlockStart)
return lexCommentStart
case r == commentSlashStart:
rn := lx.next()
if rn == commentSlashStart {
lx.push(lexBlockStart)
return lexCommentStart
}
lx.backup()
fallthrough
case isNL(r) || isWhitespace(r):
return lexBlockEnd
case r == optValTerm || r == topOptValTerm:
lx.ignore()
return lexBlockStart
case r == topOptTerm:
lx.ignore()
return lx.pop()
}
return lx.errorf("Expected a block-level to end with a '}', but got '%v' instead.", r)
}
// lexKeyStart consumes a key name up until the first non-whitespace character.
// lexKeyStart will ignore whitespace. It will also eat enclosing quotes.
func lexKeyStart(lx *lexer) stateFn {
r := lx.peek()
switch {
case isKeySeparator(r):
return lx.errorf("Unexpected key separator '%v'", r)
case unicode.IsSpace(r):
lx.next()
return lexSkip(lx, lexKeyStart)
case r == dqStringStart:
lx.next()
return lexSkip(lx, lexDubQuotedKey)
case r == sqStringStart:
lx.next()
return lexSkip(lx, lexQuotedKey)
}
lx.ignore()
lx.next()
return lexKey
}
// lexDubQuotedKey consumes the text of a key between quotes.
func lexDubQuotedKey(lx *lexer) stateFn {
r := lx.peek()
if r == dqStringEnd {
lx.emit(itemKey)
lx.next()
return lexSkip(lx, lexKeyEnd)
} else if r == eof {
if lx.pos > lx.start {
return lx.errorf("Unexpected EOF.")
}
lx.emit(itemEOF)
return nil
}
lx.next()
return lexDubQuotedKey
}
// lexQuotedKey consumes the text of a key between quotes.
func lexQuotedKey(lx *lexer) stateFn {
r := lx.peek()
if r == sqStringEnd {
lx.emit(itemKey)
lx.next()
return lexSkip(lx, lexKeyEnd)
} else if r == eof {
if lx.pos > lx.start {
return lx.errorf("Unexpected EOF.")
}
lx.emit(itemEOF)
return nil
}
lx.next()
return lexQuotedKey
}
// keyCheckKeyword will check for reserved keywords as the key value when the key is
// separated with a space.
func (lx *lexer) keyCheckKeyword(fallThrough, push stateFn) stateFn {
key := strings.ToLower(lx.input[lx.start:lx.pos])
switch key {
case "include":
lx.ignore()
if push != nil {
lx.push(push)
}
return lexIncludeStart
}
lx.emit(itemKey)
return fallThrough
}
// lexIncludeStart will consume the whitespace til the start of the value.
func lexIncludeStart(lx *lexer) stateFn {
r := lx.next()
if isWhitespace(r) {
return lexSkip(lx, lexIncludeStart)
}
lx.backup()
return lexInclude
}
// lexIncludeQuotedString consumes the inner contents of a string. It assumes that the
// beginning '"' has already been consumed and ignored. It will not interpret any
// internal contents.
func lexIncludeQuotedString(lx *lexer) stateFn {
r := lx.next()
switch {
case r == sqStringEnd:
lx.backup()
lx.emit(itemInclude)
lx.next()
lx.ignore()
return lx.pop()
case r == eof:
return lx.errorf("Unexpected EOF in quoted include")
}
return lexIncludeQuotedString
}
// lexIncludeDubQuotedString consumes the inner contents of a string. It assumes that the
// beginning '"' has already been consumed and ignored. It will not interpret any
// internal contents.
func lexIncludeDubQuotedString(lx *lexer) stateFn {
r := lx.next()
switch {
case r == dqStringEnd:
lx.backup()
lx.emit(itemInclude)
lx.next()
lx.ignore()
return lx.pop()
case r == eof:
return lx.errorf("Unexpected EOF in double quoted include")
}
return lexIncludeDubQuotedString
}
// lexIncludeString consumes the inner contents of a raw string.
func lexIncludeString(lx *lexer) stateFn {
r := lx.next()
switch {
case isNL(r) || r == eof || r == optValTerm || r == mapEnd || isWhitespace(r):
lx.backup()
lx.emit(itemInclude)
return lx.pop()
case r == sqStringEnd:
lx.backup()
lx.emit(itemInclude)
lx.next()
lx.ignore()
return lx.pop()
}
return lexIncludeString
}
// lexInclude will consume the include value.
func lexInclude(lx *lexer) stateFn {
r := lx.next()
switch {
case r == sqStringStart:
lx.ignore() // ignore the " or '
return lexIncludeQuotedString
case r == dqStringStart:
lx.ignore() // ignore the " or '
return lexIncludeDubQuotedString
case r == arrayStart:
return lx.errorf("Expected include value but found start of an array")
case r == mapStart:
return lx.errorf("Expected include value but found start of a map")
case r == blockStart:
return lx.errorf("Expected include value but found start of a block")
case unicode.IsDigit(r), r == '-':
return lx.errorf("Expected include value but found start of a number")
case r == '\\':
return lx.errorf("Expected include value but found escape sequence")
case isNL(r):
return lx.errorf("Expected include value but found new line")
}
lx.backup()
return lexIncludeString
}
// lexKey consumes the text of a key. Assumes that the first character (which
// is not whitespace) has already been consumed.
func lexKey(lx *lexer) stateFn {
r := lx.peek()
if unicode.IsSpace(r) {
// Spaces signal we could be looking at a keyword, e.g. include.
// Keywords will eat the keyword and set the appropriate return stateFn.
return lx.keyCheckKeyword(lexKeyEnd, nil)
} else if isKeySeparator(r) || r == eof {
lx.emit(itemKey)
return lexKeyEnd
}
lx.next()
return lexKey
}
// lexKeyEnd consumes the end of a key (up to the key separator).
// Assumes that the first whitespace character after a key (or the '=' or ':'
// separator) has NOT been consumed.
func lexKeyEnd(lx *lexer) stateFn {
r := lx.next()
switch {
case unicode.IsSpace(r):
return lexSkip(lx, lexKeyEnd)
case isKeySeparator(r):
return lexSkip(lx, lexValue)
case r == eof:
lx.emit(itemEOF)
return nil
}
// We start the value here
lx.backup()
return lexValue
}
// lexValue starts the consumption of a value anywhere a value is expected.
// lexValue will ignore whitespace.
// After a value is lexed, the last state on the next is popped and returned.
func lexValue(lx *lexer) stateFn {
// We allow whitespace to precede a value, but NOT new lines.
// In array syntax, the array states are responsible for ignoring new lines.
r := lx.next()
if isWhitespace(r) {
return lexSkip(lx, lexValue)
}
switch {
case r == arrayStart:
lx.ignore()
lx.emit(itemArrayStart)
return lexArrayValue
case r == mapStart:
lx.ignore()
lx.emit(itemMapStart)
return lexMapKeyStart
case r == sqStringStart:
lx.ignore() // ignore the " or '
return lexQuotedString
case r == dqStringStart:
lx.ignore() // ignore the " or '
lx.stringStateFn = lexDubQuotedString
return lexDubQuotedString
case r == '-':
return lexNegNumberStart
case r == blockStart:
lx.ignore()
return lexBlock
case unicode.IsDigit(r):
lx.backup() // avoid an extra state and use the same as above
return lexNumberOrDateOrStringOrIPStart
case r == '.': // special error case, be kind to users
return lx.errorf("Floats must start with a digit")
case isNL(r):
return lx.errorf("Expected value but found new line")
}
lx.backup()
lx.stringStateFn = lexString
return lexString
}
// lexArrayValue consumes one value in an array. It assumes that '[' or ','
// have already been consumed. All whitespace and new lines are ignored.
func lexArrayValue(lx *lexer) stateFn {
r := lx.next()
switch {
case unicode.IsSpace(r):
return lexSkip(lx, lexArrayValue)
case r == commentHashStart:
lx.push(lexArrayValue)
return lexCommentStart
case r == commentSlashStart:
rn := lx.next()
if rn == commentSlashStart {
lx.push(lexArrayValue)
return lexCommentStart
}
lx.backup()
fallthrough
case r == arrayValTerm:
return lx.errorf("Unexpected array value terminator '%v'.", arrayValTerm)
case r == arrayEnd:
return lexArrayEnd
}
lx.backup()
lx.push(lexArrayValueEnd)
return lexValue
}
// lexArrayValueEnd consumes the cruft between values of an array. Namely,
// it ignores whitespace and expects either a ',' or a ']'.
func lexArrayValueEnd(lx *lexer) stateFn {
r := lx.next()
switch {
case isWhitespace(r):
return lexSkip(lx, lexArrayValueEnd)
case r == commentHashStart:
lx.push(lexArrayValueEnd)
return lexCommentStart
case r == commentSlashStart:
rn := lx.next()
if rn == commentSlashStart {
lx.push(lexArrayValueEnd)
return lexCommentStart
}
lx.backup()
fallthrough
case r == arrayValTerm || isNL(r):
return lexSkip(lx, lexArrayValue) // Move onto next
case r == arrayEnd:
return lexArrayEnd
}
return lx.errorf("Expected an array value terminator %q or an array "+
"terminator %q, but got '%v' instead.", arrayValTerm, arrayEnd, r)
}
// lexArrayEnd finishes the lexing of an array. It assumes that a ']' has
// just been consumed.
func lexArrayEnd(lx *lexer) stateFn {
lx.ignore()
lx.emit(itemArrayEnd)
return lx.pop()
}
// lexMapKeyStart consumes a key name up until the first non-whitespace
// character.
// lexMapKeyStart will ignore whitespace.
func lexMapKeyStart(lx *lexer) stateFn {
r := lx.peek()
switch {
case isKeySeparator(r):
return lx.errorf("Unexpected key separator '%v'.", r)
case r == arrayEnd:
return lx.errorf("Unexpected array end '%v' processing map.", r)
case unicode.IsSpace(r):
lx.next()
return lexSkip(lx, lexMapKeyStart)
case r == mapEnd:
lx.next()
return lexSkip(lx, lexMapEnd)
case r == commentHashStart:
lx.next()
lx.push(lexMapKeyStart)
return lexCommentStart
case r == commentSlashStart:
lx.next()
rn := lx.next()
if rn == commentSlashStart {
lx.push(lexMapKeyStart)
return lexCommentStart
}
lx.backup()
case r == sqStringStart:
lx.next()
return lexSkip(lx, lexMapQuotedKey)
case r == dqStringStart:
lx.next()
return lexSkip(lx, lexMapDubQuotedKey)
case r == eof:
return lx.errorf("Unexpected EOF processing map.")
}
lx.ignore()
lx.next()
return lexMapKey
}
// lexMapQuotedKey consumes the text of a key between quotes.
func lexMapQuotedKey(lx *lexer) stateFn {
if r := lx.peek(); r == eof {
return lx.errorf("Unexpected EOF processing quoted map key.")
} else if r == sqStringEnd {
lx.emit(itemKey)
lx.next()
return lexSkip(lx, lexMapKeyEnd)
}
lx.next()
return lexMapQuotedKey
}
// lexMapDubQuotedKey consumes the text of a key between quotes.
func lexMapDubQuotedKey(lx *lexer) stateFn {
if r := lx.peek(); r == eof {
return lx.errorf("Unexpected EOF processing double quoted map key.")
} else if r == dqStringEnd {
lx.emit(itemKey)
lx.next()
return lexSkip(lx, lexMapKeyEnd)
}
lx.next()
return lexMapDubQuotedKey
}
// lexMapKey consumes the text of a key. Assumes that the first character (which
// is not whitespace) has already been consumed.
func lexMapKey(lx *lexer) stateFn {
if r := lx.peek(); r == eof {
return lx.errorf("Unexpected EOF processing map key.")
} else if unicode.IsSpace(r) {
// Spaces signal we could be looking at a keyword, e.g. include.
// Keywords will eat the keyword and set the appropriate return stateFn.
return lx.keyCheckKeyword(lexMapKeyEnd, lexMapValueEnd)
} else if isKeySeparator(r) {
lx.emit(itemKey)
return lexMapKeyEnd
}
lx.next()
return lexMapKey
}
// lexMapKeyEnd consumes the end of a key (up to the key separator).
// Assumes that the first whitespace character after a key (or the '='
// separator) has NOT been consumed.
func lexMapKeyEnd(lx *lexer) stateFn {
r := lx.next()
switch {
case unicode.IsSpace(r):
return lexSkip(lx, lexMapKeyEnd)
case isKeySeparator(r):
return lexSkip(lx, lexMapValue)
}
// We start the value here
lx.backup()
return lexMapValue
}
// lexMapValue consumes one value in a map. It assumes that '{' or ','
// have already been consumed. All whitespace and new lines are ignored.
// Map values can be separated by ',' or simple NLs.
func lexMapValue(lx *lexer) stateFn {
r := lx.next()
switch {
case unicode.IsSpace(r):
return lexSkip(lx, lexMapValue)
case r == mapValTerm:
return lx.errorf("Unexpected map value terminator %q.", mapValTerm)
case r == mapEnd:
return lexSkip(lx, lexMapEnd)
}
lx.backup()
lx.push(lexMapValueEnd)
return lexValue
}
// lexMapValueEnd consumes the cruft between values of a map. Namely,
// it ignores whitespace and expects either a ',' or a '}'.
func lexMapValueEnd(lx *lexer) stateFn {
r := lx.next()
switch {
case isWhitespace(r):
return lexSkip(lx, lexMapValueEnd)
case r == commentHashStart:
lx.push(lexMapValueEnd)
return lexCommentStart
case r == commentSlashStart:
rn := lx.next()
if rn == commentSlashStart {
lx.push(lexMapValueEnd)
return lexCommentStart
}
lx.backup()
fallthrough
case r == optValTerm || r == mapValTerm || isNL(r):
return lexSkip(lx, lexMapKeyStart) // Move onto next
case r == mapEnd:
return lexSkip(lx, lexMapEnd)
}
return lx.errorf("Expected a map value terminator %q or a map "+
"terminator %q, but got '%v' instead.", mapValTerm, mapEnd, r)
}
// lexMapEnd finishes the lexing of a map. It assumes that a '}' has
// just been consumed.
func lexMapEnd(lx *lexer) stateFn {
lx.ignore()
lx.emit(itemMapEnd)
return lx.pop()
}
// Checks if the unquoted string was actually a boolean
func (lx *lexer) isBool() bool {
str := strings.ToLower(lx.input[lx.start:lx.pos])
return str == "true" || str == "false" ||
str == "on" || str == "off" ||
str == "yes" || str == "no"
}
// Check if the unquoted string is a variable reference, starting with $.
func (lx *lexer) isVariable() bool {
if lx.start >= len(lx.input) {
return false
}
if lx.input[lx.start] == '$' {
lx.start += 1
return true
}
return false
}
// lexQuotedString consumes the inner contents of a string. It assumes that the
// beginning '"' has already been consumed and ignored. It will not interpret any
// internal contents.
func lexQuotedString(lx *lexer) stateFn {
r := lx.next()
switch {
case r == sqStringEnd:
lx.backup()
lx.emit(itemString)
lx.next()
lx.ignore()
return lx.pop()
case r == eof:
if lx.pos > lx.start {
return lx.errorf("Unexpected EOF.")
}
lx.emit(itemEOF)
return nil
}
return lexQuotedString
}
// lexDubQuotedString consumes the inner contents of a string. It assumes that the
// beginning '"' has already been consumed and ignored. It will not interpret any
// internal contents.
func lexDubQuotedString(lx *lexer) stateFn {
r := lx.next()
switch {
case r == '\\':
lx.addCurrentStringPart(1)
return lexStringEscape
case r == dqStringEnd:
lx.backup()
lx.emitString()
lx.next()
lx.ignore()
return lx.pop()
case r == eof:
if lx.pos > lx.start {
return lx.errorf("Unexpected EOF.")
}
lx.emit(itemEOF)
return nil
}
return lexDubQuotedString
}
// lexString consumes the inner contents of a raw string.
func lexString(lx *lexer) stateFn {
r := lx.next()
switch {
case r == '\\':
lx.addCurrentStringPart(1)
return lexStringEscape
// Termination of non-quoted strings
case isNL(r) || r == eof || r == optValTerm ||
r == arrayValTerm || r == arrayEnd || r == mapEnd ||
isWhitespace(r):
lx.backup()
if lx.hasEscapedParts() {
lx.emitString()
} else if lx.isBool() {
lx.emit(itemBool)
} else if lx.isVariable() {
lx.emit(itemVariable)
} else {
lx.emitString()
}
return lx.pop()
case r == sqStringEnd:
lx.backup()
lx.emitString()
lx.next()
lx.ignore()
return lx.pop()
}
return lexString
}
// lexBlock consumes the inner contents as a string. It assumes that the
// beginning '(' has already been consumed and ignored. It will continue
// processing until it finds a ')' on a new line by itself.
func lexBlock(lx *lexer) stateFn {
r := lx.next()
switch {
case r == blockEnd:
lx.backup()
lx.backup()
// Looking for a ')' character on a line by itself, if the previous
// character isn't a new line, then break so we keep processing the block.
if lx.next() != '\n' {
lx.next()
break
}
lx.next()
// Make sure the next character is a new line or an eof. We want a ')' on a
// bare line by itself.
switch lx.next() {
case '\n', eof:
lx.backup()
lx.backup()
lx.emit(itemString)
lx.next()
lx.ignore()
return lx.pop()
}
lx.backup()
case r == eof:
return lx.errorf("Unexpected EOF processing block.")
}
return lexBlock
}
// lexStringEscape consumes an escaped character. It assumes that the preceding
// '\\' has already been consumed.
func lexStringEscape(lx *lexer) stateFn {
r := lx.next()
switch r {
case 'x':
return lexStringBinary
case 't':
return lx.addStringPart("\t")
case 'n':
return lx.addStringPart("\n")
case 'r':
return lx.addStringPart("\r")
case '"':
return lx.addStringPart("\"")
case '\\':
return lx.addStringPart("\\")
}
return lx.errorf("Invalid escape character '%v'. Only the following "+
"escape characters are allowed: \\xXX, \\t, \\n, \\r, \\\", \\\\.", r)
}
// lexStringBinary consumes two hexadecimal digits following '\x'. It assumes
// that the '\x' has already been consumed.
func lexStringBinary(lx *lexer) stateFn {
r := lx.next()
if isNL(r) {
return lx.errorf("Expected two hexadecimal digits after '\\x', but hit end of line")
}
r = lx.next()
if isNL(r) {
return lx.errorf("Expected two hexadecimal digits after '\\x', but hit end of line")
}
offset := lx.pos - 2
byteString, err := hex.DecodeString(lx.input[offset:lx.pos])
if err != nil {
return lx.errorf("Expected two hexadecimal digits after '\\x', but got '%s'", lx.input[offset:lx.pos])
}
lx.addStringPart(string(byteString))
return lx.stringStateFn
}
// lexNumberOrDateOrStringOrIPStart consumes either a (positive)
// integer, a float, a datetime, or IP, or String that started with a
// number. It assumes that NO negative sign has been consumed, that
// is triggered above.
func lexNumberOrDateOrStringOrIPStart(lx *lexer) stateFn {
r := lx.next()
if !unicode.IsDigit(r) {
if r == '.' {
return lx.errorf("Floats must start with a digit, not '.'.")
}
return lx.errorf("Expected a digit but got '%v'.", r)
}
return lexNumberOrDateOrStringOrIP
}
// lexNumberOrDateOrStringOrIP consumes either a (positive) integer,
// float, datetime, IP or string without quotes that starts with a
// number.
func lexNumberOrDateOrStringOrIP(lx *lexer) stateFn {
r := lx.next()
switch {
case r == '-':
if lx.pos-lx.start != 5 {
return lx.errorf("All ISO8601 dates must be in full Zulu form.")
}
return lexDateAfterYear
case unicode.IsDigit(r):
return lexNumberOrDateOrStringOrIP
case r == '.':
// Assume float at first, but could be IP
return lexFloatStart
case isNumberSuffix(r):
return lexConvenientNumber
case !(isNL(r) || r == eof || r == mapEnd || r == optValTerm || r == mapValTerm || isWhitespace(r) || unicode.IsDigit(r)):
// Treat it as a string value once we get a rune that
// is not a number.
lx.stringStateFn = lexString
return lexString
}
lx.backup()
lx.emit(itemInteger)
return lx.pop()
}
// lexConvenientNumber is when we have a suffix, e.g. 1k or 1Mb
func lexConvenientNumber(lx *lexer) stateFn {
r := lx.next()
switch {
case r == 'b' || r == 'B' || r == 'i' || r == 'I':
return lexConvenientNumber
}
lx.backup()
if isNL(r) || r == eof || r == mapEnd || r == optValTerm || r == mapValTerm || isWhitespace(r) || unicode.IsDigit(r) {
lx.emit(itemInteger)
return lx.pop()
}
// This is not a number, so treat it as a string.
lx.stringStateFn = lexString
return lexString
}
// lexDateAfterYear consumes a full Zulu Datetime in ISO8601 format.
// It assumes that "YYYY-" has already been consumed.
func lexDateAfterYear(lx *lexer) stateFn {
formats := []rune{
// digits are '0'.
// everything else is direct equality.
'0', '0', '-', '0', '0',
'T',
'0', '0', ':', '0', '0', ':', '0', '0',
'Z',
}
for _, f := range formats {
r := lx.next()
if f == '0' {
if !unicode.IsDigit(r) {
return lx.errorf("Expected digit in ISO8601 datetime, "+
"but found '%v' instead.", r)
}
} else if f != r {
return lx.errorf("Expected '%v' in ISO8601 datetime, "+
"but found '%v' instead.", f, r)
}
}
lx.emit(itemDatetime)
return lx.pop()
}
// lexNegNumberStart consumes either an integer or a float. It assumes that a
// negative sign has already been read, but that *no* digits have been consumed.
// lexNegNumberStart will move to the appropriate integer or float states.
func lexNegNumberStart(lx *lexer) stateFn {
// we MUST see a digit. Even floats have to start with a digit.
r := lx.next()
if !unicode.IsDigit(r) {
if r == '.' {
return lx.errorf("Floats must start with a digit, not '.'.")
}
return lx.errorf("Expected a digit but got '%v'.", r)
}
return lexNegNumber
}
// lexNegNumber consumes a negative integer or a float after seeing the first digit.
func lexNegNumber(lx *lexer) stateFn {
r := lx.next()
switch {
case unicode.IsDigit(r):
return lexNegNumber
case r == '.':
return lexFloatStart
case isNumberSuffix(r):
return lexConvenientNumber
}
lx.backup()
lx.emit(itemInteger)
return lx.pop()
}
// lexFloatStart starts the consumption of digits of a float after a '.'.
// Namely, at least one digit is required.
func lexFloatStart(lx *lexer) stateFn {
r := lx.next()
if !unicode.IsDigit(r) {
return lx.errorf("Floats must have a digit after the '.', but got "+
"'%v' instead.", r)
}
return lexFloat
}
// lexFloat consumes the digits of a float after a '.'.
// Assumes that one digit has been consumed after a '.' already.
func lexFloat(lx *lexer) stateFn {
r := lx.next()
if unicode.IsDigit(r) {
return lexFloat
}
// Not a digit, if its another '.', need to see if we falsely assumed a float.
if r == '.' {
return lexIPAddr
}
lx.backup()
lx.emit(itemFloat)
return lx.pop()
}
// lexIPAddr consumes IP addrs, like 127.0.0.1:4222
func lexIPAddr(lx *lexer) stateFn {
r := lx.next()
if unicode.IsDigit(r) || r == '.' || r == ':' || r == '-' {
return lexIPAddr
}
lx.backup()
lx.emit(itemString)
return lx.pop()
}
// lexCommentStart begins the lexing of a comment. It will emit
// itemCommentStart and consume no characters, passing control to lexComment.
func lexCommentStart(lx *lexer) stateFn {
lx.ignore()
lx.emit(itemCommentStart)
return lexComment
}
// lexComment lexes an entire comment. It assumes that '#' has been consumed.
// It will consume *up to* the first new line character, and pass control
// back to the last state on the stack.
func lexComment(lx *lexer) stateFn {
r := lx.peek()
if isNL(r) || r == eof {
lx.emit(itemText)
return lx.pop()
}
lx.next()
return lexComment
}
// lexSkip ignores all slurped input and moves on to the next state.
func lexSkip(lx *lexer, nextState stateFn) stateFn {
return func(lx *lexer) stateFn {
lx.ignore()
return nextState
}
}
// Tests to see if we have a number suffix
func isNumberSuffix(r rune) bool {
return r == 'k' || r == 'K' || r == 'm' || r == 'M' || r == 'g' || r == 'G' || r == 't' || r == 'T' || r == 'p' || r == 'P' || r == 'e' || r == 'E'
}
// Tests for both key separators
func isKeySeparator(r rune) bool {
return r == keySepEqual || r == keySepColon
}
// isWhitespace returns true if `r` is a whitespace character according
// to the spec.
func isWhitespace(r rune) bool {
return r == '\t' || r == ' '
}
func isNL(r rune) bool {
return r == '\n' || r == '\r'
}
func (itype itemType) String() string {
switch itype {
case itemError:
return "Error"
case itemNIL:
return "NIL"
case itemEOF:
return "EOF"
case itemText:
return "Text"
case itemString:
return "String"
case itemBool:
return "Bool"
case itemInteger:
return "Integer"
case itemFloat:
return "Float"
case itemDatetime:
return "DateTime"
case itemKey:
return "Key"
case itemArrayStart:
return "ArrayStart"
case itemArrayEnd:
return "ArrayEnd"
case itemMapStart:
return "MapStart"
case itemMapEnd:
return "MapEnd"
case itemCommentStart:
return "CommentStart"
case itemVariable:
return "Variable"
case itemInclude:
return "Include"
}
panic(fmt.Sprintf("BUG: Unknown type '%s'.", itype.String()))
}
func (item item) String() string {
return fmt.Sprintf("(%s, '%s', %d, %d)", item.typ.String(), item.val, item.line, item.pos)
}
func escapeSpecial(c rune) string {
switch c {
case '\n':
return "\\n"
}
return string(c)
}
================================================
FILE: conf/lex_test.go
================================================
package conf
import "testing"
// Test to make sure we get what we expect.
func expect(t *testing.T, lx *lexer, items []item) {
t.Helper()
for i := 0; i < len(items); i++ {
item := lx.nextItem()
_ = item.String()
if item.typ == itemEOF {
break
}
if item != items[i] {
t.Fatalf("Testing: '%s'\nExpected %q, received %q\n",
lx.input, items[i], item)
}
if item.typ == itemError {
break
}
}
}
func TestPlainValue(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemEOF, "", 1, 0},
}
lx := lex("foo")
expect(t, lx, expectedItems)
}
func TestSimpleKeyStringValues(t *testing.T) {
// Double quotes
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "bar", 1, 7},
{itemEOF, "", 1, 0},
}
lx := lex("foo = \"bar\"")
expect(t, lx, expectedItems)
// Single quotes
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemString, "bar", 1, 7},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 'bar'")
expect(t, lx, expectedItems)
// No spaces
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemString, "bar", 1, 5},
{itemEOF, "", 1, 0},
}
lx = lex("foo='bar'")
expect(t, lx, expectedItems)
// NL
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemString, "bar", 1, 5},
{itemEOF, "", 1, 0},
}
lx = lex("foo='bar'\r\n")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemString, "bar", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo=\t'bar'\t")
expect(t, lx, expectedItems)
}
func TestComplexStringValues(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "bar\\r\\n \\t", 1, 7},
{itemEOF, "", 2, 0},
}
lx := lex("foo = 'bar\\r\\n \\t'")
expect(t, lx, expectedItems)
}
func TestStringStartingWithNumber(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "3xyz", 1, 6},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = 3xyz`)
expect(t, lx, expectedItems)
lx = lex(`foo = 3xyz,`)
expect(t, lx, expectedItems)
lx = lex(`foo = 3xyz;`)
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 2, 9},
{itemString, "3xyz", 2, 15},
{itemEOF, "", 2, 0},
}
content := `
foo = 3xyz
`
lx = lex(content)
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "map", 2, 9},
{itemMapStart, "", 2, 14},
{itemKey, "foo", 3, 11},
{itemString, "3xyz", 3, 17},
{itemMapEnd, "", 3, 22},
{itemEOF, "", 2, 0},
}
content = `
map {
foo = 3xyz}
`
lx = lex(content)
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "map", 2, 9},
{itemMapStart, "", 2, 14},
{itemKey, "foo", 3, 11},
{itemString, "3xyz", 3, 17},
{itemMapEnd, "", 4, 10},
{itemEOF, "", 2, 0},
}
content = `
map {
foo = 3xyz;
}
`
lx = lex(content)
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "map", 2, 9},
{itemMapStart, "", 2, 14},
{itemKey, "foo", 3, 11},
{itemString, "3xyz", 3, 17},
{itemKey, "bar", 4, 11},
{itemString, "4wqs", 4, 17},
{itemMapEnd, "", 5, 10},
{itemEOF, "", 2, 0},
}
content = `
map {
foo = 3xyz,
bar = 4wqs
}
`
lx = lex(content)
expect(t, lx, expectedItems)
}
func TestBinaryString(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "e", 1, 9},
{itemEOF, "", 1, 0},
}
lx := lex("foo = \\x65")
expect(t, lx, expectedItems)
}
func TestBinaryStringLatin1(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "\xe9", 1, 9},
{itemEOF, "", 1, 0},
}
lx := lex("foo = \\xe9")
expect(t, lx, expectedItems)
}
func TestSimpleKeyIntegerValues(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemInteger, "123", 1, 6},
{itemEOF, "", 1, 0},
}
lx := lex("foo = 123")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "123", 1, 4},
{itemEOF, "", 1, 0},
}
lx = lex("foo=123")
expect(t, lx, expectedItems)
lx = lex("foo=123\r\n")
expect(t, lx, expectedItems)
}
func TestSimpleKeyNegativeIntegerValues(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemInteger, "-123", 1, 6},
{itemEOF, "", 1, 0},
}
lx := lex("foo = -123")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "-123", 1, 4},
{itemEOF, "", 1, 0},
}
lx = lex("foo=-123")
expect(t, lx, expectedItems)
lx = lex("foo=-123\r\n")
expect(t, lx, expectedItems)
}
func TestConvenientIntegerValues(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemInteger, "1k", 1, 6},
{itemEOF, "", 1, 0},
}
lx := lex("foo = 1k")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "1K", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 1K")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "1m", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 1m")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "1M", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 1M")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "1g", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 1g")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "1G", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 1G")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "1MB", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 1MB")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "1Gb", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 1Gb")
expect(t, lx, expectedItems)
// Negative versions
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "-1m", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = -1m")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "-1GB", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = -1GB ")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemString, "1Ghz", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 1Ghz")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemString, "2Pie", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 2Pie")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemString, "3Mbs", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 3Mbs,")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "4Gb", 1, 6},
{itemKey, "bar", 1, 11},
{itemString, "5Gø", 1, 17},
{itemEOF, "", 1, 0},
}
lx = lex("foo = 4Gb, bar = 5Gø")
expect(t, lx, expectedItems)
}
func TestSimpleKeyFloatValues(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemFloat, "22.2", 1, 6},
{itemEOF, "", 1, 0},
}
lx := lex("foo = 22.2")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemFloat, "22.2", 1, 4},
{itemEOF, "", 1, 0},
}
lx = lex("foo=22.2")
expect(t, lx, expectedItems)
lx = lex("foo=22.2\r\n")
expect(t, lx, expectedItems)
}
func TestBadBinaryStringEndingAfterZeroHexChars(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemError, "Expected two hexadecimal digits after '\\x', but hit end of line", 2, 1},
{itemEOF, "", 1, 0},
}
lx := lex("foo = xyz\\x\n")
expect(t, lx, expectedItems)
}
func TestBadBinaryStringEndingAfterOneHexChar(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemError, "Expected two hexadecimal digits after '\\x', but hit end of line", 2, 1},
{itemEOF, "", 1, 0},
}
lx := lex("foo = xyz\\xF\n")
expect(t, lx, expectedItems)
}
func TestBadBinaryStringWithZeroHexChars(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemError, "Expected two hexadecimal digits after '\\x', but got ']\"'", 1, 12},
{itemEOF, "", 1, 0},
}
lx := lex(`foo = "[\x]"`)
expect(t, lx, expectedItems)
}
func TestBadBinaryStringWithOneHexChar(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemError, "Expected two hexadecimal digits after '\\x', but got 'e]'", 1, 12},
{itemEOF, "", 1, 0},
}
lx := lex(`foo = "[\xe]"`)
expect(t, lx, expectedItems)
}
func TestBadFloatValues(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemError, "Floats must start with a digit", 1, 7},
{itemEOF, "", 1, 0},
}
lx := lex("foo = .2")
expect(t, lx, expectedItems)
}
func TestBadKey(t *testing.T) {
expectedItems := []item{
{itemError, "Unexpected key separator ':'", 1, 1},
{itemEOF, "", 1, 0},
}
lx := lex(" :foo = 22")
expect(t, lx, expectedItems)
}
func TestSimpleKeyBoolValues(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemBool, "true", 1, 6},
{itemEOF, "", 1, 0},
}
lx := lex("foo = true")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemBool, "true", 1, 4},
{itemEOF, "", 1, 0},
}
lx = lex("foo=true")
expect(t, lx, expectedItems)
lx = lex("foo=true\r\n")
expect(t, lx, expectedItems)
}
func TestComments(t *testing.T) {
expectedItems := []item{
{itemCommentStart, "", 1, 1},
{itemText, " This is a comment", 1, 1},
{itemEOF, "", 1, 0},
}
lx := lex("# This is a comment")
expect(t, lx, expectedItems)
lx = lex("# This is a comment\r\n")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemCommentStart, "", 1, 2},
{itemText, " This is a comment", 1, 2},
{itemEOF, "", 1, 0},
}
lx = lex("// This is a comment\r\n")
expect(t, lx, expectedItems)
}
func TestTopValuesWithComments(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemInteger, "123", 1, 6},
{itemCommentStart, "", 1, 12},
{itemText, " This is a comment", 1, 12},
{itemEOF, "", 1, 0},
}
lx := lex("foo = 123 // This is a comment")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "123", 1, 4},
{itemCommentStart, "", 1, 12},
{itemText, " This is a comment", 1, 12},
{itemEOF, "", 1, 0},
}
lx = lex("foo=123 # This is a comment")
expect(t, lx, expectedItems)
}
func TestRawString(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "bar", 1, 6},
{itemEOF, "", 1, 0},
}
lx := lex("foo = bar")
expect(t, lx, expectedItems)
lx = lex(`foo = bar' `)
expect(t, lx, expectedItems)
}
func TestDateValues(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemDatetime, "2016-05-04T18:53:41Z", 1, 6},
{itemEOF, "", 1, 0},
}
lx := lex("foo = 2016-05-04T18:53:41Z")
expect(t, lx, expectedItems)
}
func TestVariableValues(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemVariable, "bar", 1, 7},
{itemEOF, "", 1, 0},
}
lx := lex("foo = $bar")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemVariable, "bar", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo =$bar")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemVariable, "bar", 1, 5},
{itemEOF, "", 1, 0},
}
lx = lex("foo $bar")
expect(t, lx, expectedItems)
}
func TestArrays(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemArrayStart, "", 1, 7},
{itemInteger, "1", 1, 7},
{itemInteger, "2", 1, 10},
{itemInteger, "3", 1, 13},
{itemString, "bar", 1, 17},
{itemArrayEnd, "", 1, 22},
{itemEOF, "", 1, 0},
}
lx := lex("foo = [1, 2, 3, 'bar']")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemArrayStart, "", 1, 7},
{itemInteger, "1", 1, 7},
{itemInteger, "2", 1, 9},
{itemInteger, "3", 1, 11},
{itemString, "bar", 1, 14},
{itemArrayEnd, "", 1, 19},
{itemEOF, "", 1, 0},
}
lx = lex("foo = [1,2,3,'bar']")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemArrayStart, "", 1, 7},
{itemInteger, "1", 1, 7},
{itemInteger, "2", 1, 10},
{itemInteger, "3", 1, 12},
{itemString, "bar", 1, 15},
{itemArrayEnd, "", 1, 20},
{itemEOF, "", 1, 0},
}
lx = lex("foo = [1, 2,3,'bar']")
expect(t, lx, expectedItems)
}
var mlArray = `
# top level comment
foo = [
1, # One
2, // Two
3 # Three
'bar' ,
"bar"
]
`
func TestMultilineArrays(t *testing.T) {
expectedItems := []item{
{itemCommentStart, "", 2, 2},
{itemText, " top level comment", 2, 2},
{itemKey, "foo", 3, 1},
{itemArrayStart, "", 3, 8},
{itemInteger, "1", 4, 2},
{itemCommentStart, "", 4, 6},
{itemText, " One", 4, 6},
{itemInteger, "2", 5, 2},
{itemCommentStart, "", 5, 7},
{itemText, " Two", 5, 7},
{itemInteger, "3", 6, 2},
{itemCommentStart, "", 6, 5},
{itemText, " Three", 6, 5},
{itemString, "bar", 7, 3},
{itemString, "bar", 8, 3},
{itemArrayEnd, "", 9, 2},
{itemEOF, "", 9, 0},
}
lx := lex(mlArray)
expect(t, lx, expectedItems)
}
var mlArrayNoSep = `
# top level comment
foo = [
1 // foo
2
3
'bar'
"bar"
]
`
func TestMultilineArraysNoSep(t *testing.T) {
expectedItems := []item{
{itemCommentStart, "", 2, 2},
{itemText, " top level comment", 2, 2},
{itemKey, "foo", 3, 1},
{itemArrayStart, "", 3, 8},
{itemInteger, "1", 4, 2},
{itemCommentStart, "", 4, 6},
{itemText, " foo", 4, 6},
{itemInteger, "2", 5, 2},
{itemInteger, "3", 6, 2},
{itemString, "bar", 7, 3},
{itemString, "bar", 8, 3},
{itemArrayEnd, "", 9, 2},
{itemEOF, "", 9, 0},
}
lx := lex(mlArrayNoSep)
expect(t, lx, expectedItems)
}
func TestSimpleMap(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemMapStart, "", 1, 7},
{itemKey, "ip", 1, 7},
{itemString, "127.0.0.1", 1, 11},
{itemKey, "port", 1, 23},
{itemInteger, "4242", 1, 30},
{itemMapEnd, "", 1, 35},
{itemEOF, "", 1, 0},
}
lx := lex("foo = {ip='127.0.0.1', port = 4242}")
expect(t, lx, expectedItems)
}
var mlMap = `
foo = {
ip = '127.0.0.1' # the IP
port= 4242 // the port
}
`
func TestMultilineMap(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 2, 1},
{itemMapStart, "", 2, 8},
{itemKey, "ip", 3, 3},
{itemString, "127.0.0.1", 3, 9},
{itemCommentStart, "", 3, 21},
{itemText, " the IP", 3, 21},
{itemKey, "port", 4, 3},
{itemInteger, "4242", 4, 9},
{itemCommentStart, "", 4, 16},
{itemText, " the port", 4, 16},
{itemMapEnd, "", 5, 2},
{itemEOF, "", 5, 0},
}
lx := lex(mlMap)
expect(t, lx, expectedItems)
}
var nestedMap = `
foo = {
host = {
ip = '127.0.0.1'
port= 4242
}
}
`
func TestNestedMaps(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 2, 1},
{itemMapStart, "", 2, 8},
{itemKey, "host", 3, 3},
{itemMapStart, "", 3, 11},
{itemKey, "ip", 4, 5},
{itemString, "127.0.0.1", 4, 11},
{itemKey, "port", 5, 5},
{itemInteger, "4242", 5, 11},
{itemMapEnd, "", 6, 4},
{itemMapEnd, "", 7, 2},
{itemEOF, "", 7, 0},
}
lx := lex(nestedMap)
expect(t, lx, expectedItems)
}
func TestQuotedKeys(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemInteger, "123", 1, 6},
{itemEOF, "", 1, 0},
}
lx := lex("foo : 123")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 1},
{itemInteger, "123", 1, 8},
{itemEOF, "", 1, 0},
}
lx = lex("'foo' : 123")
expect(t, lx, expectedItems)
lx = lex("\"foo\" : 123")
expect(t, lx, expectedItems)
}
func TestQuotedKeysWithSpace(t *testing.T) {
expectedItems := []item{
{itemKey, " foo", 1, 1},
{itemInteger, "123", 1, 9},
{itemEOF, "", 1, 0},
}
lx := lex("' foo' : 123")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, " foo", 1, 1},
{itemInteger, "123", 1, 9},
{itemEOF, "", 1, 0},
}
lx = lex("\" foo\" : 123")
expect(t, lx, expectedItems)
}
func TestColonKeySep(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemInteger, "123", 1, 6},
{itemEOF, "", 1, 0},
}
lx := lex("foo : 123")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "123", 1, 4},
{itemEOF, "", 1, 0},
}
lx = lex("foo:123")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "123", 1, 5},
{itemEOF, "", 1, 0},
}
lx = lex("foo: 123")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "123", 1, 6},
{itemEOF, "", 1, 0},
}
lx = lex("foo: 123\r\n")
expect(t, lx, expectedItems)
}
func TestWhitespaceKeySep(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemInteger, "123", 1, 4},
{itemEOF, "", 1, 0},
}
lx := lex("foo 123")
expect(t, lx, expectedItems)
lx = lex("foo 123")
expect(t, lx, expectedItems)
lx = lex("foo\t123")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemInteger, "123", 1, 5},
{itemEOF, "", 1, 0},
}
lx = lex("foo\t\t123\r\n")
expect(t, lx, expectedItems)
}
var escString = `
foo = \t
bar = \r
baz = \n
q = \"
bs = \\
`
func TestEscapedString(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 2, 1},
{itemString, "\t", 2, 9},
{itemKey, "bar", 3, 1},
{itemString, "\r", 3, 9},
{itemKey, "baz", 4, 1},
{itemString, "\n", 4, 9},
{itemKey, "q", 5, 1},
{itemString, "\"", 5, 9},
{itemKey, "bs", 6, 1},
{itemString, "\\", 6, 9},
{itemEOF, "", 6, 0},
}
lx := lex(escString)
expect(t, lx, expectedItems)
}
func TestCompoundStringES(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "\\end", 1, 8},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = "\\end"`)
expect(t, lx, expectedItems)
}
func TestCompoundStringSE(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "start\\", 1, 8},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = "start\\"`)
expect(t, lx, expectedItems)
}
func TestCompoundStringEE(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "Eq", 1, 12},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = \x45\x71`)
expect(t, lx, expectedItems)
}
func TestCompoundStringSEE(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "startEq", 1, 12},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = start\x45\x71`)
expect(t, lx, expectedItems)
}
func TestCompoundStringSES(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "start|end", 1, 9},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = start\x7Cend`)
expect(t, lx, expectedItems)
}
func TestCompoundStringEES(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "<>end", 1, 12},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = \x3c\x3eend`)
expect(t, lx, expectedItems)
}
func TestCompoundStringESE(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "<middle>", 1, 12},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = \x3cmiddle\x3E`)
expect(t, lx, expectedItems)
}
func TestBadStringEscape(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemError, "Invalid escape character 'y'. Only the following escape characters are allowed: \\xXX, \\t, \\n, \\r, \\\", \\\\.", 1, 8},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = \y`)
expect(t, lx, expectedItems)
}
func TestNonBool(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "\\true", 1, 7},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = \\true`)
expect(t, lx, expectedItems)
}
func TestNonVariable(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "\\$var", 1, 7},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = \\$var`)
expect(t, lx, expectedItems)
}
func TestEmptyStringDQ(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "", 1, 7},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = ""`)
expect(t, lx, expectedItems)
}
func TestEmptyStringSQ(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "", 1, 7},
{itemEOF, "", 2, 0},
}
lx := lex(`foo = ''`)
expect(t, lx, expectedItems)
}
var nestedWhitespaceMap = `
foo {
host {
ip = '127.0.0.1'
port= 4242
}
}
`
func TestNestedWhitespaceMaps(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 2, 1},
{itemMapStart, "", 2, 7},
{itemKey, "host", 3, 3},
{itemMapStart, "", 3, 10},
{itemKey, "ip", 4, 5},
{itemString, "127.0.0.1", 4, 11},
{itemKey, "port", 5, 5},
{itemInteger, "4242", 5, 11},
{itemMapEnd, "", 6, 4},
{itemMapEnd, "", 7, 2},
{itemEOF, "", 7, 0},
}
lx := lex(nestedWhitespaceMap)
expect(t, lx, expectedItems)
}
var semicolons = `
foo = 123;
bar = 'baz';
baz = 'boo'
map {
id = 1;
}
`
func TestOptionalSemicolons(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 2, 1},
{itemInteger, "123", 2, 7},
{itemKey, "bar", 3, 1},
{itemString, "baz", 3, 8},
{itemKey, "baz", 4, 1},
{itemString, "boo", 4, 8},
{itemKey, "map", 5, 1},
{itemMapStart, "", 5, 6},
{itemKey, "id", 6, 2},
{itemInteger, "1", 6, 7},
{itemMapEnd, "", 7, 2},
{itemEOF, "", 8, 0},
}
lx := lex(semicolons)
expect(t, lx, expectedItems)
}
func TestSemicolonChaining(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemString, "1", 1, 5},
{itemKey, "bar", 1, 9},
{itemFloat, "2.2", 1, 13},
{itemKey, "baz", 1, 18},
{itemBool, "true", 1, 22},
{itemEOF, "", 1, 0},
}
lx := lex("foo='1'; bar=2.2; baz=true;")
expect(t, lx, expectedItems)
}
var noquotes = `
foo = 123
bar = baz
baz=boo
map {
id:one
id2 : onetwo
}
t true
f false
tstr "true"
tkey = two
fkey = five # This should be a string
`
func TestNonQuotedStrings(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 2, 1},
{itemInteger, "123", 2, 7},
{itemKey, "bar", 3, 1},
{itemString, "baz", 3, 7},
{itemKey, "baz", 4, 1},
{itemString, "boo", 4, 5},
{itemKey, "map", 5, 1},
{itemMapStart, "", 5, 6},
{itemKey, "id", 6, 2},
{itemString, "one", 6, 5},
{itemKey, "id2", 7, 2},
{itemString, "onetwo", 7, 8},
{itemMapEnd, "", 8, 2},
{itemKey, "t", 9, 1},
{itemBool, "true", 9, 3},
{itemKey, "f", 10, 1},
{itemBool, "false", 10, 3},
{itemKey, "tstr", 11, 1},
{itemString, "true", 11, 7},
{itemKey, "tkey", 12, 1},
{itemString, "two", 12, 8},
{itemKey, "fkey", 13, 1},
{itemString, "five", 13, 8},
{itemCommentStart, "", 13, 14},
{itemText, " This should be a string", 13, 14},
{itemEOF, "", 14, 0},
}
lx := lex(noquotes)
expect(t, lx, expectedItems)
}
var danglingquote = `
listen: "localhost:4242
http: localhost:8222
`
func TestDanglingQuotedString(t *testing.T) {
expectedItems := []item{
{itemKey, "listen", 2, 1},
{itemError, "Unexpected EOF.", 5, 1},
}
lx := lex(danglingquote)
expect(t, lx, expectedItems)
}
var keydanglingquote = `
foo = "
listen: "
http: localhost:8222
"
`
func TestKeyDanglingQuotedString(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 2, 1},
{itemString, "\nlisten: ", 3, 8},
{itemKey, "http", 5, 1},
{itemString, "localhost:8222", 5, 7},
{itemError, "Unexpected EOF.", 8, 1},
}
lx := lex(keydanglingquote)
expect(t, lx, expectedItems)
}
var danglingsquote = `
listen: 'localhost:4242
http: localhost:8222
`
func TestDanglingSingleQuotedString(t *testing.T) {
expectedItems := []item{
{itemKey, "listen", 2, 1},
{itemError, "Unexpected EOF.", 5, 1},
}
lx := lex(danglingsquote)
expect(t, lx, expectedItems)
}
var keydanglingsquote = `
foo = '
listen: '
http: localhost:8222
'
`
func TestKeyDanglingSingleQuotedString(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 2, 1},
{itemString, "\nlisten: ", 3, 8},
{itemKey, "http", 5, 1},
{itemString, "localhost:8222", 5, 7},
{itemError, "Unexpected EOF.", 8, 1},
}
lx := lex(keydanglingsquote)
expect(t, lx, expectedItems)
}
var mapdanglingbracket = `
listen = 4222
cluster = {
foo = bar
`
func TestMapDanglingBracket(t *testing.T) {
expectedItems := []item{
{itemKey, "listen", 2, 1},
{itemInteger, "4222", 2, 10},
{itemKey, "cluster", 4, 1},
{itemMapStart, "", 4, 12},
{itemKey, "foo", 6, 3},
{itemString, "bar", 6, 9},
{itemError, "Unexpected EOF processing map.", 8, 1},
}
lx := lex(mapdanglingbracket)
expect(t, lx, expectedItems)
}
var blockdanglingparens = `
listen = 4222
quote = (
foo = bar
`
func TestBlockDanglingParens(t *testing.T) {
expectedItems := []item{
{itemKey, "listen", 2, 1},
{itemInteger, "4222", 2, 10},
{itemKey, "quote", 4, 1},
{itemError, "Unexpected EOF processing block.", 8, 1},
}
lx := lex(blockdanglingparens)
expect(t, lx, expectedItems)
}
func TestMapQuotedKeys(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemMapStart, "", 1, 7},
{itemKey, "bar", 1, 8},
{itemInteger, "4242", 1, 15},
{itemMapEnd, "", 1, 20},
{itemEOF, "", 1, 0},
}
lx := lex("foo = {'bar' = 4242}")
expect(t, lx, expectedItems)
lx = lex("foo = {\"bar\" = 4242}")
expect(t, lx, expectedItems)
}
func TestSpecialCharsMapQuotedKeys(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemMapStart, "", 1, 7},
{itemKey, "bar-1.2.3", 1, 8},
{itemMapStart, "", 1, 22},
{itemKey, "port", 1, 23},
{itemInteger, "4242", 1, 28},
{itemMapEnd, "", 1, 34},
{itemMapEnd, "", 1, 35},
{itemEOF, "", 1, 0},
}
lx := lex("foo = {'bar-1.2.3' = { port:4242 }}")
expect(t, lx, expectedItems)
lx = lex("foo = {\"bar-1.2.3\" = { port:4242 }}")
expect(t, lx, expectedItems)
}
var mlnestedmap = `
systems {
allinone {
description: "This is a description."
}
}
`
func TestDoubleNestedMapsNewLines(t *testing.T) {
expectedItems := []item{
{itemKey, "systems", 2, 1},
{itemMapStart, "", 2, 10},
{itemKey, "allinone", 3, 3},
{itemMapStart, "", 3, 13},
{itemKey, "description", 4, 5},
{itemString, "This is a description.", 4, 19},
{itemMapEnd, "", 5, 4},
{itemMapEnd, "", 6, 2},
{itemEOF, "", 7, 0},
}
lx := lex(mlnestedmap)
expect(t, lx, expectedItems)
}
var blockexample = `
numbers (
1234567890
)
`
func TestBlockString(t *testing.T) {
expectedItems := []item{
{itemKey, "numbers", 2, 1},
{itemString, "\n1234567890\n", 4, 10},
}
lx := lex(blockexample)
expect(t, lx, expectedItems)
}
func TestBlockStringEOF(t *testing.T) {
expectedItems := []item{
{itemKey, "numbers", 2, 1},
{itemString, "\n1234567890\n", 4, 10},
}
blockbytes := []byte(blockexample[0 : len(blockexample)-1])
blockbytes = append(blockbytes, 0)
lx := lex(string(blockbytes))
expect(t, lx, expectedItems)
}
var mlblockexample = `
numbers (
12(34)56
(
7890
)
)
`
func TestBlockStringMultiLine(t *testing.T) {
expectedItems := []item{
{itemKey, "numbers", 2, 1},
{itemString, "\n 12(34)56\n (\n 7890\n )\n", 7, 10},
}
lx := lex(mlblockexample)
expect(t, lx, expectedItems)
}
func TestUnquotedIPAddr(t *testing.T) {
expectedItems := []item{
{itemKey, "listen", 1, 0},
{itemString, "127.0.0.1:4222", 1, 8},
{itemEOF, "", 1, 0},
}
lx := lex("listen: 127.0.0.1:4222")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "listen", 1, 0},
{itemString, "127.0.0.1", 1, 8},
{itemEOF, "", 1, 0},
}
lx = lex("listen: 127.0.0.1")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "listen", 1, 0},
{itemString, "apcera.me:80", 1, 8},
{itemEOF, "", 1, 0},
}
lx = lex("listen: apcera.me:80")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "listen", 1, 0},
{itemString, "nats.io:-1", 1, 8},
{itemEOF, "", 1, 0},
}
lx = lex("listen: nats.io:-1")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "listen", 1, 0},
{itemInteger, "-1", 1, 8},
{itemEOF, "", 1, 0},
}
lx = lex("listen: -1")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "listen", 1, 0},
{itemString, ":-1", 1, 8},
{itemEOF, "", 1, 0},
}
lx = lex("listen: :-1")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "listen", 1, 0},
{itemString, ":80", 1, 9},
{itemEOF, "", 1, 0},
}
lx = lex("listen = :80")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "listen", 1, 0},
{itemArrayStart, "", 1, 10},
{itemString, "localhost:4222", 1, 10},
{itemString, "localhost:4333", 1, 26},
{itemArrayEnd, "", 1, 41},
{itemEOF, "", 1, 0},
}
lx = lex("listen = [localhost:4222, localhost:4333]")
expect(t, lx, expectedItems)
}
var arrayOfMaps = `
authorization {
users = [
{user: alice, password: foo}
{user: bob, password: bar}
]
timeout: 0.5
}
`
func TestArrayOfMaps(t *testing.T) {
expectedItems := []item{
{itemKey, "authorization", 2, 1},
{itemMapStart, "", 2, 16},
{itemKey, "users", 3, 5},
{itemArrayStart, "", 3, 14},
{itemMapStart, "", 4, 8},
{itemKey, "user", 4, 8},
{itemString, "alice", 4, 14},
{itemKey, "password", 4, 21},
{itemString, "foo", 4, 31},
{itemMapEnd, "", 4, 35},
{itemMapStart, "", 5, 8},
{itemKey, "user", 5, 8},
{itemString, "bob", 5, 14},
{itemKey, "password", 5, 21},
{itemString, "bar", 5, 31},
{itemMapEnd, "", 5, 35},
{itemArrayEnd, "", 6, 6},
{itemKey, "timeout", 7, 5},
{itemFloat, "0.5", 7, 14},
{itemMapEnd, "", 8, 2},
{itemEOF, "", 9, 0},
}
lx := lex(arrayOfMaps)
expect(t, lx, expectedItems)
}
func TestInclude(t *testing.T) {
expectedItems := []item{
{itemInclude, "users.conf", 1, 9},
{itemEOF, "", 1, 0},
}
lx := lex("include \"users.conf\"")
expect(t, lx, expectedItems)
lx = lex("include 'users.conf'")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemInclude, "users.conf", 1, 8},
{itemEOF, "", 1, 0},
}
lx = lex("include users.conf")
expect(t, lx, expectedItems)
}
func TestMapInclude(t *testing.T) {
expectedItems := []item{
{itemKey, "foo", 1, 0},
{itemMapStart, "", 1, 5},
{itemInclude, "users.conf", 1, 14},
{itemMapEnd, "", 1, 26},
{itemEOF, "", 1, 0},
}
lx := lex("foo { include users.conf }")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemMapStart, "", 1, 5},
{itemInclude, "users.conf", 1, 13},
{itemMapEnd, "", 1, 24},
{itemEOF, "", 1, 0},
}
lx = lex("foo {include users.conf}")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemMapStart, "", 1, 5},
{itemInclude, "users.conf", 1, 15},
{itemMapEnd, "", 1, 28},
{itemEOF, "", 1, 0},
}
lx = lex("foo { include 'users.conf' }")
expect(t, lx, expectedItems)
expectedItems = []item{
{itemKey, "foo", 1, 0},
{itemMapStart, "", 1, 5},
{itemInclude, "users.conf", 1, 15},
{itemMapEnd, "", 1, 27},
{itemEOF, "", 1, 0},
}
lx = lex("foo { include \"users.conf\"}")
expect(t, lx, expectedItems)
}
func TestJSONCompat(t *testing.T) {
for _, test := range []struct {
name string
input string
expected []item
}{
{
name: "should omit initial and final brackets at top level with a single item",
input: `
{
"http_port": 8223
}
`,
expected: []item{
{itemKey, "http_port", 3, 28},
{itemInteger, "8223", 3, 40},
{itemKey, "}", 4, 25},
{itemEOF, "", 0, 0},
},
},
{
name: "should omit trailing commas at top level with two items",
input: `
{
"http_port": 8223,
"port": 4223
}
`,
expected: []item{
{itemKey, "http_port", 3, 28},
{itemInteger, "8223", 3, 40},
{itemKey, "port", 4, 28},
{itemInteger, "4223", 4, 35},
{itemKey, "}", 5, 25},
{itemEOF, "", 0, 0},
},
},
{
name: "should omit trailing commas at top level with multiple items",
input: `
{
"http_port": 8223,
"port": 4223,
"max_payload": "5MB",
"debug": true,
"max_control_line": 1024
}
`,
expected: []item{
{itemKey, "http_port", 3, 28},
{itemInteger, "8223", 3, 40},
{itemKey, "port", 4, 28},
{itemInteger, "4223", 4, 35},
{itemKey, "max_payload", 5, 28},
{itemString, "5MB", 5, 43},
{itemKey, "debug", 6, 28},
{itemBool, "true", 6, 36},
{itemKey, "max_control_line", 7, 28},
{itemInteger, "1024", 7, 47},
{itemKey, "}", 8, 25},
{itemEOF, "", 0, 0},
},
},
{
name: "should support JSON not prettified",
input: `{"http_port": 8224,"port": 4224}
`,
expected: []item{
{itemKey, "http_port", 1, 2},
{itemInteger, "8224", 1, 14},
{itemKey, "port", 1, 20},
{itemInteger, "4224", 1, 27},
{itemEOF, "", 0, 0},
},
},
{
name: "should support JSON not prettified with final bracket after newline",
input: `{"http_port": 8225,"port": 4225
}
`,
expected: []item{
{itemKey, "http_port", 1, 2},
{itemInteger, "8225", 1, 14},
{itemKey, "port", 1, 20},
{itemInteger, "4225", 1, 27},
{itemKey, "}", 2, 25},
{itemEOF, "", 0, 0},
},
},
{
name: "should support uglified JSON with inner blocks",
input: `{"http_port": 8227,"port": 4227,"write_deadline": "1h","cluster": {"port": 6222,"routes": ["nats://127.0.0.1:4222","nats://127.0.0.1:4223","nats://127.0.0.1:4224"]}}
`,
expected: []item{
{itemKey, "http_port", 1, 2},
{itemInteger, "8227", 1, 14},
{itemKey, "port", 1, 20},
{itemInteger, "4227", 1, 27},
{itemKey, "write_deadline", 1, 33},
{itemString, "1h", 1, 51},
{itemKey, "cluster", 1, 56},
{itemMapStart, "", 1, 67},
{itemKey, "port", 1, 68},
{itemInteger, "6222", 1, 75},
{itemKey, "routes", 1, 81},
{itemArrayStart, "", 1, 91},
{itemString, "nats://127.0.0.1:4222", 1, 92},
{itemString, "nats://127.0.0.1:4223", 1, 116},
{itemString, "nats://127.0.0.1:4224", 1, 140},
{itemArrayEnd, "", 1, 163},
{itemMapEnd, "", 1, 164},
{itemKey, "}", 14, 25},
{itemEOF, "", 0, 0},
},
},
{
name: "should support prettified JSON with inner blocks",
input: `
{
"http_port": 8227,
"port": 4227,
"write_deadline": "1h",
"cluster": {
"port": 6222,
"routes": [
"nats://127.0.0.1:4222",
"nats://127.0.0.1:4223",
"nats://127.0.0.1:4224"
]
}
}
`,
expected: []item{
{itemKey, "http_port", 3, 28},
{itemInteger, "8227", 3, 40},
{itemKey, "port", 4, 28},
{itemInteger, "4227", 4, 35},
{itemKey, "write_deadline", 5, 28},
{itemString, "1h", 5, 46},
{itemKey, "cluster", 6, 28},
{itemMapStart, "", 6, 39},
{itemKey, "port", 7, 30},
{itemInteger, "6222", 7, 37},
{itemKey, "routes", 8, 30},
{itemArrayStart, "", 8, 40},
{itemString, "nats://127.0.0.1:4222", 9, 32},
{itemString, "nats://127.0.0.1:4223", 10, 32},
{itemString, "nats://127.0.0.1:4224", 11, 32},
{itemArrayEnd, "", 12, 30},
{itemMapEnd, "", 13, 28},
{itemKey, "}", 14, 25},
{itemEOF, "", 0, 0},
},
},
{
name: "should support JSON with blocks",
input: `{
"jetstream": {
"store_dir": "/tmp/nats"
"max_mem": 1000000,
},
"port": 4222,
"server_name": "nats1"
}
`,
expected: []item{
{itemKey, "jetstream", 2, 28},
{itemMapStart, "", 2, 41},
{itemKey, "store_dir", 3, 30},
{itemString, "/tmp/nats", 3, 43},
{itemKey, "max_mem", 4, 30},
{itemInteger, "1000000", 4, 40},
{itemMapEnd, "", 5, 28},
{itemKey, "port", 6, 28},
{itemInteger, "4222", 6, 35},
{itemKey, "server_name", 7, 28},
{itemString, "nats1", 7, 43},
{itemKey, "}", 8, 25},
{itemEOF, "", 0, 0},
},
},
} {
t.Run(test.name, func(t *testing.T) {
lx := lex(test.input)
expect(t, lx, test.expected)
})
}
}
================================================
FILE: conf/parse.go
================================================
// Copyright 2013-2025 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package conf supports a configuration file format used by gnatsd. It is
// a flexible format that combines the best of traditional
// configuration formats and newer styles such as JSON and YAML.
package conf
// The format supported is less restrictive than today's formats.
// Supports mixed Arrays [], nested Maps {}, multiple comment types (# and //)
// Also supports key value assignments using '=' or ':' or whiteSpace()
// e.g. foo = 2, foo : 2, foo 2
// maps can be assigned with no key separator as well
// semicolons as value terminators in key/value assignments are optional
//
// see parse_test.go for more examples.
import (
"crypto/sha256"
"encoding/json"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"unicode"
)
const _EMPTY_ = ""
type parser struct {
mapping map[string]any
lx *lexer
// The current scoped context, can be array or map
ctx any
// stack of contexts, either map or array/slice stack
ctxs []any
// Keys stack
keys []string
// Keys stack as items
ikeys []item
// The config file path, empty by default.
fp string
// pedantic reports error when configuration is not correct.
pedantic bool
// Tracks environment variable references, to avoid cycles
envVarReferences map[string]bool
}
// Parse will return a map of keys to any, although concrete types
// underly them. The values supported are string, bool, int64, float64, DateTime.
// Arrays and nested Maps are also supported.
func Parse(data string) (map[string]any, error) {
p, err := parse(data, "", false)
if err != nil {
return nil, err
}
return p.mapping, nil
}
// ParseWithChecks is equivalent to Parse but runs in pedantic mode.
func ParseWithChecks(data string) (map[string]any, error) {
p, err := parse(data, "", true)
if err != nil {
return nil, err
}
return p.mapping, nil
}
// ParseFile is a helper to open file, etc. and parse the contents.
func ParseFile(fp string) (map[string]any, error) {
data, err := os.ReadFile(fp)
if err != nil {
return nil, fmt.Errorf("error opening config file: %v", err)
}
p, err := parse(string(data), fp, false)
if err != nil {
return nil, err
}
return p.mapping, nil
}
// ParseFileWithChecks is equivalent to ParseFile but runs in pedantic mode.
func ParseFileWithChecks(fp string) (map[string]any, error) {
data, err := os.ReadFile(fp)
if err != nil {
return nil, err
}
p, err := parse(string(data), fp, true)
if err != nil {
return nil, err
}
return p.mapping, nil
}
// configDigest returns a digest for the parsed config.
func configDigest(m map[string]any) (string, error) {
digest := sha256.New()
e := json.NewEncoder(digest)
if err := e.Encode(m); err != nil {
return _EMPTY_, err
}
return fmt.Sprintf("sha256:%x", digest.Sum(nil)), nil
}
// ParseFileWithChecksDigest returns the processed config and a digest
// that represents the configuration.
func ParseFileWithChecksDigest(fp string) (map[string]any, string, error) {
m, err := ParseFileWithChecks(fp)
if err != nil {
return nil, _EMPTY_, err
}
digest, err := configDigest(m)
if err != nil {
return nil, _EMPTY_, err
}
return m, digest, nil
}
type token struct {
item item
value any
usedVariable bool
sourceFile string
}
func (t *token) MarshalJSON() ([]byte, error) {
return json.Marshal(t.value)
}
func (t *token) Value() any {
return t.value
}
func (t *token) Line() int {
return t.item.line
}
func (t *token) IsUsedVariable() bool {
return t.usedVariable
}
func (t *token) SourceFile() string {
return t.sourceFile
}
func (t *token) Position() int {
return t.item.pos
}
func newParser(data, fp string, pedantic bool) *parser {
return &parser{
mapping: make(map[string]any),
lx: lex(data),
ctxs: make([]any, 0, 4),
keys: make([]string, 0, 4),
ikeys: make([]item, 0, 4),
fp: filepath.Dir(fp),
pedantic: pedantic,
envVarReferences: make(map[string]bool),
}
}
func parse(data, fp string, pedantic bool) (*parser, error) {
p := newParser(data, fp, pedantic)
if err := p.parse(fp); err != nil {
return nil, err
}
return p, nil
}
func parseEnv(data string, parent *parser) (*parser, error) {
p := newParser(data, "", false)
p.envVarReferences = parent.envVarReferences
if err := p.parse(""); err != nil {
return nil, err
}
return p, nil
}
func (p *parser) parse(fp string) error {
p.pushContext(p.mapping)
var prevItem item
for {
it := p.next()
if it.typ == itemEOF {
// Here we allow the final character to be a bracket '}'
// in order to support JSON like configurations.
if prevItem.typ == itemKey && prevItem.val != mapEndString {
return fmt.Errorf("config is invalid (%s:%d:%d)", fp, it.line, it.pos)
}
break
}
prevItem = it
if err := p.processItem(it, fp); err != nil {
return err
}
}
return nil
}
func (p *parser) next() item {
return p.lx.nextItem()
}
func (p *parser) pushContext(ctx any) {
p.ctxs = append(p.ctxs, ctx)
p.ctx = ctx
}
func (p *parser) popContext() any {
if len(p.ctxs) == 0 {
panic("BUG in parser, context stack empty")
}
li := len(p.ctxs) - 1
last := p.ctxs[li]
p.ctxs = p.ctxs[0:li]
p.ctx = p.ctxs[len(p.ctxs)-1]
return last
}
func (p *parser) pushKey(key string) {
p.keys = append(p.keys, key)
}
func (p *parser) popKey() string {
if len(p.keys) == 0 {
panic("BUG in parser, keys stack empty")
}
li := len(p.keys) - 1
last := p.keys[li]
p.keys = p.keys[0:li]
return last
}
func (p *parser) pushItemKey(key item) {
p.ikeys = append(p.ikeys, key)
}
func (p *parser) popItemKey() item {
if len(p.ikeys) == 0 {
panic("BUG in parser, item keys stack empty")
}
li := len(p.ikeys) - 1
last := p.ikeys[li]
p.ikeys = p.ikeys[0:li]
return last
}
func (p *parser) processItem(it item, fp string) error {
setValue := func(it item, v any) {
if p.pedantic {
p.setValue(&token{it, v, false, fp})
} else {
p.setValue(v)
}
}
switch it.typ {
case itemError:
return fmt.Errorf("Parse error on line %d: '%s'", it.line, it.val)
case itemKey:
// Keep track of the keys as items and strings,
// we do this in order to be able to still support
// includes without many breaking changes.
p.pushKey(it.val)
if p.pedantic {
p.pushItemKey(it)
}
case itemMapStart:
newCtx := make(map[string]any)
p.pushContext(newCtx)
case itemMapEnd:
setValue(it, p.popContext())
case itemString:
// FIXME(dlc) sanitize string?
setValue(it, it.val)
case itemInteger:
lastDigit := 0
for _, r := range it.val {
if !unicode.IsDigit(r) && r != '-' {
break
}
lastDigit++
}
numStr := it.val[:lastDigit]
num, err := strconv.ParseInt(numStr, 10, 64)
if err != nil {
if e, ok := err.(*strconv.NumError); ok &&
e.Err == strconv.ErrRange {
return fmt.Errorf("integer '%s' is out of the range", it.val)
}
return fmt.Errorf("expected integer, but got '%s'", it.val)
}
// Process a suffix
suffix := strings.ToLower(strings.TrimSpace(it.val[lastDigit:]))
switch suffix {
case "":
setValue(it, num)
case "k":
setValue(it, num*1000)
case "kb", "ki", "kib":
setValue(it, num*1024)
case "m":
setValue(it, num*1000*1000)
case "mb", "mi", "mib":
setValue(it, num*1024*1024)
case "g":
setValue(it, num*1000*1000*1000)
case "gb", "gi", "gib":
setValue(it, num*1024*1024*1024)
case "t":
setValue(it, num*1000*1000*1000*1000)
case "tb", "ti", "tib":
setValue(it, num*1024*1024*1024*1024)
case "p":
setValue(it, num*1000*1000*1000*1000*1000)
case "pb", "pi", "pib":
setValue(it, num*1024*1024*1024*1024*1024)
case "e":
setValue(it, num*1000*1000*1000*1000*1000*1000)
case "eb", "ei", "eib":
setValue(it, num*1024*1024*1024*1024*1024*1024)
}
case itemFloat:
num, err := strconv.ParseFloat(it.val, 64)
if err != nil {
if e, ok := err.(*strconv.NumError); ok &&
e.Err == strconv.ErrRange {
return fmt.Errorf("float '%s' is out of the range", it.val)
}
return fmt.Errorf("expected float, but got '%s'", it.val)
}
setValue(it, num)
case itemBool:
switch strings.ToLower(it.val) {
case "true", "yes", "on":
setValue(it, true)
case "false", "no", "off":
setValue(it, false)
default:
return fmt.Errorf("expected boolean value, but got '%s'", it.val)
}
case itemDatetime:
dt, err := time.Parse("2006-01-02T15:04:05Z", it.val)
if err != nil {
return fmt.Errorf(
"expected Zulu formatted DateTime, but got '%s'", it.val)
}
setValue(it, dt)
case itemArrayStart:
var array = make([]any, 0)
p.pushContext(array)
case itemArrayEnd:
array := p.ctx
p.popContext()
setValue(it, array)
case itemVariable:
value, found, err := p.lookupVariable(it.val)
if err != nil {
return fmt.Errorf("variable reference for '%s' on line %d could not be parsed: %s",
it.val, it.line, err)
}
if !found {
return fmt.Errorf("variable reference for '%s' on line %d can not be found",
it.val, it.line)
}
if p.pedantic {
switch tk := value.(type) {
case *token:
// Mark the looked up variable as used, and make
// the variable reference become handled as a token.
tk.usedVariable = true
p.setValue(&token{it, tk.Value(), false, fp})
default:
// Special case to add position context to bcrypt references.
p.setValue(&token{it, value, false, fp})
}
} else {
p.setValue(value)
}
case itemInclude:
var (
m map[string]any
err error
)
if p.pedantic {
m, err = ParseFileWithChecks(filepath.Join(p.fp, it.val))
} else {
m, err = ParseFile(filepath.Join(p.fp, it.val))
}
if err != nil {
return fmt.Errorf("error parsing include file '%s', %v", it.val, err)
}
for k, v := range m {
p.pushKey(k)
if p.pedantic {
switch tk := v.(type) {
case *token:
p.pushItemKey(tk.item)
}
}
p.setValue(v)
}
}
return nil
}
// Used to map an environment value into a temporary map to pass to secondary Parse call.
const pkey = "pk"
// We special case raw strings here that are bcrypt'd. This allows us not to force quoting the strings
const bcryptPrefix = "2a$"
// lookupVariable will lookup a variable reference. It will use block scoping on keys
// it has seen before, with the top level scoping being the environment variables. We
// ignore array contexts and only process the map contexts..
//
// Returns true for ok if it finds something, similar to map.
func (p *parser) lookupVariable(varReference string) (any, bool, error) {
// Do special check to see if it is a raw bcrypt string.
if strings.HasPrefix(varReference, bcryptPrefix) {
return "$" + varReference, true, nil
}
// Loop through contexts currently on the stack.
for i := len(p.ctxs) - 1; i >= 0; i-- {
ctx := p.ctxs[i]
// Process if it is a map context
if m, ok := ctx.(map[string]any); ok {
if v, ok := m[varReference]; ok {
return v, ok, nil
}
}
}
// If we are here, we have exhausted our context maps and still not found anything.
// Detect reference cycles
if p.envVarReferences[varReference] {
return nil, false, fmt.Errorf("variable reference cycle for '%s'", varReference)
}
p.envVarReferences[varReference] = true
defer delete(p.envVarReferences, varReference)
// Parse from the environment
if vStr, ok := os.LookupEnv(varReference); ok {
// Everything we get here will be a string value, so we need to process as a parser would.
if subp, err := parseEnv(fmt.Sprintf("%s=%s", pkey, vStr), p); err == nil {
v, ok := subp.mapping[pkey]
return v, ok, nil
} else {
return nil, false, err
}
}
return nil, false, nil
}
func (p *parser) setValue(val any) {
// Test to see if we are on an array or a map
// Array processing
if ctx, ok := p.ctx.([]any); ok {
p.ctx = append(ctx, val)
p.ctxs[len(p.ctxs)-1] = p.ctx
}
// Map processing
if ctx, ok := p.ctx.(map[string]any); ok {
key := p.popKey()
if p.pedantic {
// Change the position to the beginning of the key
// since more useful when reporting errors.
switch v := val.(type) {
case *token:
it := p.popItemKey()
v.item.pos = it.pos
v.item.line = it.line
ctx[key] = v
}
} else {
// FIXME(dlc), make sure to error if redefining same key?
ctx[key] = val
}
}
}
================================================
FILE: conf/parse_test.go
================================================
package conf
import (
"bytes"
"encoding/json"
"fmt"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
"time"
)
// Test to make sure we get what we expect.
func test(t *testing.T, data string, ex map[string]any) {
t.Helper()
m, err := Parse(data)
if err != nil {
t.Fatalf("Received err: %v\n", err)
}
if m == nil {
t.Fatal("Received nil map")
}
if !reflect.DeepEqual(m, ex) {
t.Fatalf("Not Equal:\nReceived: '%+v'\nExpected: '%+v'\n", m, ex)
}
// Also test ParseWithChecks
n, err := ParseWithChecks(data)
if err != nil {
t.Fatalf("Received err: %v\n", err)
}
if n == nil {
t.Fatal("Received nil map")
}
// Compare with the original results.
a, err := json.Marshal(m)
if err != nil {
t.Fatal(err)
}
b, err := json.Marshal(n)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(b, a) {
t.Fatalf("Not Equal:\nReceived: '%+v'\nExpected: '%+v'\n", string(a), string(b))
}
}
func TestSimpleTopLevel(t *testing.T) {
ex := map[string]any{
"foo": "1",
"bar": float64(2.2),
"baz": true,
"boo": int64(22),
}
test(t, "foo='1'; bar=2.2; baz=true; boo=22", ex)
}
func TestBools(t *testing.T) {
ex := map[string]any{
"foo": true,
}
test(t, "foo=true", ex)
test(t, "foo=TRUE", ex)
test(t, "foo=true", ex)
test(t, "foo=yes", ex)
test(t, "foo=on", ex)
}
var varSample = `
index = 22
foo = $index
`
func TestSimpleVariable(t *testing.T) {
ex := map[string]any{
"index": int64(22),
"foo": int64(22),
}
test(t, varSample, ex)
}
var varNestedSample = `
index = 22
nest {
index = 11
foo = $index
}
bar = $index
`
func TestNestedVariable(t *testing.T) {
ex := map[string]any{
"index": int64(22),
"nest": map[string]any{
"index": int64(11),
"foo": int64(11),
},
"bar": int64(22),
}
test(t, varNestedSample, ex)
}
func TestMissingVariable(t *testing.T) {
_, err := Parse("foo=$index")
if err == nil {
t.Fatalf("Expected an error for a missing variable, got none")
}
if !strings.HasPrefix(err.Error(), "variable reference") {
t.Fatalf("Wanted a variable reference err, got %q\n", err)
}
}
func TestEnvVariable(t *testing.T) {
ex := map[string]any{
"foo": int64(22),
}
evar := "__UNIQ22__"
os.Setenv(evar, "22")
defer os.Unsetenv(evar)
test(t, fmt.Sprintf("foo = $%s", evar), ex)
}
func TestEnvVariableString(t *testing.T) {
ex := map[string]any{
"foo": "xyz",
}
evar := "__UNIQ22__"
os.Setenv(evar, "xyz")
defer os.Unsetenv(evar)
test(t, fmt.Sprintf("foo = $%s", evar), ex)
}
func TestEnvVariableStringStartingWithNumber(t *testing.T) {
evar := "__UNIQ22__"
os.Setenv(evar, "3xyz")
defer os.Unsetenv(evar)
_, err := Parse("foo = $%s")
if err == nil {
t.Fatalf("Expected err not being able to process string: %v\n", err)
}
}
func TestEnvVariableStringStartingWithNumberAndSizeUnit(t *testing.T) {
ex := map[string]any{
"foo": "3Gyz",
}
evar := "__UNIQ22__"
os.Setenv(evar, "3Gyz")
defer os.Unsetenv(evar)
test(t, fmt.Sprintf("foo = $%s", evar), ex)
}
func TestEnvVariableStringStartingWithNumberUsingQuotes(t *testing.T) {
ex := map[string]any{
"foo": "3xyz",
}
evar := "__UNIQ22__"
os.Setenv(evar, "'3xyz'")
defer os.Unsetenv(evar)
test(t, fmt.Sprintf("foo = $%s", evar), ex)
}
func TestBcryptVariable(t *testing.T) {
ex := map[string]any{
"password": "$2a$11$ooo",
}
test(t, "password: $2a$11$ooo", ex)
}
var easynum = `
k = 8k
kb = 4kb
ki = 3ki
kib = 4ki
m = 1m
mb = 2MB
mi = 2Mi
mib = 64MiB
g = 2g
gb = 22GB
gi = 22Gi
gib = 22GiB
tb = 22TB
ti = 22Ti
tib = 22TiB
pb = 22PB
pi = 22Pi
pib = 22PiB
`
func TestConvenientNumbers(t *testing.T) {
ex := map[string]any{
"k": int64(8 * 1000),
"kb": int64(4 * 1024),
"ki": int64(3 * 1024),
"kib": int64(4 * 1024),
"m": int64(1000 * 1000),
"mb": int64(2 * 1024 * 1024),
"mi": int64(2 * 1024 * 1024),
"mib": int64(64 * 1024 * 1024),
"g": int64(2 * 1000 * 1000 * 1000),
"gb": int64(22 * 1024 * 1024 * 1024),
"gi": int64(22 * 1024 * 1024 * 1024),
"gib": int64(22 * 1024 * 1024 * 1024),
"tb": int64(22 * 1024 * 1024 * 1024 * 1024),
"ti": int64(22 * 1024 * 1024 * 1024 * 1024),
"tib": int64(22 * 1024 * 1024 * 1024 * 1024),
"pb": int64(22 * 1024 * 1024 * 1024 * 1024 * 1024),
"pi": int64(22 * 1024 * 1024 * 1024 * 1024 * 1024),
"pib": int64(22 * 1024 * 1024 * 1024 * 1024 * 1024),
}
test(t, easynum, ex)
}
func TestParseFileWithChecksDigestPreservesConfigKeyUsedAsVariable(t *testing.T) {
confFile := filepath.Join(t.TempDir(), "nats.conf")
if err := os.WriteFile(confFile, []byte(`
port = 4222
monitor_port = $port
`), 0666); err != nil {
t.Fatal(err)
}
m, _, err := ParseFileWithChecksDigest(confFile)
if err != nil {
t.Fatal(err)
}
if _, ok := m["port"]; !ok {
t.Fatal("expected config key used as a variable reference to be preserved")
}
}
var sample1 = `
foo {
host {
ip = '127.0.0.1'
port = 4242
}
servers = [ "a.com", "b.com", "c.com"]
}
`
func TestSample1(t *testing.T) {
ex := map[string]any{
"foo": map[string]any{
"host": map[string]any{
"ip": "127.0.0.1",
"port": int64(4242),
},
"servers": []any{"a.com", "b.com", "c.com"},
},
}
test(t, sample1, ex)
}
var cluster = `
cluster {
port: 4244
authorization {
user: route_user
password: top_secret
timeout: 1
}
# Routes are actively solicited and connected to from this server.
# Other servers can connect to us if they supply the correct credentials
# in their routes definitions from above.
// Test both styles of comments
routes = [
nats-route://foo:bar@apcera.me:4245
nats-route://foo:bar@apcera.me:4246
]
}
`
func TestSample2(t *testing.T) {
ex := map[string]any{
"cluster": map[string]any{
"port": int64(4244),
"authorization": map[string]any{
"user": "route_user",
"password": "top_secret",
"timeout": int64(1),
},
"routes": []any{
"nats-route://foo:bar@apcera.me:4245",
"nats-route://foo:bar@apcera.me:4246",
},
},
}
test(t, cluster, ex)
}
var sample3 = `
foo {
expr = '(true == "false")'
text = 'This is a multi-line
text block.'
}
`
func TestSample3(t *testing.T) {
ex := map[string]any{
"foo": map[string]any{
"expr": "(true == \"false\")",
"text": "This is a multi-line\ntext block.",
},
}
test(t, sample3, ex)
}
var sample4 = `
array [
{ abc: 123 }
{ xyz: "word" }
]
`
func TestSample4(t *testing.T) {
ex := map[string]any{
"array": []any{
map[string]any{"abc": int64(123)},
map[string]any{"xyz": "word"},
},
}
test(t, sample4, ex)
}
var sample5 = `
now = 2016-05-04T18:53:41Z
gmt = false
`
func TestSample5(t *testing.T) {
dt, _ := time.Parse("2006-01-02T15:04:05Z", "2016-05-04T18:53:41Z")
ex := map[string]any{
"now": dt,
"gmt": false,
}
test(t, sample5, ex)
}
func TestIncludes(t *testing.T) {
ex := map[string]any{
"listen": "127.0.0.1:4222",
"authorization": map[string]any{
"ALICE_PASS": "$2a$10$UHR6GhotWhpLsKtVP0/i6.Nh9.fuY73cWjLoJjb2sKT8KISBcUW5q",
"BOB_PASS": "$2a$11$dZM98SpGeI7dCFFGSpt.JObQcix8YHml4TBUZoge9R1uxnMIln5ly",
"users": []any{
map[string]any{
"user": "alice",
"password": "$2a$10$UHR6GhotWhpLsKtVP0/i6.Nh9.fuY73cWjLoJjb2sKT8KISBcUW5q"},
map[string]any{
"user": "bob",
"password": "$2a$11$dZM98SpGeI7dCFFGSpt.JObQcix8YHml4TBUZoge9R1uxnMIln5ly"},
},
"timeout": float64(0.5),
},
}
m, err := ParseFile("simple.conf")
if err != nil {
t.Fatalf("Received err: %v\n", err)
}
if m == nil {
t.Fatal("Received nil map")
}
if !reflect.DeepEqual(m, ex) {
t.Fatalf("Not Equal:\nReceived: '%+v'\nExpected: '%+v'\n", m, ex)
}
}
var varIncludedVariablesSample = `
authorization {
include "./includes/passwords.conf"
CAROL_PASS: foo
users = [
{user: alice, password: $ALICE_PASS}
{user: bob, password: $BOB_PASS}
{user: carol, password: $CAROL_PASS}
]
}
`
func TestIncludeVariablesWithChecks(t *testing.T) {
p, err := parse(varIncludedVariablesSample, "", true)
if err != nil {
t.Fatalf("Received err: %v\n", err)
}
key := "authorization"
m, ok := p.mapping[key]
if !ok {
t.Errorf("Expected %q to be in the config", key)
}
expectKeyVal := func(t *testing.T, m any, expectedKey string, expectedVal string, expectedLine, expectedPos int) {
t.Helper()
tk := m.(*token)
v := tk.Value()
vv := v.(map[string]any)
value, ok := vv[expectedKey]
if !ok {
t.Errorf("Expected key %q", expectedKey)
}
tk, ok = value.(*token)
if !ok {
t.Fatalf("Expected token %v", value)
}
if tk.Line() != expectedLine {
t.Errorf("Expected token to be at line %d, got: %d", expectedLine, tk.Line())
}
if tk.Position() != expectedPos {
t.Errorf("Expected token to be at position %d, got: %d", expectedPos, tk.Position())
}
v = tk.Value()
if v != expectedVal {
t.Errorf("Expected %q, got: %s", expectedVal, v)
}
}
expectKeyVal(t, m, "ALICE_PASS", "$2a$10$UHR6GhotWhpLsKtVP0/i6.Nh9.fuY73cWjLoJjb2sKT8KISBcUW5q", 2, 1)
expectKeyVal(t, m, "BOB_PASS", "$2a$11$dZM98SpGeI7dCFFGSpt.JObQcix8YHml4TBUZoge9R1uxnMIln5ly", 3, 1)
expectKeyVal(t, m, "CAROL_PASS", "foo", 6, 3)
}
func TestParserNoInfiniteLoop(t *testing.T) {
for _, test := range []string{`A@@Føøøø?˛ø:{øøøø˙˙`, `include "9/�`} {
if _, err := Parse(test); err == nil {
t.Fatal("expected an error")
} else if !strings.Contains(err.Error(), "Unexpected EOF") {
t.Fatal("expected unexpected eof error")
}
}
}
func TestParseWithNoValuesAreInvalid(t *testing.T) {
for _, test := range []struct {
name string
conf string
err string
}{
{
"invalid key without values",
`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
"config is invalid (:1:41)",
},
{
"invalid untrimmed key without values",
` aaaaaaaaaaaaaaaaaaaaaaaaaaa`,
"config is invalid (:1:41)",
},
{
"invalid untrimmed key without values",
` aaaaaaaaaaaaaaaaaaaaaaaaaaa `,
"config is invalid (:1:41)",
},
{
"invalid keys after comments",
`
# with comments and no spaces to create key values
# is also an invalid config.
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
`,
"config is invalid (:5:25)",
},
{
"comma separated without values are invalid",
`
a,a,a,a,a,a,a,a,a,a,a
`,
"config is invalid (:3:25)",
},
} {
t.Run(test.name, func(t *testing.T) {
if _, err := parse(test.conf, "", true); err == nil {
t.Error("expected an error")
} else if !strings.Contains(err.Error(), test.err) {
t.Errorf("expected invalid conf error, got: %v", err)
}
})
}
}
func TestParseWithNoValuesEmptyConfigsAreValid(t *testing.T) {
for _, test := range []struct {
name string
conf string
}{
{
"empty conf",
"",
},
{
"empty conf with line breaks",
`
`,
},
{
"just comments with no values",
`
# just comments with no values
# is still valid.
`,
},
} {
t.Run(test.name, func(t *testing.T) {
if _, err := parse(test.conf, "", true); err != nil {
t.Errorf("unexpected error: %v", err)
}
})
}
}
func TestParseWithTrailingBracketsAreValid(t *testing.T) {
for _, test := range []struct {
name string
conf string
}{
{
"empty conf",
"{}",
},
{
"just comments with no values",
`
{
# comments in the body
}
`,
},
{
// trailing brackets accidentally can become keys,
// this is valid since needed to support JSON like configs..
"trailing brackets after config",
`
accounts { users = [{}]}
}
`,
},
{
"wrapped in brackets",
`{
accounts { users = [{}]}
}
`,
},
} {
t.Run(test.name, func(t *testing.T) {
if _, err := parse(test.conf, "", true); err != nil {
t.Errorf("unexpected error: %v", err)
}
})
}
}
func TestParseWithNoValuesIncludes(t *testing.T) {
for _, test := range []struct {
input string
includes map[string]string
err string
linepos string
}{
{
`# includes
accounts {
foo { include 'foo.conf'}
bar { users = [{user = "bar"}] }
quux { include 'quux.conf'}
}
`,
map[string]string{
"foo.conf": ``,
"quux.conf": `?????????????`,
},
"error parsing include file 'quux.conf', config is invalid",
"quux.conf:1:1",
},
{
`# includes
accounts {
foo { include 'foo.conf'}
bar { include 'bar.conf'}
quux { include 'quux.conf'}
}
`,
map[string]string{
"foo.conf": ``, // Empty configs are ok
"bar.conf": `AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`,
"quux.conf": `
# just some comments,
# and no key values also ok.
`,
},
"error parsing include file 'bar.conf', config is invalid",
"bar.conf:1:34",
},
} {
t.Run("", func(t *testing.T) {
sdir := t.TempDir()
f, err := os.CreateTemp(sdir, "nats.conf-")
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(f.Name(), []byte(test.input), 066); err != nil {
t.Error(err)
}
if test.includes != nil {
for includeFile, contents := range test.includes {
inf, err := os.Create(filepath.Join(sdir, includeFile))
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(inf.Name(), []byte(contents), 066); err != nil {
t.Error(err)
}
}
}
if _, err := parse(test.input, f.Name(), true); err == nil {
t.Error("expected an error")
} else if !strings.Contains(err.Error(), test.err) || !strings.Contains(err.Error(), test.linepos) {
t.Errorf("expected invalid conf error, got: %v", err)
}
})
}
}
func TestJSONParseCompat(t *testing.T) {
for _, test := range []struct {
name string
input string
includes map[string]string
expected map[string]any
}{
{
"JSON with nested blocks",
`
{
"http_port": 8227,
"port": 4227,
"write_deadline": "1h",
"cluster": {
"port": 6222,
"routes": [
"nats://127.0.0.1:4222",
"nats://127.0.0.1:4223",
"nats://127.0.0.1:4224"
]
}
}
`,
nil,
map[string]any{
"http_port": int64(8227),
"port": int64(4227),
"write_deadline": "1h",
"cluster": map[string]any{
"port": int64(6222),
"routes": []any{
"nats://127.0.0.1:4222",
"nats://127.0.0.1:4223",
"nats://127.0.0.1:4224",
},
},
},
},
{
"JSON with nested blocks",
`{
"jetstream": {
"store_dir": "/tmp/nats"
"max_mem": 1000000,
},
"port": 4222,
"server_name": "nats1"
}
`,
nil,
map[string]any{
"jetstream": map[string]any{
"store_dir": "/tmp/nats",
"max_mem": int64(1_000_000),
},
"port": int64(4222),
"server_name": "nats1",
},
},
{
"JSON empty object in one line",
`{}`,
nil,
map[string]any{},
},
{
"JSON empty object with line breaks",
`
{
}
`,
nil,
map[string]any{},
},
{
"JSON includes",
`
accounts {
foo { include 'foo.json' }
bar { include 'bar.json' }
quux { include 'quux.json' }
}
`,
map[string]string{
"foo.json": `{ "users": [ {"user": "foo"} ] }`,
"bar.json": `{
"users": [ {"user": "bar"} ]
}`,
"quux.json": `{}`,
},
map[string]any{
"accounts": map[string]any{
"foo": map[string]any{
"users": []any{
map[string]any{
"user": "foo",
},
},
},
"bar": map[string]any{
"users": []any{
map[string]any{
"user": "bar",
},
},
},
"quux": map[string]any{},
},
},
},
} {
t.Run(test.name, func(t *testing.T) {
sdir := t.TempDir()
f, err := os.CreateTemp(sdir, "nats.conf-")
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(f.Name(), []byte(test.input), 066); err != nil {
t.Error(err)
}
if test.includes != nil {
for includeFile, contents := range test.includes {
inf, err := os.Create(filepath.Join(sdir, includeFile))
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(inf.Name(), []byte(contents), 066); err != nil {
t.Error(err)
}
}
}
m, err := ParseFile(f.Name())
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
if !reflect.DeepEqual(m, test.expected) {
t.Fatalf("Not Equal:\nReceived: '%+v'\nExpected: '%+v'\n", m, test.expected)
}
})
}
}
func TestBlocks(t *testing.T) {
for _, test := range []struct {
name string
input string
expected map[string]any
err string
linepos string
}{
{
"inline block",
`{ listen: 0.0.0.0:4222 }`,
map[string]any{
"listen": "0.0.0.0:4222",
},
"", "",
},
{
"newline block",
`{
listen: 0.0.0.0:4222
}`,
map[string]any{
"listen": "0.0.0.0:4222",
},
"", "",
},
{
"newline block with trailing comment",
`
{
listen: 0.0.0.0:4222
}
# wibble
`,
map[string]any{
"listen": "0.0.0.0:4222",
},
"", "",
},
{
"nested newline blocks with trailing comment",
`
{
{
listen: 0.0.0.0:4222 // random comment
}
# wibble1
}
# wibble2
`,
map[string]any{
"listen": "0.0.0.0:4222",
},
"", "",
},
{
"top line values in block scope",
`
{
"debug": False
"prof_port": 8221
"server_name": "aws-useast2-natscj1-1"
}
`,
map[string]any{
"debug": false,
"prof_port": int64(8221),
"server_name": "aws-useast2-natscj1-1",
},
"", "",
},
{
"comment in block scope after value parse",
`
{
"debug": False
"server_name": "gcp-asianortheast3-natscj1-1"
# Profile port specification.
"prof_port": 8221
}
`,
map[string]any{
"debug": false,
"prof_port": int64(8221),
"server_name": "gcp-asianortheast3-natscj1-1",
},
"", "",
},
} {
t.Run(test.name, func(t *testing.T) {
f, err := os.CreateTemp(t.TempDir(), "nats.conf-")
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(f.Name(), []byte(test.input), 066); err != nil {
t.Error(err)
}
if m, err := ParseFile(f.Name()); err == nil {
if !reflect.DeepEqual(m, test.expected) {
t.Fatalf("Not Equal:\nReceived: '%+v'\nExpected: '%+v'\n", m, test.expected)
}
} else if !strings.Contains(err.Error(), test.err) || !strings.Contains(err.Error(), test.linepos) {
t.Errorf("expected invalid conf error, got: %v", err)
} else if err != nil {
t.Error(err)
}
})
}
}
func TestParseDigest(t *testing.T) {
for _, test := range []struct {
input string
includes map[string]string
digest string
}{
{
`foo = bar`,
nil,
"sha256:226e49e13d16e5e8aa0d62e58cd63361bf097d3e2b2444aa3044334628a2e8de",
},
{
`# Comments and whitespace have no effect
foo = bar
`,
nil,
"sha256:226e49e13d16e5e8aa0d62e58cd63361bf097d3e2b2444aa3044334628a2e8de",
},
{
`# Syntax changes have no effect
'foo': 'bar'
`,
nil,
"sha256:226e49e13d16e5e8aa0d62e58cd63361bf097d3e2b2444aa3044334628a2e8de",
},
{
`# Syntax changes have no effect
{ 'foo': 'bar' }
`,
nil,
"sha256:226e49e13d16e5e8aa0d62e58cd63361bf097d3e2b2444aa3044334628a2e8de",
},
{
`# substitutions
BAR_USERS = { users = [ {user = "bar"} ]}
hello = 'world'
accounts {
QUUX_USERS = [ { user: quux }]
bar = $BAR_USERS
quux = { users = $QUUX_USERS }
}
very { nested { env { VAR = 'NESTED', quux = $VAR }}}
`,
nil,
"sha256:bddb282343249c26d3edcef9bfaa9d2711505fc67210380e871405ba394a9186",
},
{
`# substitutions, same as previous one without env vars.
hello = 'world'
accounts {
bar = { users = [ { user = "bar" } ]}
quux = { users = [ { user: quux } ]}
}
very { nested { env { quux = 'NESTED' }}}
`,
nil,
"sha256:34f8faf3f269fe7509edc4742f20c8c4a7ad51fe21f8b361764314b533ac3ab5",
},
{
`# substitutions
BAR_USERS = { users = [ {user = "foo"} ]}
bar = $BAR_USERS
accounts {
users = $BAR_USERS
}
`,
nil,
"sha256:b0e2ba0b8ec2cb75681b5c5d61789cda0c9942c2f9fe16cdb7f6703364485360",
},
{
`# substitutions
bar = { users = [ {user = "foo"} ]}
accounts {
users = { users = [ {user = "foo"} ]}
}
`,
nil,
"sha256:f5d943b4ed22b80c6199203f8a7eaa8eb68ef7b2d46ef6b1b26f05e21f8beb13",
},
{
`# includes
accounts {
foo { include 'foo.conf'}
bar { users = [{user = "bar"}] }
quux { include 'quux.conf'}
}
`,
map[string]string{
"foo.conf": ` users = [{user = "foo"}]`,
"quux.conf": ` users = [{user = "quux"}]`,
},
"sha256:e72d70c91b64b0f880f86decb95ec2600cbdcf8bdcd2355fce5ebc54a84a77e9",
},
{
`# includes
accounts {
foo { include 'foo.conf'}
bar { include 'bar.conf'}
quux { include 'quux.conf'}
}
`,
map[string]string{
"foo.conf": ` users = [{user = "foo"}]`,
"bar.conf": ` users = [{user = "bar"}]`,
"quux.conf": ` users = [{user = "quux"}]`,
},
"sha256:e72d70c91b64b0f880f86decb95ec2600cbdcf8bdcd2355fce5ebc54a84a77e9",
},
} {
t.Run("", func(t *testing.T) {
sdir := t.TempDir()
f, err := os.CreateTemp(sdir, "nats.conf-")
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(f.Name(), []byte(test.input), 066); err != nil {
t.Error(err)
}
if test.includes != nil {
for includeFile, contents := range test.includes {
inf, err := os.Create(filepath.Join(sdir, includeFile))
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(inf.Name(), []byte(contents), 066); err != nil {
t.Error(err)
}
}
}
_, digest, err := ParseFileWithChecksDigest(f.Name())
if err != nil {
t.Fatal(err)
}
if digest != test.digest {
t.Errorf("\ngot: %s\nexpected: %s", digest, test.digest)
}
})
}
}
================================================
FILE: doc/README.md
================================================
# Architecture Decision Records
The NATS ADR documents have moved to their [own repository](https://github.com/nats-io/nats-architecture-and-design/)
================================================
FILE: docker/Dockerfile.nightly
================================================
FROM --platform=$BUILDPLATFORM golang:alpine AS builder
ARG VERSION="nightly"
ARG GIT_COMMIT
ARG TARGETOS
ARG TARGETARCH
ENV GOOS=$TARGETOS \
GOARCH=$TARGETARCH \
GO111MODULE=on \
CGO_ENABLED=0
RUN apk add --no-cache ca-certificates
RUN update-ca-certificates
WORKDIR /src
RUN mkdir -p /src/out/$GOOS/$GOARCH
COPY ./nats-server/ /src/nats-server/
COPY ./nsc/ /src/nsc/
COPY ./natscli/ /src/natscli/
RUN cd /src/nats-server && go build -trimpath \
-ldflags "-w -X server.serverVersion=${VERSION},server.gitCommit=${GIT_COMMIT}" \
-o /src/out/$TARGETOS/$TARGETARCH/nats-server .
RUN cd /src/natscli && go build -trimpath \
-ldflags "-w -X main.version=${VERSION}" \
-o /src/out/$TARGETOS/$TARGETARCH/nats ./nats
RUN cd /src/nsc && go build -trimpath \
-o /src/out/$TARGETOS/$TARGETARCH/nsc .
FROM --platform=$TARGETPLATFORM alpine:latest
ARG TARGETOS
ARG TARGETARCH
COPY ./nats-server/docker/nats-server.conf /nats/conf/nats-server.conf
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /src/out/$TARGETOS/$TARGETARCH/nats-server /bin/nats-server
COPY --from=builder /src/out/$TARGETOS/$TARGETARCH/nats /bin/nats
COPY --from=builder /src/out/$TARGETOS/$TARGETARCH/nsc /bin/nsc
EXPOSE 4222 8222 6222 5222
ENTRYPOINT ["/bin/nats-server"]
CMD ["-c", "/nats/conf/nats-server.conf"]
================================================
FILE: go.mod
================================================
module github.com/nats-io/nats-server/v2
go 1.25.0
toolchain go1.25.8
require (
github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op
github.com/google/go-tpm v0.9.8
github.com/klauspost/compress v1.18.4
github.com/nats-io/jwt/v2 v2.8.1
github.com/nats-io/nats.go v1.49.0
github.com/nats-io/nkeys v0.4.15
github.com/nats-io/nuid v1.0.1
golang.org/x/crypto v0.49.0
golang.org/x/sys v0.42.0
golang.org/x/time v0.15.0
)
// We don't usually pin non-tagged commits but so far no release has
// been made that includes https://github.com/minio/highwayhash/pull/29.
// This will be updated if a new tag covers this in the future.
require github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76
================================================
FILE: go.sum
================================================
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/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.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
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.1 h1:V0xpGuD/N8Mi+fQNDynXohVvp7ZztevW5io8CUWlPmU=
github.com/nats-io/jwt/v2 v2.8.1/go.mod h1:nWnOEEiVMiKHQpnAy4eXlizVEtSfzacZ1Q43LIRavZg=
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/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.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.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=
================================================
FILE: internal/antithesis/noop.go
================================================
// Copyright 2022-2024 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file is used iff the `enable_antithesis_sdk` build tag is not present
//go:build !enable_antithesis_sdk
package antithesis
import (
"testing"
)
// AssertUnreachable this implementation is a NOOP
func AssertUnreachable(_ testing.TB, _ string, _ map[string]any) {}
// Assert this implementation is a NOOP
func Assert(_ testing.TB, _ bool, _ string, _ map[string]any) {}
================================================
FILE: internal/antithesis/test_assert.go
================================================
// Copyright 2022-2024 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file is used iff the `enable_antithesis_sdk` build tag is present
//go:build enable_antithesis_sdk
package antithesis
import (
"encoding/json"
"fmt"
"runtime/debug"
"testing"
"github.com/antithesishq/antithesis-sdk-go/assert"
)
// This file provides assertions utility functions suitable for use in tests.
// It is a thin wrapper around the Antithesis SDK.
//
// Notice that unlike other assertions libraries, a violation does not halt execution or fail the test.
// The effects of violating an assertion, are:
// 1. Print the violation message, prefixed by the test name in which it happened
// 2. Print the stack for the calling goroutine so each failed test has a clear trace of the failure
// 3. Invoke the underlying Antithesis assertion
//
// N.B. Enabling this module outside for tests running outside of Antithesis will enable 1 and 2 above, but not 3.
// therefore it can be useful to output additional test failure details when running tests locally or in CI.
// AssertUnreachable is used to flag code branches that should not get invoked ever.
// Example:
//
// pubAck, err := js.Publish(...)
//
// if err != nil {
// antithesis.AssertUnreachable(t, "Publish failed", map[string]any{"error": err.Error()})
// t.Fatalf("Publish failed with error: %s", err)
// }
func AssertUnreachable(t testing.TB, message string, details map[string]any) {
// Always print a message
fmt.Printf("{*} [%s] Assert Unreachable violation: %s\n", t.Name(), message)
if details != nil && len(details) > 0 {
fmt.Printf("{*} Details:\n")
jsonDetails, err := json.MarshalIndent(details, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(jsonDetails))
}
// Always print the stack trace
fmt.Printf("{*} Stack trace:\n")
debug.PrintStack()
// N.B. as of today, message (as-is) is the unique identifier of the event
// Therefore this will de-duplicate the same assertion failing in 2 different tests
// But not the same assertion failing at 2 different lines of the same test
messageWithTestName := fmt.Sprintf("[%s] %s", t.Name(), message)
// Fire assertion violation event (if Antithesis is enabled)
assert.Unreachable(messageWithTestName, details)
}
// Assert is used to check that some given condition is always true,
// Example:
//
// antithesis.Assert(t, sequence > lastSequence, "Non-monotonic stream sequence number", map[string]any{
// "stream": streamName,
// "connection_id": nc.Id(),
// "sequence": sequence,
// "lastSequence": lastSequence,
// })
func Assert(t testing.TB, condition bool, message string, details map[string]any) {
// Condition is true, nothing to do
if condition {
return
}
// Always print a message
fmt.Printf("{*} [%s] Assert violation: %s\n", t.Name(), message)
if details != nil && len(details) > 0 {
fmt.Printf("{*} Details:\n")
jsonDetails, err := json.MarshalIndent(details, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(jsonDetails))
}
// Always print the stack trace
fmt.Printf("{*} Stack trace:\n")
debug.PrintStack()
// N.B. as of today, message (as-is) is the unique identifier of the event
// Therefore this will de-duplicate the same assertion failing in 2 different tests
// But not the same assertion failing at 2 different lines of the same test
messageWithTestName := fmt.Sprintf("[%s] %s", t.Name(), message)
// Fire assertion violation event (if Antithesis is enabled)
assert.AlwaysOrUnreachable(false, messageWithTestName, details)
}
================================================
FILE: internal/fastrand/LICENSE
================================================
Copyright (c) 2011 The LevelDB-Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: internal/fastrand/fastrand.go
================================================
// Copyright 2020-2023 The LevelDB-Go, Pebble and NATS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
package fastrand
import _ "unsafe" // required by go:linkname
// Uint32 returns a lock free uint32 value.
//
//go:linkname Uint32 runtime.fastrand
func Uint32() uint32
// Uint32n returns a lock free uint32 value in the interval [0, n).
//
//go:linkname Uint32n runtime.fastrandn
func Uint32n(n uint32) uint32
// Uint64 returns a lock free uint64 value.
func Uint64() uint64 {
v := uint64(Uint32())
return v<<32 | uint64(Uint32())
}
================================================
FILE: internal/fastrand/fastrand_test.go
================================================
// Copyright 2020-23 The LevelDB-Go, Pebble and NATS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
package fastrand
import (
"math/rand"
"sync"
"testing"
"time"
)
type defaultRand struct {
mu sync.Mutex
src rand.Source64
}
func newDefaultRand() *defaultRand {
r := &defaultRand{
src: rand.New(rand.NewSource(time.Now().UnixNano())),
}
return r
}
func (r *defaultRand) Uint32() uint32 {
r.mu.Lock()
i := uint32(r.src.Uint64())
r.mu.Unlock()
return i
}
func (r *defaultRand) Uint64() uint64 {
r.mu.Lock()
i := uint64(r.src.Uint64())
r.mu.Unlock()
return i
}
func BenchmarkFastRand32(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Uint32()
}
})
}
func BenchmarkFastRand64(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Uint64()
}
})
}
func BenchmarkDefaultRand32(b *testing.B) {
r := newDefaultRand()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
r.Uint32()
}
})
}
func BenchmarkDefaultRand64(b *testing.B) {
r := newDefaultRand()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
r.Uint64()
}
})
}
================================================
FILE: internal/ldap/dn.go
================================================
// Copyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)
// Portions copyright (c) 2015-2016 go-ldap Authors
package ldap
import (
"bytes"
"crypto/x509/pkix"
"encoding/asn1"
enchex "encoding/hex"
"errors"
"fmt"
"strings"
)
var attributeTypeNames = map[string]string{
"2.5.4.3": "CN",
"2.5.4.5": "SERIALNUMBER",
"2.5.4.6": "C",
"2.5.4.7": "L",
"2.5.4.8": "ST",
"2.5.4.9": "STREET",
"2.5.4.10": "O",
"2.5.4.11": "OU",
"2.5.4.17": "POSTALCODE",
// FIXME: Add others.
"0.9.2342.19200300.100.1.25": "DC",
}
// AttributeTypeAndValue represents an attributeTypeAndValue from https://tools.ietf.org/html/rfc4514
type AttributeTypeAndValue struct {
// Type is the attribute type
Type string
// Value is the attribute value
Value string
}
// RelativeDN represents a relativeDistinguishedName from https://tools.ietf.org/html/rfc4514
type RelativeDN struct {
Attributes []*AttributeTypeAndValue
}
// DN represents a distinguishedName from https://tools.ietf.org/html/rfc4514
type DN struct {
RDNs []*RelativeDN
}
// FromCertSubject takes a pkix.Name from a cert and returns a DN
// that uses the same set. Does not support multi value RDNs.
func FromCertSubject(subject pkix.Name) (*DN, error) {
dn := &DN{
RDNs: make([]*RelativeDN, 0),
}
for i := len(subject.Names) - 1; i >= 0; i-- {
name := subject.Names[i]
oidString := name.Type.String()
typeName, ok := attributeTypeNames[oidString]
if !ok {
return nil, fmt.Errorf("invalid type name: %+v", name)
}
v, ok := name.Value.(string)
if !ok {
return nil, fmt.Errorf("invalid type value: %+v", v)
}
rdn := &RelativeDN{
Attributes: []*AttributeTypeAndValue{
{
Type: typeName,
Value: v,
},
},
}
dn.RDNs = append(dn.RDNs, rdn)
}
return dn, nil
}
// FromRawCertSubject takes a raw subject from a certificate
// and uses asn1.Unmarshal to get the individual RDNs in the
// original order, including multi-value RDNs.
func FromRawCertSubject(rawSubject []byte) (*DN, error) {
dn := &DN{
RDNs: make([]*RelativeDN, 0),
}
var rdns pkix.RDNSequence
_, err := asn1.Unmarshal(rawSubject, &rdns)
if err != nil {
return nil, err
}
for i := len(rdns) - 1; i >= 0; i-- {
rdn := rdns[i]
if len(rdn) == 0 {
continue
}
r := &RelativeDN{}
attrs := make([]*AttributeTypeAndValue, 0)
for j := len(rdn) - 1; j >= 0; j-- {
atv := rdn[j]
typeName := ""
name := atv.Type.String()
typeName, ok := attributeTypeNames[name]
if !ok {
return nil, fmt.Errorf("invalid type name: %+v", name)
}
value, ok := atv.Value.(string)
if !ok {
return nil, fmt.Errorf("invalid type value: %+v", atv.Value)
}
attr := &AttributeTypeAndValue{
Type: typeName,
Value: value,
}
attrs = append(attrs, attr)
}
r.Attributes = attrs
dn.RDNs = append(dn.RDNs, r)
}
return dn, nil
}
// ParseDN returns a distinguishedName or an error.
// The function respects https://tools.ietf.org/html/rfc4514
func ParseDN(str string) (*DN, error) {
dn := new(DN)
dn.RDNs = make([]*RelativeDN, 0)
rdn := new(RelativeDN)
rdn.Attributes = make([]*AttributeTypeAndValue, 0)
buffer := bytes.Buffer{}
attribute := new(AttributeTypeAndValue)
escaping := false
unescapedTrailingSpaces := 0
stringFromBuffer := func() string {
s := buffer.String()
s = s[0 : len(s)-unescapedTrailingSpaces]
buffer.Reset()
unescapedTrailingSpaces = 0
return s
}
for i := 0; i < len(str); i++ {
char := str[i]
switch {
case escaping:
unescapedTrailingSpaces = 0
escaping = false
switch char {
case ' ', '"', '#', '+', ',', ';', '<', '=', '>', '\\':
buffer.WriteByte(char)
continue
}
// Not a special character, assume hex encoded octet
if len(str) == i+1 {
return nil, errors.New("got corrupted escaped character")
}
dst := []byte{0}
n, err := enchex.Decode([]byte(dst), []byte(str[i:i+2]))
if err != nil {
return nil, fmt.Errorf("failed to decode escaped character: %s", err)
} else if n != 1 {
return nil, fmt.Errorf("expected 1 byte when un-escaping, got %d", n)
}
buffer.WriteByte(dst[0])
i++
case char == '\\':
unescapedTrailingSpaces = 0
escaping = true
case char == '=':
attribute.Type = stringFromBuffer()
// Special case: If the first character in the value is # the following data
// is BER encoded. Throw an error since not supported right now.
if len(str) > i+1 && str[i+1] == '#' {
return nil, errors.New("unsupported BER encoding")
}
case char == ',' || char == '+':
// We're done with this RDN or value, push it
if len(attribute.Type) == 0 {
return nil, errors.New("incomplete type, value pair")
}
attribute.Value = stringFromBuffer()
rdn.Attributes = append(rdn.Attributes, attribute)
attribute = new(AttributeTypeAndValue)
if char == ',' {
dn.RDNs = append(dn.RDNs, rdn)
rdn = new(RelativeDN)
rdn.Attributes = make([]*AttributeTypeAndValue, 0)
}
case char == ' ' && buffer.Len() == 0:
// ignore unescaped leading spaces
continue
default:
if char == ' ' {
// Track unescaped spaces in case they are trailing and we need to remove them
unescapedTrailingSpaces++
} else {
// Reset if we see a non-space char
unescapedTrailingSpaces = 0
}
buffer.WriteByte(char)
}
}
if buffer.Len() > 0 {
if len(attribute.Type) == 0 {
return nil, errors.New("DN ended with incomplete type, value pair")
}
attribute.Value = stringFromBuffer()
rdn.Attributes = append(rdn.Attributes, attribute)
dn.RDNs = append(dn.RDNs, rdn)
}
return dn, nil
}
// Equal returns true if the DNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch).
// Returns true if they have the same number of relative distinguished names
// and corresponding relative distinguished names (by position) are the same.
func (d *DN) Equal(other *DN) bool {
if len(d.RDNs) != len(other.RDNs) {
return false
}
for i := range d.RDNs {
if !d.RDNs[i].Equal(other.RDNs[i]) {
return false
}
}
return true
}
// RDNsMatch returns true if the individual RDNs of the DNs
// are the same regardless of ordering.
func (d *DN) RDNsMatch(other *DN) bool {
if len(d.RDNs) != len(other.RDNs) {
return false
}
CheckNextRDN:
for _, irdn := range d.RDNs {
for _, ordn := range other.RDNs {
if (len(irdn.Attributes) == len(ordn.Attributes)) &&
(irdn.hasAllAttributes(ordn.Attributes) && ordn.hasAllAttributes(irdn.Attributes)) {
// Found the RDN, check if next one matches.
continue CheckNextRDN
}
}
// Could not find a matching individual RDN, auth fails.
return false
}
return true
}
// AncestorOf returns true if the other DN consists of at least one RDN followed by all the RDNs of the current DN.
// "ou=widgets,o=acme.com" is an ancestor of "ou=sprockets,ou=widgets,o=acme.com"
// "ou=widgets,o=acme.com" is not an ancestor of "ou=sprockets,ou=widgets,o=foo.com"
// "ou=widgets,o=acme.com" is not an ancestor of "ou=widgets,o=acme.com"
func (d *DN) AncestorOf(other *DN) bool {
if len(d.RDNs) >= len(other.RDNs) {
return false
}
// Take the last `len(d.RDNs)` RDNs from the other DN to compare against
otherRDNs := other.RDNs[len(other.RDNs)-len(d.RDNs):]
for i := range d.RDNs {
if !d.RDNs[i].Equal(otherRDNs[i]) {
return false
}
}
return true
}
// Equal returns true if the RelativeDNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch).
// Relative distinguished names are the same if and only if they have the same number of AttributeTypeAndValues
// and each attribute of the first RDN is the same as the attribute of the second RDN with the same attribute type.
// The order of attributes is not significant.
// Case of attribute types is not significant.
func (r *RelativeDN) Equal(other *RelativeDN) bool {
if len(r.Attributes) != len(other.Attributes) {
return false
}
return r.hasAllAttributes(other.Attributes) && other.hasAllAttributes(r.Attributes)
}
func (r *RelativeDN) hasAllAttributes(attrs []*AttributeTypeAndValue) bool {
for _, attr := range attrs {
found := false
for _, myattr := range r.Attributes {
if myattr.Equal(attr) {
found = true
break
}
}
if !found {
return false
}
}
return true
}
// Equal returns true if the AttributeTypeAndValue is equivalent to the specified AttributeTypeAndValue
// Case of the attribute type is not significant
func (a *AttributeTypeAndValue) Equal(other *AttributeTypeAndValue) bool {
return strings.EqualFold(a.Type, other.Type) && a.Value == other.Value
}
================================================
FILE: internal/ldap/dn_test.go
================================================
// Copyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)
// Portions copyright (c) 2015-2016 go-ldap Authors
// Static-Check Fixes Copyright 2024 The NATS Authors
package ldap
import (
"reflect"
"testing"
)
func TestSuccessfulDNParsing(t *testing.T) {
testcases := map[string]DN{
"": {[]*RelativeDN{}},
"cn=Jim\\2C \\22Hasse Hö\\22 Hansson!,dc=dummy,dc=com": {[]*RelativeDN{
{[]*AttributeTypeAndValue{{"cn", "Jim, \"Hasse Hö\" Hansson!"}}},
{[]*AttributeTypeAndValue{{"dc", "dummy"}}},
{[]*AttributeTypeAndValue{{"dc", "com"}}}}},
"UID=jsmith,DC=example,DC=net": {[]*RelativeDN{
{[]*AttributeTypeAndValue{{"UID", "jsmith"}}},
{[]*AttributeTypeAndValue{{"DC", "example"}}},
{[]*AttributeTypeAndValue{{"DC", "net"}}}}},
"OU=Sales+CN=J. Smith,DC=example,DC=net": {[]*RelativeDN{
{[]*AttributeTypeAndValue{
{"OU", "Sales"},
{"CN", "J. Smith"}}},
{[]*AttributeTypeAndValue{{"DC", "example"}}},
{[]*AttributeTypeAndValue{{"DC", "net"}}}}},
//
// "1.3.6.1.4.1.1466.0=#04024869": {[]*RelativeDN{
// {[]*AttributeTypeAndValue{{"1.3.6.1.4.1.1466.0", "Hi"}}}}},
// "1.3.6.1.4.1.1466.0=#04024869,DC=net": {[]*RelativeDN{
// {[]*AttributeTypeAndValue{{"1.3.6.1.4.1.1466.0", "Hi"}}},
// {[]*AttributeTypeAndValue{{"DC", "net"}}}}},
"CN=Lu\\C4\\8Di\\C4\\87": {[]*RelativeDN{
{[]*AttributeTypeAndValue{{"CN", "Lučić"}}}}},
" CN = Lu\\C4\\8Di\\C4\\87 ": {[]*RelativeDN{
{[]*AttributeTypeAndValue{{"CN", "Lučić"}}}}},
` A = 1 , B = 2 `: {[]*RelativeDN{
{[]*AttributeTypeAndValue{{"A", "1"}}},
{[]*AttributeTypeAndValue{{"B", "2"}}}}},
` A = 1 + B = 2 `: {[]*RelativeDN{
{[]*AttributeTypeAndValue{
{"A", "1"},
{"B", "2"}}}}},
` \ \ A\ \ = \ \ 1\ \ , \ \ B\ \ = \ \ 2\ \ `: {[]*RelativeDN{
{[]*AttributeTypeAndValue{{" A ", " 1 "}}},
{[]*AttributeTypeAndValue{{" B ", " 2 "}}}}},
` \ \ A\ \ = \ \ 1\ \ + \ \ B\ \ = \ \ 2\ \ `: {[]*RelativeDN{
{[]*AttributeTypeAndValue{
{" A ", " 1 "},
{" B ", " 2 "}}}}},
}
for test, answer := range testcases {
dn, err := ParseDN(test)
if err != nil {
t.Error(err.Error())
continue
}
if !reflect.DeepEqual(dn, &answer) {
t.Errorf("Parsed DN %s is not equal to the expected structure", test)
t.Logf("Expected:")
for _, rdn := range answer.RDNs {
for _, attribs := range rdn.Attributes {
t.Logf("#%v\n", attribs)
}
}
t.Logf("Actual:")
for _, rdn := range dn.RDNs {
for _, attribs := range rdn.Attributes {
t.Logf("#%v\n", attribs)
}
}
}
}
}
func TestErrorDNParsing(t *testing.T) {
testcases := map[string]string{
"*": "DN ended with incomplete type, value pair",
"cn=Jim\\0Test": "failed to decode escaped character: encoding/hex: invalid byte: U+0054 'T'",
"cn=Jim\\0": "got corrupted escaped character",
"DC=example,=net": "DN ended with incomplete type, value pair",
// "1=#0402486": "failed to decode BER encoding: encoding/hex: odd length hex string",
"test,DC=example,DC=com": "incomplete type, value pair",
"=test,DC=example,DC=com": "incomplete type, value pair",
}
for test, answer := range testcases {
_, err := ParseDN(test)
if err == nil {
t.Errorf("Expected %s to fail parsing but succeeded\n", test)
} else if err.Error() != answer {
t.Errorf("Unexpected error on %s:\n%s\nvs.\n%s\n", test, answer, err.Error())
}
}
}
func TestDNEqual(t *testing.T) {
testcases := []struct {
A string
B string
Equal bool
}{
// Exact match
{"", "", true},
{"o=A", "o=A", true},
{"o=A", "o=B", false},
{"o=A,o=B", "o=A,o=B", true},
{"o=A,o=B", "o=A,o=C", false},
{"o=A+o=B", "o=A+o=B", true},
{"o=A+o=B", "o=A+o=C", false},
// Case mismatch in type is ignored
{"o=A", "O=A", true},
{"o=A,o=B", "o=A,O=B", true},
{"o=A+o=B", "o=A+O=B", true},
// Case mismatch in value is significant
{"o=a", "O=A", false},
{"o=a,o=B", "o=A,O=B", false},
{"o=a+o=B", "o=A+O=B", false},
// Multi-valued RDN order mismatch is ignored
{"o=A+o=B", "O=B+o=A", true},
// Number of RDN attributes is significant
{"o=A+o=B", "O=B+o=A+O=B", false},
// Missing values are significant
{"o=A+o=B", "O=B+o=A+O=C", false}, // missing values matter
{"o=A+o=B+o=C", "O=B+o=A", false}, // missing values matter
// Whitespace tests
// Matching
{
"cn=John Doe, ou=People, dc=sun.com",
"cn=John Doe, ou=People, dc=sun.com",
true,
},
// Difference in leading/trailing chars is ignored
{
"cn=John Doe, ou=People, dc=sun.com",
"cn=John Doe,ou=People,dc=sun.com",
true,
},
// Difference in values is significant
{
"cn=John Doe, ou=People, dc=sun.com",
"cn=John Doe, ou=People, dc=sun.com",
false,
},
}
for i, tc := range testcases {
a, err := ParseDN(tc.A)
if err != nil {
t.Errorf("%d: %v", i, err)
continue
}
b, err := ParseDN(tc.B)
if err != nil {
t.Errorf("%d: %v", i, err)
continue
}
if expected, actual := tc.Equal, a.Equal(b); expected != actual {
t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual)
continue
}
if expected, actual := tc.Equal, b.Equal(a); expected != actual {
t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual)
continue
}
}
}
func TestDNAncestor(t *testing.T) {
testcases := []struct {
A string
B string
Ancestor bool
}{
// Exact match returns false
{"", "", false},
{"o=A", "o=A", false},
{"o=A,o=B", "o=A,o=B", false},
{"o=A+o=B", "o=A+o=B", false},
// Mismatch
{"ou=C,ou=B,o=A", "ou=E,ou=D,ou=B,o=A", false},
// Descendant
{"ou=C,ou=B,o=A", "ou=E,ou=C,ou=B,o=A", true},
}
for i, tc := range testcases {
a, err := ParseDN(tc.A)
if err != nil {
t.Errorf("%d: %v", i, err)
continue
}
b, err := ParseDN(tc.B)
if err != nil {
t.Errorf("%d: %v", i, err)
continue
}
if expected, actual := tc.Ancestor, a.AncestorOf(b); expected != actual {
t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual)
continue
}
}
}
================================================
FILE: internal/ocsp/ocsp.go
================================================
// Copyright 2019-2024 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package testhelper
import (
"crypto"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"io"
"net/http"
"os"
"strconv"
"strings"
"sync"
"testing"
"time"
"golang.org/x/crypto/ocsp"
)
const (
defaultResponseTTL = 4 * time.Second
defaultAddress = "127.0.0.1:8888"
)
func NewOCSPResponderCustomAddress(t *testing.T, issuerCertPEM, issuerKeyPEM string, addr string) *http.Server {
t.Helper()
return NewOCSPResponderBase(t, issuerCertPEM, issuerCertPEM, issuerKeyPEM, false, addr, defaultResponseTTL, "")
}
func NewOCSPResponder(t *testing.T, issuerCertPEM, issuerKeyPEM string) *http.Server {
t.Helper()
return NewOCSPResponderBase(t, issuerCertPEM, issuerCertPEM, issuerKeyPEM, false, defaultAddress, defaultResponseTTL, "")
}
func NewOCSPResponderDesignatedCustomAddress(t *testing.T, issuerCertPEM, respCertPEM, respKeyPEM string, addr string) *http.Server {
t.Helper()
return NewOCSPResponderBase(t, issuerCertPEM, respCertPEM, respKeyPEM, true, addr, defaultResponseTTL, "")
}
func NewOCSPResponderPreferringHTTPMethod(t *testing.T, issuerCertPEM, issuerKeyPEM, method string) *http.Server {
t.Helper()
return NewOCSPResponderBase(t, issuerCertPEM, issuerCert
gitextract_i1v6glus/
├── .coveralls.yml
├── .github/
│ ├── CODEOWNERS
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── config.yml
│ │ ├── defect.yml
│ │ └── proposal.yml
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── actions/
│ │ └── nightly-release/
│ │ └── action.yaml
│ ├── dependabot.yml
│ └── workflows/
│ ├── claude.yml
│ ├── cov.yaml
│ ├── long-tests.yaml
│ ├── mqtt-test.yaml
│ ├── nightly.yaml
│ ├── release.yaml
│ ├── stale-issues.yaml
│ ├── tests.yaml
│ └── vuln.yaml
├── .gitignore
├── .golangci.yml
├── .goreleaser.yml
├── AMBASSADORS.md
├── CODE-OF-CONDUCT.md
├── CONTRIBUTING.md
├── DEPENDENCIES.md
├── GOVERNANCE.md
├── LICENSE
├── MAINTAINERS.md
├── README.md
├── RELEASES.md
├── TODO.md
├── conf/
│ ├── fuzz.go
│ ├── lex.go
│ ├── lex_test.go
│ ├── parse.go
│ └── parse_test.go
├── doc/
│ └── README.md
├── docker/
│ └── Dockerfile.nightly
├── go.mod
├── go.sum
├── internal/
│ ├── antithesis/
│ │ ├── noop.go
│ │ └── test_assert.go
│ ├── fastrand/
│ │ ├── LICENSE
│ │ ├── fastrand.go
│ │ └── fastrand_test.go
│ ├── ldap/
│ │ ├── dn.go
│ │ └── dn_test.go
│ ├── ocsp/
│ │ └── ocsp.go
│ └── testhelper/
│ └── logging.go
├── locksordering.txt
├── logger/
│ ├── log.go
│ ├── log_test.go
│ ├── syslog.go
│ ├── syslog_test.go
│ ├── syslog_windows.go
│ └── syslog_windows_test.go
├── main.go
├── scripts/
│ ├── cov.sh
│ ├── runTestsOnTravis.sh
│ └── updateCopyrights.sh
├── server/
│ ├── README-MQTT.md
│ ├── README.md
│ ├── accounts.go
│ ├── accounts_test.go
│ ├── ats/
│ │ ├── ats.go
│ │ └── ats_test.go
│ ├── auth.go
│ ├── auth_callout.go
│ ├── auth_callout_test.go
│ ├── auth_test.go
│ ├── avl/
│ │ ├── norace_test.go
│ │ ├── seqset.go
│ │ └── seqset_test.go
│ ├── benchmark_publish_test.go
│ ├── certidp/
│ │ ├── certidp.go
│ │ ├── certidp_test.go
│ │ ├── messages.go
│ │ ├── ocsp_responder.go
│ │ └── ocsp_responder_test.go
│ ├── certstore/
│ │ ├── certstore.go
│ │ ├── certstore_other.go
│ │ ├── certstore_windows.go
│ │ └── errors.go
│ ├── certstore_windows_test.go
│ ├── ciphersuites.go
│ ├── client.go
│ ├── client_proxyproto.go
│ ├── client_proxyproto_test.go
│ ├── client_test.go
│ ├── closed_conns_test.go
│ ├── config_check_test.go
│ ├── configs/
│ │ ├── certs/
│ │ │ ├── cert.new.pem
│ │ │ ├── key.new.pem
│ │ │ ├── key.pem
│ │ │ ├── server.pem
│ │ │ └── tls/
│ │ │ ├── benchmark-ca-cert.pem
│ │ │ ├── benchmark-ca-key.pem
│ │ │ ├── benchmark-server-cert-ed25519.pem
│ │ │ ├── benchmark-server-cert-rsa-1024.pem
│ │ │ ├── benchmark-server-cert-rsa-2048.pem
│ │ │ ├── benchmark-server-cert-rsa-4096.pem
│ │ │ ├── benchmark-server-key-ed25519.pem
│ │ │ ├── benchmark-server-key-rsa-1024.pem
│ │ │ ├── benchmark-server-key-rsa-2048.pem
│ │ │ └── benchmark-server-key-rsa-4096.pem
│ │ └── one.creds
│ ├── const.go
│ ├── consumer.go
│ ├── core_benchmarks_test.go
│ ├── cron.go
│ ├── dirstore.go
│ ├── dirstore_test.go
│ ├── disk_avail.go
│ ├── disk_avail_netbsd.go
│ ├── disk_avail_openbsd.go
│ ├── disk_avail_solaris.go
│ ├── disk_avail_wasm.go
│ ├── disk_avail_windows.go
│ ├── elastic/
│ │ └── elastic.go
│ ├── errors.go
│ ├── errors.json
│ ├── errors_gen.go
│ ├── errors_test.go
│ ├── events.go
│ ├── events_test.go
│ ├── filestore.go
│ ├── filestore_test.go
│ ├── gateway.go
│ ├── gateway_test.go
│ ├── gsl/
│ │ ├── gsl.go
│ │ └── gsl_test.go
│ ├── ipqueue.go
│ ├── ipqueue_test.go
│ ├── jetstream.go
│ ├── jetstream_api.go
│ ├── jetstream_batching.go
│ ├── jetstream_batching_test.go
│ ├── jetstream_benchmark_test.go
│ ├── jetstream_cluster.go
│ ├── jetstream_cluster_1_test.go
│ ├── jetstream_cluster_2_test.go
│ ├── jetstream_cluster_3_test.go
│ ├── jetstream_cluster_4_test.go
│ ├── jetstream_cluster_long_test.go
│ ├── jetstream_consumer_test.go
│ ├── jetstream_errors.go
│ ├── jetstream_errors_generated.go
│ ├── jetstream_errors_test.go
│ ├── jetstream_events.go
│ ├── jetstream_helpers_test.go
│ ├── jetstream_jwt_test.go
│ ├── jetstream_leafnode_test.go
│ ├── jetstream_meta_benchmark_test.go
│ ├── jetstream_sourcing_scaling_test.go
│ ├── jetstream_super_cluster_test.go
│ ├── jetstream_test.go
│ ├── jetstream_tpm_test.go
│ ├── jetstream_versioning.go
│ ├── jetstream_versioning_test.go
│ ├── jwt.go
│ ├── jwt_test.go
│ ├── leafnode.go
│ ├── leafnode_proxy_test.go
│ ├── leafnode_test.go
│ ├── log.go
│ ├── log_test.go
│ ├── memstore.go
│ ├── memstore_test.go
│ ├── monitor.go
│ ├── monitor_sort_opts.go
│ ├── monitor_test.go
│ ├── mqtt.go
│ ├── mqtt_ex_bench_test.go
│ ├── mqtt_ex_test_test.go
│ ├── mqtt_test.go
│ ├── msgtrace.go
│ ├── msgtrace_test.go
│ ├── nkey.go
│ ├── nkey_test.go
│ ├── norace_1_test.go
│ ├── norace_2_test.go
│ ├── ocsp.go
│ ├── ocsp_peer.go
│ ├── ocsp_responsecache.go
│ ├── opts.go
│ ├── opts_test.go
│ ├── parser.go
│ ├── parser_fuzz_test.go
│ ├── parser_test.go
│ ├── ping_test.go
│ ├── proto.go
│ ├── pse/
│ │ ├── freebsd.txt
│ │ ├── pse_darwin.go
│ │ ├── pse_dragonfly.go
│ │ ├── pse_freebsd_cgo.go
│ │ ├── pse_freebsd_sysctl.go
│ │ ├── pse_linux.go
│ │ ├── pse_netbsd.go
│ │ ├── pse_openbsd.go
│ │ ├── pse_rumprun.go
│ │ ├── pse_solaris.go
│ │ ├── pse_test.go
│ │ ├── pse_wasm.go
│ │ ├── pse_windows.go
│ │ ├── pse_windows_test.go
│ │ └── pse_zos.go
│ ├── raft.go
│ ├── raft_chain_of_blocks_helpers_test.go
│ ├── raft_helpers_test.go
│ ├── raft_test.go
│ ├── rate_counter.go
│ ├── rate_counter_test.go
│ ├── reload.go
│ ├── reload_test.go
│ ├── ring.go
│ ├── ring_test.go
│ ├── route.go
│ ├── routes_test.go
│ ├── scheduler.go
│ ├── sdm.go
│ ├── sendq.go
│ ├── server.go
│ ├── server_fuzz_test.go
│ ├── server_test.go
│ ├── service.go
│ ├── service_test.go
│ ├── service_windows.go
│ ├── service_windows_test.go
│ ├── signal.go
│ ├── signal_test.go
│ ├── signal_wasm.go
│ ├── signal_windows.go
│ ├── split_test.go
│ ├── store.go
│ ├── store_test.go
│ ├── stream.go
│ ├── stree/
│ │ ├── dump.go
│ │ ├── helper_test.go
│ │ ├── leaf.go
│ │ ├── node.go
│ │ ├── node10.go
│ │ ├── node16.go
│ │ ├── node256.go
│ │ ├── node4.go
│ │ ├── node48.go
│ │ ├── parts.go
│ │ ├── stree.go
│ │ ├── stree_test.go
│ │ └── util.go
│ ├── subject_fuzz_test.go
│ ├── subject_transform.go
│ ├── subject_transform_test.go
│ ├── sublist.go
│ ├── sublist_test.go
│ ├── sysmem/
│ │ ├── mem_bsd.go
│ │ ├── mem_darwin.go
│ │ ├── mem_linux.go
│ │ ├── mem_solaris.go
│ │ ├── mem_wasm.go
│ │ ├── mem_windows.go
│ │ ├── mem_zos.go
│ │ └── sysctl.go
│ ├── test_test.go
│ ├── thw/
│ │ ├── helper_test.go
│ │ ├── thw.go
│ │ └── thw_test.go
│ ├── tpm/
│ │ ├── js_ek_tpm_other.go
│ │ ├── js_ek_tpm_test.go
│ │ └── js_ek_tpm_windows.go
│ ├── trust_test.go
│ ├── util.go
│ ├── util_test.go
│ ├── websocket.go
│ └── websocket_test.go
├── test/
│ ├── accounts_cycles_test.go
│ ├── auth_test.go
│ ├── bench_results.txt
│ ├── bench_test.go
│ ├── client_auth_test.go
│ ├── client_cluster_test.go
│ ├── cluster_test.go
│ ├── cluster_tls_test.go
│ ├── configs/
│ │ ├── certs/
│ │ │ ├── ca.pem
│ │ │ ├── client-cert.pem
│ │ │ ├── client-id-auth-cert.pem
│ │ │ ├── client-id-auth-key.pem
│ │ │ ├── client-key.pem
│ │ │ ├── ocsp/
│ │ │ │ ├── ca-cert.pem
│ │ │ │ ├── ca-key.pem
│ │ │ │ ├── client-cert.pem
│ │ │ │ ├── client-key.pem
│ │ │ │ ├── desgsign/
│ │ │ │ │ ├── ca-cert.pem
│ │ │ │ │ ├── ca-chain-cert.pem
│ │ │ │ │ ├── ca-interm-cert.pem
│ │ │ │ │ ├── ca-interm-key.pem
│ │ │ │ │ ├── ca-key.pem
│ │ │ │ │ ├── server-01-cert.pem
│ │ │ │ │ ├── server-01-key.pem
│ │ │ │ │ ├── server-02-cert.pem
│ │ │ │ │ └── server-02-key.pem
│ │ │ │ ├── gen.sh
│ │ │ │ ├── server-cert.pem
│ │ │ │ ├── server-key.pem
│ │ │ │ ├── server-status-request-cert.pem
│ │ │ │ ├── server-status-request-key.pem
│ │ │ │ ├── server-status-request-url-01-cert.pem
│ │ │ │ ├── server-status-request-url-01-key.pem
│ │ │ │ ├── server-status-request-url-02-cert.pem
│ │ │ │ ├── server-status-request-url-02-key.pem
│ │ │ │ ├── server-status-request-url-03-cert.pem
│ │ │ │ ├── server-status-request-url-03-key.pem
│ │ │ │ ├── server-status-request-url-04-cert.pem
│ │ │ │ ├── server-status-request-url-04-key.pem
│ │ │ │ ├── server-status-request-url-05-cert.pem
│ │ │ │ ├── server-status-request-url-05-key.pem
│ │ │ │ ├── server-status-request-url-06-cert.pem
│ │ │ │ ├── server-status-request-url-06-key.pem
│ │ │ │ ├── server-status-request-url-07-cert.pem
│ │ │ │ ├── server-status-request-url-07-key.pem
│ │ │ │ ├── server-status-request-url-08-cert.pem
│ │ │ │ └── server-status-request-url-08-key.pem
│ │ │ ├── ocsp_peer/
│ │ │ │ └── mini-ca/
│ │ │ │ ├── caocsp/
│ │ │ │ │ ├── caocsp_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ └── caocsp_keypair.pem
│ │ │ │ ├── client1/
│ │ │ │ │ ├── System_bundle.pem
│ │ │ │ │ ├── System_cert.pem
│ │ │ │ │ ├── UserA1_bundle.pem
│ │ │ │ │ ├── UserA1_cert.pem
│ │ │ │ │ ├── UserA2_bundle.pem
│ │ │ │ │ ├── UserA2_cert.pem
│ │ │ │ │ ├── certfile.pem
│ │ │ │ │ └── private/
│ │ │ │ │ ├── System_keypair.pem
│ │ │ │ │ ├── UserA1_keypair.pem
│ │ │ │ │ └── UserA2_keypair.pem
│ │ │ │ ├── client2/
│ │ │ │ │ ├── UserB1_bundle.pem
│ │ │ │ │ ├── UserB1_cert.pem
│ │ │ │ │ ├── UserB2_bundle.pem
│ │ │ │ │ ├── UserB2_cert.pem
│ │ │ │ │ ├── certfile.pem
│ │ │ │ │ └── private/
│ │ │ │ │ ├── UserB1_keypair.pem
│ │ │ │ │ └── UserB2_keypair.pem
│ │ │ │ ├── intermediate1/
│ │ │ │ │ ├── intermediate1_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ └── intermediate1_keypair.pem
│ │ │ │ ├── intermediate2/
│ │ │ │ │ ├── intermediate2_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ └── intermediate2_keypair.pem
│ │ │ │ ├── misc/
│ │ │ │ │ ├── misconfig_TestServer1_bundle.pem
│ │ │ │ │ ├── trust_config1_bundle.pem
│ │ │ │ │ ├── trust_config2_bundle.pem
│ │ │ │ │ └── trust_config3_bundle.pem
│ │ │ │ ├── ocsp1/
│ │ │ │ │ ├── ocsp1_bundle.pem
│ │ │ │ │ ├── ocsp1_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ └── ocsp1_keypair.pem
│ │ │ │ ├── ocsp2/
│ │ │ │ │ ├── ocsp2_bundle.pem
│ │ │ │ │ ├── ocsp2_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ └── ocsp2_keypair.pem
│ │ │ │ ├── root/
│ │ │ │ │ ├── private/
│ │ │ │ │ │ └── root_keypair.pem
│ │ │ │ │ └── root_cert.pem
│ │ │ │ ├── server1/
│ │ │ │ │ ├── TestServer1_bundle.pem
│ │ │ │ │ ├── TestServer1_cert.pem
│ │ │ │ │ ├── TestServer2_bundle.pem
│ │ │ │ │ ├── TestServer2_cert.pem
│ │ │ │ │ └── private/
│ │ │ │ │ ├── TestServer1_keypair.pem
│ │ │ │ │ └── TestServer2_keypair.pem
│ │ │ │ └── server2/
│ │ │ │ ├── TestServer3_bundle.pem
│ │ │ │ ├── TestServer3_cert.pem
│ │ │ │ ├── TestServer4_bundle.pem
│ │ │ │ ├── TestServer4_cert.pem
│ │ │ │ └── private/
│ │ │ │ ├── TestServer3_keypair.pem
│ │ │ │ └── TestServer4_keypair.pem
│ │ │ ├── rdns/
│ │ │ │ ├── ca.key
│ │ │ │ ├── ca.pem
│ │ │ │ ├── client-a.key
│ │ │ │ ├── client-a.pem
│ │ │ │ ├── client-b.key
│ │ │ │ ├── client-b.pem
│ │ │ │ ├── client-c.key
│ │ │ │ ├── client-c.pem
│ │ │ │ ├── client-d.key
│ │ │ │ ├── client-d.pem
│ │ │ │ ├── client-e.key
│ │ │ │ ├── client-e.pem
│ │ │ │ ├── client-f.key
│ │ │ │ ├── client-f.pem
│ │ │ │ ├── server.key
│ │ │ │ └── server.pem
│ │ │ ├── regenerate_rdns_svid.sh
│ │ │ ├── regenerate_top.sh
│ │ │ ├── sans/
│ │ │ │ ├── ca.pem
│ │ │ │ ├── client-key.pem
│ │ │ │ ├── client.pem
│ │ │ │ ├── dev-email-key.pem
│ │ │ │ ├── dev-email.pem
│ │ │ │ ├── dev-key.pem
│ │ │ │ ├── dev.pem
│ │ │ │ ├── prod-key.pem
│ │ │ │ ├── prod.pem
│ │ │ │ ├── server-key.pem
│ │ │ │ └── server.pem
│ │ │ ├── server-cert.pem
│ │ │ ├── server-iponly.pem
│ │ │ ├── server-key-iponly.pem
│ │ │ ├── server-key-noip.pem
│ │ │ ├── server-key.pem
│ │ │ ├── server-noip.pem
│ │ │ ├── srva-cert.pem
│ │ │ ├── srva-key.pem
│ │ │ ├── srvb-cert.pem
│ │ │ ├── srvb-key.pem
│ │ │ ├── svid/
│ │ │ │ ├── ca.key
│ │ │ │ ├── ca.pem
│ │ │ │ ├── client-a.key
│ │ │ │ ├── client-a.pem
│ │ │ │ ├── client-b.key
│ │ │ │ ├── client-b.pem
│ │ │ │ ├── server.key
│ │ │ │ ├── server.pem
│ │ │ │ ├── svid-user-a.key
│ │ │ │ ├── svid-user-a.pem
│ │ │ │ ├── svid-user-b.key
│ │ │ │ └── svid-user-b.pem
│ │ │ └── tlsauth/
│ │ │ ├── ca.pem
│ │ │ ├── certstore/
│ │ │ │ ├── ca.p12
│ │ │ │ ├── client.p12
│ │ │ │ ├── delete-cert-from-store.ps1
│ │ │ │ ├── ecdsa_server.key
│ │ │ │ ├── ecdsa_server.pem
│ │ │ │ ├── ecdsa_server.pfx
│ │ │ │ ├── expired.p12
│ │ │ │ ├── generate_ecdsa_test_cert.sh
│ │ │ │ ├── import-p12-ca.ps1
│ │ │ │ ├── import-p12-client.ps1
│ │ │ │ ├── import-p12-server.ps1
│ │ │ │ ├── not-expired.p12
│ │ │ │ ├── pkcs12.md
│ │ │ │ └── server.p12
│ │ │ ├── client-key.pem
│ │ │ ├── client.pem
│ │ │ ├── client2-key.pem
│ │ │ ├── client2.pem
│ │ │ ├── server-key.pem
│ │ │ ├── server-no-ou-key.pem
│ │ │ ├── server-no-ou.pem
│ │ │ └── server.pem
│ │ ├── jetstream/
│ │ │ ├── restore_bad_stream/
│ │ │ │ ├── backup.json
│ │ │ │ └── stream.tar.s2
│ │ │ ├── restore_empty_R1F_stream/
│ │ │ │ ├── backup.json
│ │ │ │ └── stream.tar.s2
│ │ │ └── restore_empty_R3F_stream/
│ │ │ ├── backup.json
│ │ │ └── stream.tar.s2
│ │ └── nkeys/
│ │ ├── op.jwt
│ │ ├── sigkeys.txt
│ │ └── test.seed
│ ├── fanout_test.go
│ ├── gateway_test.go
│ ├── gosrv_test.go
│ ├── leafnode_test.go
│ ├── log_test.go
│ ├── maxpayload_test.go
│ ├── monitor_test.go
│ ├── new_routes_test.go
│ ├── norace_test.go
│ ├── ocsp_peer_test.go
│ ├── ocsp_test.go
│ ├── operator_test.go
│ ├── opts_test.go
│ ├── pedantic_test.go
│ ├── pid_test.go
│ ├── ping_test.go
│ ├── port_test.go
│ ├── ports_test.go
│ ├── proto_test.go
│ ├── route_discovery_test.go
│ ├── routes_test.go
│ ├── service_latency_test.go
│ ├── services_test.go
│ ├── system_services_test.go
│ ├── test.go
│ ├── test_test.go
│ ├── tls_test.go
│ ├── user_authorization_test.go
│ └── verbose_test.go
└── util/
├── nats-server-hardened.service
└── nats-server.service
Showing preview only (1,115K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (11136 symbols across 249 files)
FILE: conf/fuzz.go
function Fuzz (line 18) | func Fuzz(data []byte) int {
FILE: conf/lex.go
type itemType (line 37) | type itemType
method String (line 1269) | func (itype itemType) String() string {
constant itemError (line 40) | itemError itemType = iota
constant itemNIL (line 41) | itemNIL
constant itemEOF (line 42) | itemEOF
constant itemKey (line 43) | itemKey
constant itemText (line 44) | itemText
constant itemString (line 45) | itemString
constant itemBool (line 46) | itemBool
constant itemInteger (line 47) | itemInteger
constant itemFloat (line 48) | itemFloat
constant itemDatetime (line 49) | itemDatetime
constant itemArrayStart (line 50) | itemArrayStart
constant itemArrayEnd (line 51) | itemArrayEnd
constant itemMapStart (line 52) | itemMapStart
constant itemMapEnd (line 53) | itemMapEnd
constant itemCommentStart (line 54) | itemCommentStart
constant itemVariable (line 55) | itemVariable
constant itemInclude (line 56) | itemInclude
constant eof (line 60) | eof = 0
constant mapStart (line 61) | mapStart = '{'
constant mapEnd (line 62) | mapEnd = '}'
constant keySepEqual (line 63) | keySepEqual = '='
constant keySepColon (line 64) | keySepColon = ':'
constant arrayStart (line 65) | arrayStart = '['
constant arrayEnd (line 66) | arrayEnd = ']'
constant arrayValTerm (line 67) | arrayValTerm = ','
constant mapValTerm (line 68) | mapValTerm = ','
constant commentHashStart (line 69) | commentHashStart = '#'
constant commentSlashStart (line 70) | commentSlashStart = '/'
constant dqStringStart (line 71) | dqStringStart = '"'
constant dqStringEnd (line 72) | dqStringEnd = '"'
constant sqStringStart (line 73) | sqStringStart = '\''
constant sqStringEnd (line 74) | sqStringEnd = '\''
constant optValTerm (line 75) | optValTerm = ';'
constant topOptStart (line 76) | topOptStart = '{'
constant topOptValTerm (line 77) | topOptValTerm = ','
constant topOptTerm (line 78) | topOptTerm = '}'
constant blockStart (line 79) | blockStart = '('
constant blockEnd (line 80) | blockEnd = ')'
constant mapEndString (line 81) | mapEndString = string(mapEnd)
type stateFn (line 84) | type stateFn
type lexer (line 86) | type lexer struct
method nextItem (line 120) | func (lx *lexer) nextItem() item {
method push (line 143) | func (lx *lexer) push(state stateFn) {
method pop (line 147) | func (lx *lexer) pop() stateFn {
method emit (line 157) | func (lx *lexer) emit(typ itemType) {
method emitString (line 166) | func (lx *lexer) emitString() {
method addCurrentStringPart (line 181) | func (lx *lexer) addCurrentStringPart(offset int) {
method addStringPart (line 186) | func (lx *lexer) addStringPart(s string) stateFn {
method hasEscapedParts (line 192) | func (lx *lexer) hasEscapedParts() bool {
method next (line 196) | func (lx *lexer) next() (r rune) {
method ignore (line 215) | func (lx *lexer) ignore() {
method backup (line 221) | func (lx *lexer) backup() {
method peek (line 229) | func (lx *lexer) peek() rune {
method errorf (line 238) | func (lx *lexer) errorf(format string, values ...any) stateFn {
method keyCheckKeyword (line 480) | func (lx *lexer) keyCheckKeyword(fallThrough, push stateFn) stateFn {
method isBool (line 884) | func (lx *lexer) isBool() bool {
method isVariable (line 892) | func (lx *lexer) isVariable() bool {
type item (line 113) | type item struct
method String (line 1309) | func (item item) String() string {
function lex (line 131) | func lex(input string) *lexer {
function lexTop (line 257) | func lexTop(lx *lexer) stateFn {
function lexTopValueEnd (line 296) | func lexTopValueEnd(lx *lexer) stateFn {
function lexBlockStart (line 321) | func lexBlockStart(lx *lexer) stateFn {
function lexBlockValueEnd (line 363) | func lexBlockValueEnd(lx *lexer) stateFn {
function lexBlockEnd (line 393) | func lexBlockEnd(lx *lexer) stateFn {
function lexKeyStart (line 422) | func lexKeyStart(lx *lexer) stateFn {
function lexDubQuotedKey (line 443) | func lexDubQuotedKey(lx *lexer) stateFn {
function lexQuotedKey (line 461) | func lexQuotedKey(lx *lexer) stateFn {
function lexIncludeStart (line 495) | func lexIncludeStart(lx *lexer) stateFn {
function lexIncludeQuotedString (line 507) | func lexIncludeQuotedString(lx *lexer) stateFn {
function lexIncludeDubQuotedString (line 525) | func lexIncludeDubQuotedString(lx *lexer) stateFn {
function lexIncludeString (line 541) | func lexIncludeString(lx *lexer) stateFn {
function lexInclude (line 559) | func lexInclude(lx *lexer) stateFn {
function lexKey (line 587) | func lexKey(lx *lexer) stateFn {
function lexKeyEnd (line 604) | func lexKeyEnd(lx *lexer) stateFn {
function lexValue (line 623) | func lexValue(lx *lexer) stateFn {
function lexArrayValue (line 667) | func lexArrayValue(lx *lexer) stateFn {
function lexArrayValueEnd (line 696) | func lexArrayValueEnd(lx *lexer) stateFn {
function lexArrayEnd (line 723) | func lexArrayEnd(lx *lexer) stateFn {
function lexMapKeyStart (line 732) | func lexMapKeyStart(lx *lexer) stateFn {
function lexMapQuotedKey (line 772) | func lexMapQuotedKey(lx *lexer) stateFn {
function lexMapDubQuotedKey (line 785) | func lexMapDubQuotedKey(lx *lexer) stateFn {
function lexMapKey (line 799) | func lexMapKey(lx *lexer) stateFn {
function lexMapKeyEnd (line 817) | func lexMapKeyEnd(lx *lexer) stateFn {
function lexMapValue (line 833) | func lexMapValue(lx *lexer) stateFn {
function lexMapValueEnd (line 850) | func lexMapValueEnd(lx *lexer) stateFn {
function lexMapEnd (line 877) | func lexMapEnd(lx *lexer) stateFn {
function lexQuotedString (line 906) | func lexQuotedString(lx *lexer) stateFn {
function lexDubQuotedString (line 928) | func lexDubQuotedString(lx *lexer) stateFn {
function lexString (line 951) | func lexString(lx *lexer) stateFn {
function lexBlock (line 986) | func lexBlock(lx *lexer) stateFn {
function lexStringEscape (line 1021) | func lexStringEscape(lx *lexer) stateFn {
function lexStringBinary (line 1043) | func lexStringBinary(lx *lexer) stateFn {
function lexNumberOrDateOrStringOrIPStart (line 1065) | func lexNumberOrDateOrStringOrIPStart(lx *lexer) stateFn {
function lexNumberOrDateOrStringOrIP (line 1079) | func lexNumberOrDateOrStringOrIP(lx *lexer) stateFn {
function lexConvenientNumber (line 1106) | func lexConvenientNumber(lx *lexer) stateFn {
function lexDateAfterYear (line 1124) | func lexDateAfterYear(lx *lexer) stateFn {
function lexNegNumberStart (line 1152) | func lexNegNumberStart(lx *lexer) stateFn {
function lexNegNumber (line 1165) | func lexNegNumber(lx *lexer) stateFn {
function lexFloatStart (line 1182) | func lexFloatStart(lx *lexer) stateFn {
function lexFloat (line 1193) | func lexFloat(lx *lexer) stateFn {
function lexIPAddr (line 1210) | func lexIPAddr(lx *lexer) stateFn {
function lexCommentStart (line 1222) | func lexCommentStart(lx *lexer) stateFn {
function lexComment (line 1231) | func lexComment(lx *lexer) stateFn {
function lexSkip (line 1242) | func lexSkip(lx *lexer, nextState stateFn) stateFn {
function isNumberSuffix (line 1250) | func isNumberSuffix(r rune) bool {
function isKeySeparator (line 1255) | func isKeySeparator(r rune) bool {
function isWhitespace (line 1261) | func isWhitespace(r rune) bool {
function isNL (line 1265) | func isNL(r rune) bool {
function escapeSpecial (line 1313) | func escapeSpecial(c rune) string {
FILE: conf/lex_test.go
function expect (line 6) | func expect(t *testing.T, lx *lexer, items []item) {
function TestPlainValue (line 24) | func TestPlainValue(t *testing.T) {
function TestSimpleKeyStringValues (line 33) | func TestSimpleKeyStringValues(t *testing.T) {
function TestComplexStringValues (line 79) | func TestComplexStringValues(t *testing.T) {
function TestStringStartingWithNumber (line 90) | func TestStringStartingWithNumber(t *testing.T) {
function TestBinaryString (line 168) | func TestBinaryString(t *testing.T) {
function TestBinaryStringLatin1 (line 178) | func TestBinaryStringLatin1(t *testing.T) {
function TestSimpleKeyIntegerValues (line 188) | func TestSimpleKeyIntegerValues(t *testing.T) {
function TestSimpleKeyNegativeIntegerValues (line 208) | func TestSimpleKeyNegativeIntegerValues(t *testing.T) {
function TestConvenientIntegerValues (line 228) | func TestConvenientIntegerValues(t *testing.T) {
function TestSimpleKeyFloatValues (line 345) | func TestSimpleKeyFloatValues(t *testing.T) {
function TestBadBinaryStringEndingAfterZeroHexChars (line 365) | func TestBadBinaryStringEndingAfterZeroHexChars(t *testing.T) {
function TestBadBinaryStringEndingAfterOneHexChar (line 375) | func TestBadBinaryStringEndingAfterOneHexChar(t *testing.T) {
function TestBadBinaryStringWithZeroHexChars (line 385) | func TestBadBinaryStringWithZeroHexChars(t *testing.T) {
function TestBadBinaryStringWithOneHexChar (line 395) | func TestBadBinaryStringWithOneHexChar(t *testing.T) {
function TestBadFloatValues (line 405) | func TestBadFloatValues(t *testing.T) {
function TestBadKey (line 415) | func TestBadKey(t *testing.T) {
function TestSimpleKeyBoolValues (line 424) | func TestSimpleKeyBoolValues(t *testing.T) {
function TestComments (line 444) | func TestComments(t *testing.T) {
function TestTopValuesWithComments (line 464) | func TestTopValuesWithComments(t *testing.T) {
function TestRawString (line 487) | func TestRawString(t *testing.T) {
function TestDateValues (line 499) | func TestDateValues(t *testing.T) {
function TestVariableValues (line 510) | func TestVariableValues(t *testing.T) {
function TestArrays (line 536) | func TestArrays(t *testing.T) {
function TestMultilineArrays (line 588) | func TestMultilineArrays(t *testing.T) {
function TestMultilineArraysNoSep (line 623) | func TestMultilineArraysNoSep(t *testing.T) {
function TestSimpleMap (line 643) | func TestSimpleMap(t *testing.T) {
function TestMultilineMap (line 666) | func TestMultilineMap(t *testing.T) {
function TestNestedMaps (line 695) | func TestNestedMaps(t *testing.T) {
function TestQuotedKeys (line 714) | func TestQuotedKeys(t *testing.T) {
function TestQuotedKeysWithSpace (line 734) | func TestQuotedKeysWithSpace(t *testing.T) {
function TestColonKeySep (line 752) | func TestColonKeySep(t *testing.T) {
function TestWhitespaceKeySep (line 786) | func TestWhitespaceKeySep(t *testing.T) {
function TestEscapedString (line 815) | func TestEscapedString(t *testing.T) {
function TestCompoundStringES (line 833) | func TestCompoundStringES(t *testing.T) {
function TestCompoundStringSE (line 843) | func TestCompoundStringSE(t *testing.T) {
function TestCompoundStringEE (line 853) | func TestCompoundStringEE(t *testing.T) {
function TestCompoundStringSEE (line 863) | func TestCompoundStringSEE(t *testing.T) {
function TestCompoundStringSES (line 873) | func TestCompoundStringSES(t *testing.T) {
function TestCompoundStringEES (line 883) | func TestCompoundStringEES(t *testing.T) {
function TestCompoundStringESE (line 893) | func TestCompoundStringESE(t *testing.T) {
function TestBadStringEscape (line 903) | func TestBadStringEscape(t *testing.T) {
function TestNonBool (line 913) | func TestNonBool(t *testing.T) {
function TestNonVariable (line 923) | func TestNonVariable(t *testing.T) {
function TestEmptyStringDQ (line 933) | func TestEmptyStringDQ(t *testing.T) {
function TestEmptyStringSQ (line 943) | func TestEmptyStringSQ(t *testing.T) {
function TestNestedWhitespaceMaps (line 962) | func TestNestedWhitespaceMaps(t *testing.T) {
function TestOptionalSemicolons (line 990) | func TestOptionalSemicolons(t *testing.T) {
function TestSemicolonChaining (line 1010) | func TestSemicolonChaining(t *testing.T) {
function TestNonQuotedStrings (line 1040) | func TestNonQuotedStrings(t *testing.T) {
function TestDanglingQuotedString (line 1079) | func TestDanglingQuotedString(t *testing.T) {
function TestKeyDanglingQuotedString (line 1097) | func TestKeyDanglingQuotedString(t *testing.T) {
function TestDanglingSingleQuotedString (line 1115) | func TestDanglingSingleQuotedString(t *testing.T) {
function TestKeyDanglingSingleQuotedString (line 1133) | func TestKeyDanglingSingleQuotedString(t *testing.T) {
function TestMapDanglingBracket (line 1154) | func TestMapDanglingBracket(t *testing.T) {
function TestBlockDanglingParens (line 1177) | func TestBlockDanglingParens(t *testing.T) {
function TestMapQuotedKeys (line 1188) | func TestMapQuotedKeys(t *testing.T) {
function TestSpecialCharsMapQuotedKeys (line 1203) | func TestSpecialCharsMapQuotedKeys(t *testing.T) {
function TestDoubleNestedMapsNewLines (line 1229) | func TestDoubleNestedMapsNewLines(t *testing.T) {
function TestBlockString (line 1251) | func TestBlockString(t *testing.T) {
function TestBlockStringEOF (line 1260) | func TestBlockStringEOF(t *testing.T) {
function TestBlockStringMultiLine (line 1280) | func TestBlockStringMultiLine(t *testing.T) {
function TestUnquotedIPAddr (line 1289) | func TestUnquotedIPAddr(t *testing.T) {
function TestArrayOfMaps (line 1368) | func TestArrayOfMaps(t *testing.T) {
function TestInclude (line 1396) | func TestInclude(t *testing.T) {
function TestMapInclude (line 1415) | func TestMapInclude(t *testing.T) {
function TestJSONCompat (line 1458) | func TestJSONCompat(t *testing.T) {
FILE: conf/parse.go
constant _EMPTY_ (line 40) | _EMPTY_ = ""
type parser (line 42) | type parser struct
method parse (line 202) | func (p *parser) parse(fp string) error {
method next (line 224) | func (p *parser) next() item {
method pushContext (line 228) | func (p *parser) pushContext(ctx any) {
method popContext (line 233) | func (p *parser) popContext() any {
method pushKey (line 244) | func (p *parser) pushKey(key string) {
method popKey (line 248) | func (p *parser) popKey() string {
method pushItemKey (line 258) | func (p *parser) pushItemKey(key item) {
method popItemKey (line 262) | func (p *parser) popItemKey() item {
method processItem (line 272) | func (p *parser) processItem(it item, fp string) error {
method lookupVariable (line 448) | func (p *parser) lookupVariable(varReference string) (any, bool, error) {
method setValue (line 486) | func (p *parser) setValue(val any) {
function Parse (line 71) | func Parse(data string) (map[string]any, error) {
function ParseWithChecks (line 80) | func ParseWithChecks(data string) (map[string]any, error) {
function ParseFile (line 89) | func ParseFile(fp string) (map[string]any, error) {
function ParseFileWithChecks (line 103) | func ParseFileWithChecks(fp string) (map[string]any, error) {
function configDigest (line 118) | func configDigest(m map[string]any) (string, error) {
function ParseFileWithChecksDigest (line 129) | func ParseFileWithChecksDigest(fp string) (map[string]any, string, error) {
type token (line 141) | type token struct
method MarshalJSON (line 148) | func (t *token) MarshalJSON() ([]byte, error) {
method Value (line 152) | func (t *token) Value() any {
method Line (line 156) | func (t *token) Line() int {
method IsUsedVariable (line 160) | func (t *token) IsUsedVariable() bool {
method SourceFile (line 164) | func (t *token) SourceFile() string {
method Position (line 168) | func (t *token) Position() int {
function newParser (line 172) | func newParser(data, fp string, pedantic bool) *parser {
function parse (line 185) | func parse(data, fp string, pedantic bool) (*parser, error) {
function parseEnv (line 193) | func parseEnv(data string, parent *parser) (*parser, error) {
constant pkey (line 438) | pkey = "pk"
constant bcryptPrefix (line 441) | bcryptPrefix = "2a$"
FILE: conf/parse_test.go
function test (line 17) | func test(t *testing.T, data string, ex map[string]any) {
function TestSimpleTopLevel (line 53) | func TestSimpleTopLevel(t *testing.T) {
function TestBools (line 63) | func TestBools(t *testing.T) {
function TestSimpleVariable (line 79) | func TestSimpleVariable(t *testing.T) {
function TestNestedVariable (line 96) | func TestNestedVariable(t *testing.T) {
function TestMissingVariable (line 108) | func TestMissingVariable(t *testing.T) {
function TestEnvVariable (line 118) | func TestEnvVariable(t *testing.T) {
function TestEnvVariableString (line 128) | func TestEnvVariableString(t *testing.T) {
function TestEnvVariableStringStartingWithNumber (line 138) | func TestEnvVariableStringStartingWithNumber(t *testing.T) {
function TestEnvVariableStringStartingWithNumberAndSizeUnit (line 149) | func TestEnvVariableStringStartingWithNumberAndSizeUnit(t *testing.T) {
function TestEnvVariableStringStartingWithNumberUsingQuotes (line 159) | func TestEnvVariableStringStartingWithNumberUsingQuotes(t *testing.T) {
function TestBcryptVariable (line 169) | func TestBcryptVariable(t *testing.T) {
function TestConvenientNumbers (line 197) | func TestConvenientNumbers(t *testing.T) {
function TestParseFileWithChecksDigestPreservesConfigKeyUsedAsVariable (line 221) | func TestParseFileWithChecksDigestPreservesConfigKeyUsedAsVariable(t *te...
function TestSample1 (line 249) | func TestSample1(t *testing.T) {
function TestSample2 (line 285) | func TestSample2(t *testing.T) {
function TestSample3 (line 312) | func TestSample3(t *testing.T) {
function TestSample4 (line 329) | func TestSample4(t *testing.T) {
function TestSample5 (line 345) | func TestSample5(t *testing.T) {
function TestIncludes (line 354) | func TestIncludes(t *testing.T) {
function TestIncludeVariablesWithChecks (line 400) | func TestIncludeVariablesWithChecks(t *testing.T) {
function TestParserNoInfiniteLoop (line 439) | func TestParserNoInfiniteLoop(t *testing.T) {
function TestParseWithNoValuesAreInvalid (line 449) | func TestParseWithNoValuesAreInvalid(t *testing.T) {
function TestParseWithNoValuesEmptyConfigsAreValid (line 497) | func TestParseWithNoValuesEmptyConfigsAreValid(t *testing.T) {
function TestParseWithTrailingBracketsAreValid (line 529) | func TestParseWithTrailingBracketsAreValid(t *testing.T) {
function TestParseWithNoValuesIncludes (line 571) | func TestParseWithNoValuesIncludes(t *testing.T) {
function TestJSONParseCompat (line 642) | func TestJSONParseCompat(t *testing.T) {
function TestBlocks (line 785) | func TestBlocks(t *testing.T) {
function TestParseDigest (line 896) | func TestParseDigest(t *testing.T) {
FILE: internal/antithesis/noop.go
function AssertUnreachable (line 24) | func AssertUnreachable(_ testing.TB, _ string, _ map[string]any) {}
function Assert (line 27) | func Assert(_ testing.TB, _ bool, _ string, _ map[string]any) {}
FILE: internal/antithesis/test_assert.go
function AssertUnreachable (line 49) | func AssertUnreachable(t testing.TB, message string, details map[string]...
function Assert (line 83) | func Assert(t testing.TB, condition bool, message string, details map[st...
FILE: internal/fastrand/fastrand.go
function Uint32 (line 12) | func Uint32() uint32
function Uint32n (line 17) | func Uint32n(n uint32) uint32
function Uint64 (line 20) | func Uint64() uint64 {
FILE: internal/fastrand/fastrand_test.go
type defaultRand (line 14) | type defaultRand struct
method Uint32 (line 26) | func (r *defaultRand) Uint32() uint32 {
method Uint64 (line 33) | func (r *defaultRand) Uint64() uint64 {
function newDefaultRand (line 19) | func newDefaultRand() *defaultRand {
function BenchmarkFastRand32 (line 40) | func BenchmarkFastRand32(b *testing.B) {
function BenchmarkFastRand64 (line 48) | func BenchmarkFastRand64(b *testing.B) {
function BenchmarkDefaultRand32 (line 56) | func BenchmarkDefaultRand32(b *testing.B) {
function BenchmarkDefaultRand64 (line 65) | func BenchmarkDefaultRand64(b *testing.B) {
FILE: internal/ldap/dn.go
type AttributeTypeAndValue (line 30) | type AttributeTypeAndValue struct
method Equal (line 303) | func (a *AttributeTypeAndValue) Equal(other *AttributeTypeAndValue) bo...
type RelativeDN (line 38) | type RelativeDN struct
method Equal (line 278) | func (r *RelativeDN) Equal(other *RelativeDN) bool {
method hasAllAttributes (line 285) | func (r *RelativeDN) hasAllAttributes(attrs []*AttributeTypeAndValue) ...
type DN (line 43) | type DN struct
method Equal (line 220) | func (d *DN) Equal(other *DN) bool {
method RDNsMatch (line 234) | func (d *DN) RDNsMatch(other *DN) bool {
method AncestorOf (line 259) | func (d *DN) AncestorOf(other *DN) bool {
function FromCertSubject (line 49) | func FromCertSubject(subject pkix.Name) (*DN, error) {
function FromRawCertSubject (line 80) | func FromRawCertSubject(rawSubject []byte) (*DN, error) {
function ParseDN (line 126) | func ParseDN(str string) (*DN, error) {
FILE: internal/ldap/dn_test.go
function TestSuccessfulDNParsing (line 12) | func TestSuccessfulDNParsing(t *testing.T) {
function TestErrorDNParsing (line 79) | func TestErrorDNParsing(t *testing.T) {
function TestDNEqual (line 100) | func TestDNEqual(t *testing.T) {
function TestDNAncestor (line 179) | func TestDNAncestor(t *testing.T) {
FILE: internal/ocsp/ocsp.go
constant defaultResponseTTL (line 36) | defaultResponseTTL = 4 * time.Second
constant defaultAddress (line 37) | defaultAddress = "127.0.0.1:8888"
function NewOCSPResponderCustomAddress (line 40) | func NewOCSPResponderCustomAddress(t *testing.T, issuerCertPEM, issuerKe...
function NewOCSPResponder (line 45) | func NewOCSPResponder(t *testing.T, issuerCertPEM, issuerKeyPEM string) ...
function NewOCSPResponderDesignatedCustomAddress (line 50) | func NewOCSPResponderDesignatedCustomAddress(t *testing.T, issuerCertPEM...
function NewOCSPResponderPreferringHTTPMethod (line 55) | func NewOCSPResponderPreferringHTTPMethod(t *testing.T, issuerCertPEM, i...
function NewOCSPResponderCustomTimeout (line 60) | func NewOCSPResponderCustomTimeout(t *testing.T, issuerCertPEM, issuerKe...
function NewOCSPResponderBase (line 65) | func NewOCSPResponderBase(t *testing.T, issuerCertPEM, respCertPEM, resp...
function parseCertPEM (line 190) | func parseCertPEM(t *testing.T, certPEM string) *x509.Certificate {
function parseKeyPEM (line 201) | func parseKeyPEM(t *testing.T, keyPEM string) crypto.Signer {
function parsePEM (line 216) | func parsePEM(t *testing.T, pemPath string) *pem.Block {
function GetOCSPStatus (line 230) | func GetOCSPStatus(s tls.ConnectionState) (*ocsp.Response, error) {
function SetOCSPStatus (line 251) | func SetOCSPStatus(t *testing.T, ocspURL, certPEM string, status int) {
FILE: internal/testhelper/logging.go
type DummyLogger (line 28) | type DummyLogger struct
method CheckContent (line 34) | func (l *DummyLogger) CheckContent(t *testing.T, expectedStr string) {
method aggregate (line 43) | func (l *DummyLogger) aggregate() {
method Noticef (line 49) | func (l *DummyLogger) Noticef(format string, v ...any) {
method Errorf (line 55) | func (l *DummyLogger) Errorf(format string, v ...any) {
method Warnf (line 61) | func (l *DummyLogger) Warnf(format string, v ...any) {
method Fatalf (line 67) | func (l *DummyLogger) Fatalf(format string, v ...any) {
method Debugf (line 73) | func (l *DummyLogger) Debugf(format string, v ...any) {
method Tracef (line 79) | func (l *DummyLogger) Tracef(format string, v ...any) {
method Drain (line 97) | func (l *DummyLogger) Drain() {
method CheckForProhibited (line 106) | func (l *DummyLogger) CheckForProhibited(t *testing.T, reason, needle ...
function NewDummyLogger (line 89) | func NewDummyLogger(retain uint) *DummyLogger {
FILE: logger/log.go
constant defaultLogPerms (line 29) | defaultLogPerms = os.FileMode(0640)
type Logger (line 32) | type Logger struct
method SetSizeLimit (line 298) | func (l *Logger) SetSizeLimit(limit int64) error {
method SetMaxNumFiles (line 311) | func (l *Logger) SetMaxNumFiles(max int) error {
method Close (line 342) | func (l *Logger) Close() error {
method Noticef (line 374) | func (l *Logger) Noticef(format string, v ...any) {
method Warnf (line 379) | func (l *Logger) Warnf(format string, v ...any) {
method Errorf (line 384) | func (l *Logger) Errorf(format string, v ...any) {
method Fatalf (line 389) | func (l *Logger) Fatalf(format string, v ...any) {
method Debugf (line 394) | func (l *Logger) Debugf(format string, v ...any) {
method Tracef (line 401) | func (l *Logger) Tracef(format string, v ...any) {
type LogOption (line 46) | type LogOption interface
type LogUTC (line 51) | type LogUTC
method isLoggerOption (line 53) | func (l LogUTC) isLoggerOption() {}
function logFlags (line 55) | func logFlags(time bool, opts ...LogOption) int {
function NewStdLogger (line 74) | func NewStdLogger(time, debug, trace, colors, pid bool, opts ...LogOptio...
function NewFileLogger (line 98) | func NewFileLogger(filename string, time, debug, trace, pid bool, opts ....
type writerAndCloser (line 126) | type writerAndCloser interface
type fileLogger (line 132) | type fileLogger struct
method setLimit (line 167) | func (l *fileLogger) setLimit(limit int64) {
method setMaxNumFiles (line 178) | func (l *fileLogger) setMaxNumFiles(max int) {
method logDirect (line 184) | func (l *fileLogger) logDirect(label, format string, v ...any) int {
method logPurge (line 205) | func (l *fileLogger) logPurge(fname string) {
method Write (line 240) | func (l *fileLogger) Write(b []byte) (int, error) {
method close (line 284) | func (l *fileLogger) close() error {
function newFileLogger (line 146) | func newFileLogger(filename, pidPrefix string, time bool) (*fileLogger, ...
function NewTestLogger (line 325) | func NewTestLogger(prefix string, time bool) *Logger {
function pidPrefix (line 350) | func pidPrefix() string {
function setPlainLabelFormats (line 354) | func setPlainLabelFormats(l *Logger) {
function setColoredLabelFormats (line 363) | func setColoredLabelFormats(l *Logger) {
FILE: logger/log_test.go
function TestStdLogger (line 28) | func TestStdLogger(t *testing.T) {
function TestStdLoggerWithDebugTraceAndTime (line 45) | func TestStdLoggerWithDebugTraceAndTime(t *testing.T) {
function TestStdLoggerNotice (line 62) | func TestStdLoggerNotice(t *testing.T) {
function TestStdLoggerNoticeWithColor (line 69) | func TestStdLoggerNoticeWithColor(t *testing.T) {
function TestStdLoggerDebug (line 76) | func TestStdLoggerDebug(t *testing.T) {
function TestStdLoggerDebugWithOutDebug (line 83) | func TestStdLoggerDebugWithOutDebug(t *testing.T) {
function TestStdLoggerTrace (line 90) | func TestStdLoggerTrace(t *testing.T) {
function TestStdLoggerTraceWithOutDebug (line 97) | func TestStdLoggerTraceWithOutDebug(t *testing.T) {
function TestFileLogger (line 104) | func TestFileLogger(t *testing.T) {
function TestFileLoggerSizeLimit (line 166) | func TestFileLoggerSizeLimit(t *testing.T) {
type fileLogFailClose (line 285) | type fileLogFailClose struct
method Close (line 290) | func (l *fileLogFailClose) Close() error {
function expectOutput (line 297) | func expectOutput(t *testing.T, f func(), expected string) {
function createFileAtDir (line 320) | func createFileAtDir(t *testing.T, dir, prefix string) *os.File {
FILE: logger/syslog.go
type SysLogger (line 28) | type SysLogger struct
method Noticef (line 101) | func (l *SysLogger) Noticef(format string, v ...any) {
method Warnf (line 106) | func (l *SysLogger) Warnf(format string, v ...any) {
method Fatalf (line 111) | func (l *SysLogger) Fatalf(format string, v ...any) {
method Errorf (line 116) | func (l *SysLogger) Errorf(format string, v ...any) {
method Debugf (line 121) | func (l *SysLogger) Debugf(format string, v ...any) {
method Tracef (line 128) | func (l *SysLogger) Tracef(format string, v ...any) {
function SetSyslogName (line 36) | func SetSyslogName(name string) {}
function GetSysLoggerTag (line 42) | func GetSysLoggerTag() string {
function NewSysLogger (line 54) | func NewSysLogger(debug, trace bool) *SysLogger {
function NewRemoteSysLogger (line 68) | func NewRemoteSysLogger(fqn string, debug, trace bool) *SysLogger {
function getNetworkAndAddr (line 82) | func getNetworkAndAddr(fqn string) (network, addr string) {
FILE: logger/syslog_test.go
function TestSysLogger (line 31) | func TestSysLogger(t *testing.T) {
function TestSysLoggerWithDebugAndTrace (line 43) | func TestSysLoggerWithDebugAndTrace(t *testing.T) {
function testTag (line 55) | func testTag(t *testing.T, exePath, expected string) {
function restoreArg (line 62) | func restoreArg(orig string) {
function TestSysLoggerTagGen (line 66) | func TestSysLoggerTagGen(t *testing.T) {
function TestSysLoggerTag (line 80) | func TestSysLoggerTag(t *testing.T) {
function TestRemoteSysLogger (line 102) | func TestRemoteSysLogger(t *testing.T) {
function TestRemoteSysLoggerNotice (line 118) | func TestRemoteSysLoggerNotice(t *testing.T) {
function TestRemoteSysLoggerDebug (line 127) | func TestRemoteSysLoggerDebug(t *testing.T) {
function TestRemoteSysLoggerDebugDisabled (line 136) | func TestRemoteSysLoggerDebugDisabled(t *testing.T) {
function TestRemoteSysLoggerTrace (line 148) | func TestRemoteSysLoggerTrace(t *testing.T) {
function TestRemoteSysLoggerTraceDisabled (line 157) | func TestRemoteSysLoggerTraceDisabled(t *testing.T) {
function TestGetNetworkAndAddrUDP (line 169) | func TestGetNetworkAndAddrUDP(t *testing.T) {
function TestGetNetworkAndAddrTCP (line 181) | func TestGetNetworkAndAddrTCP(t *testing.T) {
function TestGetNetworkAndAddrUnix (line 193) | func TestGetNetworkAndAddrUnix(t *testing.T) {
function expectSyslogOutput (line 204) | func expectSyslogOutput(t *testing.T, line string, expected string) {
function runSyslog (line 215) | func runSyslog(c net.PacketConn, done chan<- string) {
function startServer (line 228) | func startServer(done chan<- string) {
FILE: logger/syslog_windows.go
function SetSyslogName (line 28) | func SetSyslogName(name string) {
type SysLogger (line 33) | type SysLogger struct
method Noticef (line 79) | func (l *SysLogger) Noticef(format string, v ...any) {
method Warnf (line 84) | func (l *SysLogger) Warnf(format string, v ...any) {
method Fatalf (line 89) | func (l *SysLogger) Fatalf(format string, v ...any) {
method Errorf (line 96) | func (l *SysLogger) Errorf(format string, v ...any) {
method Debugf (line 101) | func (l *SysLogger) Debugf(format string, v ...any) {
method Tracef (line 108) | func (l *SysLogger) Tracef(format string, v ...any) {
function NewSysLogger (line 40) | func NewSysLogger(debug, trace bool) *SysLogger {
function NewRemoteSysLogger (line 60) | func NewRemoteSysLogger(fqn string, debug, trace bool) *SysLogger {
function formatMsg (line 73) | func formatMsg(tag, format string, v ...any) string {
FILE: logger/syslog_windows_test.go
function checkPrivledges (line 28) | func checkPrivledges(t *testing.T) {
function lastLogEntryContains (line 43) | func lastLogEntryContains(t *testing.T, text string) bool {
function TestSysLogger (line 56) | func TestSysLogger(t *testing.T) {
function TestSysLoggerWithDebugAndTrace (line 88) | func TestSysLoggerWithDebugAndTrace(t *testing.T) {
function TestRemoteSysLoggerWithDebugAndTrace (line 111) | func TestRemoteSysLoggerWithDebugAndTrace(t *testing.T) {
function TestSysLoggerFatalf (line 127) | func TestSysLoggerFatalf(t *testing.T) {
FILE: main.go
function usage (line 92) | func usage() {
function main (line 97) | func main() {
FILE: server/accounts.go
constant globalAccountName (line 44) | globalAccountName = DEFAULT_GLOBAL_ACCOUNT
constant defaultMaxSubLimitReportThreshold (line 46) | defaultMaxSubLimitReportThreshold = int64(2 * time.Second)
type Account (line 52) | type Account struct
method String (line 281) | func (a *Account) String() string {
method setTraceDest (line 285) | func (a *Account) setTraceDest(dest string) {
method getTraceDestAndSampling (line 291) | func (a *Account) getTraceDestAndSampling() (string, int) {
method shallowCopy (line 304) | func (a *Account) shallowCopy(na *Account) {
method nextEventID (line 360) | func (a *Account) nextEventID() string {
method getClientsLocked (line 369) | func (a *Account) getClientsLocked() []*client {
method getClients (line 381) | func (a *Account) getClients() []*client {
method getExternalClientsLocked (line 390) | func (a *Account) getExternalClientsLocked() []*client {
method updateRemoteServer (line 405) | func (a *Account) updateRemoteServer(m *AccountNumConns) []*client {
method removeRemoteServer (line 452) | func (a *Account) removeRemoteServer(sid string) {
method expectedRemoteResponses (line 466) | func (a *Account) expectedRemoteResponses() (expected int32) {
method clearEventing (line 478) | func (a *Account) clearEventing() {
method GetName (line 490) | func (a *Account) GetName() string {
method getNameTag (line 501) | func (a *Account) getNameTag() string {
method getNameTagLocked (line 512) | func (a *Account) getNameTagLocked() string {
method NumConnections (line 525) | func (a *Account) NumConnections() int {
method NumRemoteConnections (line 534) | func (a *Account) NumRemoteConnections() int {
method NumLocalConnections (line 543) | func (a *Account) NumLocalConnections() int {
method numLocalConnections (line 551) | func (a *Account) numLocalConnections() int {
method numLocalAndLeafConnections (line 557) | func (a *Account) numLocalAndLeafConnections() int {
method numLocalLeafNodes (line 564) | func (a *Account) numLocalLeafNodes() int {
method MaxTotalConnectionsReached (line 569) | func (a *Account) MaxTotalConnectionsReached() bool {
method MaxActiveConnections (line 581) | func (a *Account) MaxActiveConnections() int {
method MaxTotalLeafNodesReached (line 589) | func (a *Account) MaxTotalLeafNodesReached() bool {
method maxTotalLeafNodesReached (line 596) | func (a *Account) maxTotalLeafNodesReached() bool {
method NumLeafNodes (line 605) | func (a *Account) NumLeafNodes() int {
method NumRemoteLeafNodes (line 614) | func (a *Account) NumRemoteLeafNodes() int {
method MaxActiveLeafNodes (line 624) | func (a *Account) MaxActiveLeafNodes() int {
method RoutedSubs (line 633) | func (a *Account) RoutedSubs() int {
method TotalSubs (line 640) | func (a *Account) TotalSubs() int {
method shouldLogMaxSubErr (line 649) | func (a *Account) shouldLogMaxSubErr() bool {
method AddMapping (line 692) | func (a *Account) AddMapping(src, dest string) error {
method AddWeightedMappings (line 697) | func (a *Account) AddWeightedMappings(src string, dests ...*MapDest) e...
method RemoveMapping (line 816) | func (a *Account) RemoveMapping(src string) bool {
method hasMappings (line 845) | func (a *Account) hasMappings() bool {
method selectMappedSubject (line 854) | func (a *Account) selectMappedSubject(dest string) (string, bool) {
method SubscriptionInterest (line 935) | func (a *Account) SubscriptionInterest(subject string) bool {
method Interest (line 940) | func (a *Account) Interest(subject string) int {
method addClient (line 953) | func (a *Account) addClient(c *client) int {
method registerLeafNodeCluster (line 992) | func (a *Account) registerLeafNodeCluster(cluster string) {
method hasLeafNodeCluster (line 1002) | func (a *Account) hasLeafNodeCluster(cluster string) bool {
method isLeafNodeClusterIsolated (line 1010) | func (a *Account) isLeafNodeClusterIsolated(cluster string) bool {
method removeLeafNode (line 1024) | func (a *Account) removeLeafNode(c *client) {
method removeClient (line 1044) | func (a *Account) removeClient(c *client) int {
method AddServiceExport (line 1107) | func (a *Account) AddServiceExport(subject string, accounts []*Account...
method addServiceExportWithAccountPos (line 1112) | func (a *Account) addServiceExportWithAccountPos(subject string, accou...
method AddServiceExportWithResponse (line 1117) | func (a *Account) AddServiceExportWithResponse(subject string, respTyp...
method addServiceExportWithResponseAndAccountPos (line 1122) | func (a *Account) addServiceExportWithResponseAndAccountPos(
method TrackServiceExport (line 1169) | func (a *Account) TrackServiceExport(service, results string) error {
method TrackServiceExportWithSampling (line 1175) | func (a *Account) TrackServiceExportWithSampling(service, results stri...
method UnTrackServiceExport (line 1244) | func (a *Account) UnTrackServiceExport(service string) {
method IsExportService (line 1287) | func (a *Account) IsExportService(service string) bool {
method IsExportServiceTracking (line 1304) | func (a *Account) IsExportServiceTracking(service string) bool {
method sendLatencyResult (line 1394) | func (a *Account) sendLatencyResult(si *serviceImport, sl *ServiceLate...
method sendBadRequestTrackingLatency (line 1407) | func (a *Account) sendBadRequestTrackingLatency(si *serviceImport, req...
method sendReplyInterestLostTrackLatency (line 1420) | func (a *Account) sendReplyInterestLostTrackLatency(si *serviceImport) {
method sendBackendErrorTrackingLatency (line 1436) | func (a *Account) sendBackendErrorTrackingLatency(si *serviceImport, r...
method sendTrackingLatency (line 1464) | func (a *Account) sendTrackingLatency(si *serviceImport, responder *cl...
method lowestServiceExportResponseTime (line 1548) | func (a *Account) lowestServiceExportResponseTime() time.Duration {
method AddServiceImportWithClaim (line 1560) | func (a *Account) AddServiceImportWithClaim(destination *Account, from...
method addServiceImportWithClaim (line 1566) | func (a *Account) addServiceImportWithClaim(destination *Account, from...
method serviceImportFormsCycle (line 1601) | func (a *Account) serviceImportFormsCycle(dest *Account, from string) ...
method checkServiceImportsForCycles (line 1605) | func (a *Account) checkServiceImportsForCycles(from string, visited ma...
method streamImportFormsCycle (line 1635) | func (a *Account) streamImportFormsCycle(dest *Account, to string) err...
method hasServiceExportMatching (line 1640) | func (a *Account) hasServiceExportMatching(to string) bool {
method hasStreamExportMatching (line 1650) | func (a *Account) hasStreamExportMatching(to string) bool {
method checkStreamImportsForCycles (line 1659) | func (a *Account) checkStreamImportsForCycles(to string, visited map[s...
method SetServiceImportSharing (line 1696) | func (a *Account) SetServiceImportSharing(destination *Account, to str...
method setServiceImportSharing (line 1701) | func (a *Account) setServiceImportSharing(destination *Account, to str...
method AddServiceImport (line 1725) | func (a *Account) AddServiceImport(destination *Account, from, to stri...
method NumPendingReverseResponses (line 1731) | func (a *Account) NumPendingReverseResponses() int {
method NumPendingAllResponses (line 1738) | func (a *Account) NumPendingAllResponses() int {
method NumPendingResponses (line 1746) | func (a *Account) NumPendingResponses(filter string) int {
method NumServiceImports (line 1766) | func (a *Account) NumServiceImports() int {
method removeRespServiceImport (line 1782) | func (a *Account) removeRespServiceImport(si *serviceImport, reason rs...
method getServiceImportForAccountLocked (line 1805) | func (a *Account) getServiceImportForAccountLocked(dstAccName, subject...
method removeServiceImport (line 1822) | func (a *Account) removeServiceImport(dstAccName, subject string) {
method addReverseRespMapEntry (line 1868) | func (a *Account) addReverseRespMapEntry(acc *Account, reply, from str...
method checkForReverseEntries (line 1882) | func (a *Account) checkForReverseEntries(reply string, checkInterest, ...
method checkForReverseEntry (line 1920) | func (a *Account) checkForReverseEntry(reply string, si *serviceImport...
method _checkForReverseEntry (line 1926) | func (a *Account) _checkForReverseEntry(reply string, si *serviceImpor...
method serviceImportShadowed (line 2025) | func (a *Account) serviceImportShadowed(from string) bool {
method serviceImportExists (line 2041) | func (a *Account) serviceImportExists(dstAccName, from string) bool {
method addServiceImport (line 2051) | func (a *Account) addServiceImport(dest *Account, from, to string, cla...
method internalClient (line 2126) | func (a *Account) internalClient() *client {
method subscribeInternal (line 2135) | func (a *Account) subscribeInternal(subject string, cb msgHandler) (*s...
method unsubscribeInternal (line 2140) | func (a *Account) unsubscribeInternal(sub *subscription) {
method subscribeServiceImportResponse (line 2147) | func (a *Account) subscribeServiceImportResponse(subject string) (*sub...
method subscribeInternalEx (line 2151) | func (a *Account) subscribeInternalEx(subject string, cb msgHandler, r...
method addServiceImportSub (line 2166) | func (a *Account) addServiceImportSub(si *serviceImport) error {
method removeAllServiceImportSubs (line 2200) | func (a *Account) removeAllServiceImportSubs() {
method addAllServiceImportSubs (line 2225) | func (a *Account) addAllServiceImportSubs() {
method processServiceImportResponse (line 2368) | func (a *Account) processServiceImportResponse(sub *subscription, c *c...
method createRespWildcard (line 2390) | func (a *Account) createRespWildcard() {
method newServiceReply (line 2408) | func (a *Account) newServiceReply(tracking bool) []byte {
method ServiceExportResponseThreshold (line 2520) | func (a *Account) ServiceExportResponseThreshold(export string) (time....
method SetServiceExportResponseThreshold (line 2532) | func (a *Account) SetServiceExportResponseThreshold(export string, max...
method SetServiceExportAllowTrace (line 2559) | func (a *Account) SetServiceExportAllowTrace(export string, allowTrace...
method addRespServiceImport (line 2572) | func (a *Account) addRespServiceImport(dest *Account, to string, osi *...
method AddStreamImportWithClaim (line 2608) | func (a *Account) AddStreamImportWithClaim(account *Account, from, pre...
method addStreamImportWithClaim (line 2612) | func (a *Account) addStreamImportWithClaim(account *Account, from, pre...
method AddMappedStreamImport (line 2639) | func (a *Account) AddMappedStreamImport(account *Account, from, to str...
method AddMappedStreamImportWithClaim (line 2644) | func (a *Account) AddMappedStreamImportWithClaim(account *Account, fro...
method addMappedStreamImportWithClaim (line 2648) | func (a *Account) addMappedStreamImportWithClaim(account *Account, fro...
method isStreamImportDuplicate (line 2704) | func (a *Account) isStreamImportDuplicate(acc *Account, from string) b...
method AddStreamImport (line 2714) | func (a *Account) AddStreamImport(account *Account, from, prefix strin...
method AddStreamExport (line 2723) | func (a *Account) AddStreamExport(subject string, accounts []*Account)...
method addStreamExportWithAccountPos (line 2731) | func (a *Account) addStreamExportWithAccountPos(subject string, accoun...
method checkStreamImportAuthorized (line 2756) | func (a *Account) checkStreamImportAuthorized(account *Account, subjec...
method checkStreamImportAuthorizedNoLock (line 2764) | func (a *Account) checkStreamImportAuthorizedNoLock(account *Account, ...
method checkAuth (line 2771) | func (a *Account) checkAuth(ea *exportAuth, account *Account, imClaim ...
method checkStreamExportApproved (line 2792) | func (a *Account) checkStreamExportApproved(account *Account, subject ...
method checkServiceExportApproved (line 2819) | func (a *Account) checkServiceExportApproved(account *Account, subject...
method getServiceExport (line 2847) | func (a *Account) getServiceExport(subj string) *serviceExport {
method getWildcardServiceExport (line 2859) | func (a *Account) getWildcardServiceExport(from string) *serviceExport {
method streamActivationExpired (line 2870) | func (a *Account) streamActivationExpired(exportAcc *Account, subject ...
method serviceActivationExpired (line 2905) | func (a *Account) serviceActivationExpired(dstAcc *Account, subject st...
method activationExpired (line 2930) | func (a *Account) activationExpired(exportAcc *Account, subject string...
method checkActivation (line 2953) | func (a *Account) checkActivation(importAcc *Account, claim *jwt.Impor...
method isIssuerClaimTrusted (line 2998) | func (a *Account) isIssuerClaimTrusted(claims *jwt.ActivationClaims) b...
method checkStreamImportsEqual (line 3021) | func (a *Account) checkStreamImportsEqual(b *Account) bool {
method checkStreamExportsEqual (line 3046) | func (a *Account) checkStreamExportsEqual(b *Account) bool {
method checkServiceExportsEqual (line 3077) | func (a *Account) checkServiceExportsEqual(b *Account) bool {
method checkServiceImportAuthorized (line 3158) | func (a *Account) checkServiceImportAuthorized(account *Account, subje...
method checkServiceImportAuthorizedNoLock (line 3166) | func (a *Account) checkServiceImportAuthorizedNoLock(account *Account,...
method IsExpired (line 3175) | func (a *Account) IsExpired() bool {
method expiredTimeout (line 3180) | func (a *Account) expiredTimeout() {
method setExpirationTimer (line 3194) | func (a *Account) setExpirationTimer(d time.Duration) {
method clearExpirationTimer (line 3199) | func (a *Account) clearExpirationTimer() bool {
method checkUserRevoked (line 3209) | func (a *Account) checkUserRevoked(nkey string, issuedAt int64) bool {
method failBearer (line 3216) | func (a *Account) failBearer() bool {
method checkExpiration (line 3223) | func (a *Account) checkExpiration(claims *jwt.ClaimsData) {
method hasIssuer (line 3245) | func (a *Account) hasIssuer(issuer string) (jwt.Scope, bool) {
method hasIssuerNoLock (line 3253) | func (a *Account) hasIssuerNoLock(issuer string) (jwt.Scope, bool) {
method getLDSubject (line 3259) | func (a *Account) getLDSubject() string {
method isClaimAccount (line 3293) | func (a *Account) isClaimAccount() bool {
method traceLabel (line 3304) | func (a *Account) traceLabel() string {
method hasExternalAuth (line 3316) | func (a *Account) hasExternalAuth() bool {
method isExternalAuthUser (line 3326) | func (a *Account) isExternalAuthUser(userID string) bool {
method externalAuthXKey (line 3344) | func (a *Account) externalAuthXKey() string {
method isAllowedAcount (line 3357) | func (a *Account) isAllowedAcount(acc string) bool {
constant accDedicatedRoute (line 122) | accDedicatedRoute = -1
constant accTransitioningToDedicatedRoute (line 123) | accTransitioningToDedicatedRoute = -2
type limits (line 127) | type limits struct
type sconns (line 136) | type sconns struct
function clampInt64ToInt32 (line 143) | func clampInt64ToInt32(v int64) int32 {
type streamImport (line 148) | type streamImport struct
constant ClientInfoHdr (line 163) | ClientInfoHdr = "Nats-Request-Info"
type serviceImport (line 166) | type serviceImport struct
method isRespServiceImport (line 2450) | func (si *serviceImport) isRespServiceImport() bool {
type serviceRespEntry (line 193) | type serviceRespEntry struct
type ServiceRespType (line 199) | type ServiceRespType
method String (line 209) | func (rt ServiceRespType) String() string {
constant Singleton (line 203) | Singleton ServiceRespType = iota
constant Streamed (line 204) | Streamed
constant Chunked (line 205) | Chunked
type exportAuth (line 223) | type exportAuth struct
type streamExport (line 231) | type streamExport struct
type serviceExport (line 236) | type serviceExport struct
method setResponseThresholdTimer (line 2456) | func (se *serviceExport) setResponseThresholdTimer() {
method clearResponseThresholdTimer (line 2464) | func (se *serviceExport) clearResponseThresholdTimer() bool {
method checkExpiredResponses (line 2475) | func (se *serviceExport) checkExpiredResponses() {
type serviceLatency (line 251) | type serviceLatency struct
type exportMap (line 257) | type exportMap struct
type importMap (line 265) | type importMap struct
function NewAccount (line 272) | func NewAccount(name string) *Account {
type MapDest (line 666) | type MapDest struct
function NewMapDest (line 672) | func NewMapDest(subject string, weight uint8) *MapDest {
type destination (line 677) | type destination struct
type mapping (line 683) | type mapping struct
function setExportAuth (line 1081) | func setExportAuth(ea *exportAuth, subject string, accounts []*Account, ...
type ServiceLatency (line 1332) | type ServiceLatency struct
method NATSTotalTime (line 1349) | func (m1 *ServiceLatency) NATSTotalTime() time.Duration {
method merge (line 1360) | func (m1 *ServiceLatency) merge(m2 *ServiceLatency) {
constant ServiceLatencyType (line 1346) | ServiceLatencyType = "io.nats.server.metric.v1.service_latency"
function sanitizeLatencyMetric (line 1376) | func sanitizeLatencyMetric(sl *ServiceLatency) {
type remoteLatency (line 1386) | type remoteLatency struct
function updateAllClientsServiceExportResponseTime (line 1533) | func updateAllClientsServiceExportResponseTime(clients []*client, lrt ti...
constant MaxAccountCycleSearchDepth (line 1599) | MaxAccountCycleSearchDepth = 1024
type rsiReason (line 1773) | type rsiReason
constant rsiOk (line 1776) | rsiOk = rsiReason(iota)
constant rsiNoDelivery (line 1777) | rsiNoDelivery
constant rsiTimeout (line 1778) | rsiTimeout
function newB3Header (line 2253) | func newB3Header(h http.Header) http.Header {
function newUberHeader (line 2270) | func newUberHeader(h http.Header, tId []string) http.Header {
function newTraceCtxHeader (line 2280) | func newTraceCtxHeader(h http.Header, tId []string) http.Header {
function shouldSample (line 2289) | func shouldSample(l *serviceLatency, c *client) (bool, http.Header) {
constant replyPrefix (line 2358) | replyPrefix = "_R_."
constant replyPrefixLen (line 2359) | replyPrefixLen = len(replyPrefix)
constant baseServerLen (line 2360) | baseServerLen = 10
constant replyLen (line 2361) | replyLen = 6
constant minReplyLen (line 2362) | minReplyLen = 15
constant digits (line 2363) | digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr...
constant base (line 2364) | base = 62
function isTrackedReply (line 2401) | func isTrackedReply(reply []byte) bool {
function isRevoked (line 2939) | func isRevoked(revocations map[string]int64, subject string, issuedAt in...
function isStreamExportEqual (line 3064) | func isStreamExportEqual(a, b *streamExport) bool {
function isServiceExportEqual (line 3095) | func isServiceExportEqual(a, b *serviceExport) bool {
function isExportAuthEqual (line 3131) | func isExportAuthEqual(a, b *exportAuth) bool {
function authAccounts (line 3269) | func authAccounts(tokenReq bool) []*Account {
method SetAccountResolver (line 3277) | func (s *Server) SetAccountResolver(ar AccountResolver) {
method AccountResolver (line 3284) | func (s *Server) AccountResolver() AccountResolver {
method UpdateAccountClaims (line 3300) | func (s *Server) UpdateAccountClaims(a *Account, ac *jwt.AccountClaims) {
method updateAccountClaimsWithRefresh (line 3384) | func (s *Server) updateAccountClaimsWithRefresh(a *Account, ac *jwt.Acco...
method buildInternalAccount (line 3967) | func (s *Server) buildInternalAccount(ac *jwt.AccountClaims) *Account {
function buildPermissionsFromJwt (line 3989) | func buildPermissionsFromJwt(uc *jwt.Permissions) *Permissions {
function buildInternalNkeyUser (line 4022) | func buildInternalNkeyUser(uc *jwt.UserClaims, acts map[string]struct{},...
function fetchAccount (line 4037) | func fetchAccount(res AccountResolver, name string) (string, error) {
type AccountResolver (line 4045) | type AccountResolver interface
type resolverDefaultsOpsImpl (line 4056) | type resolverDefaultsOpsImpl struct
method IsReadOnly (line 4058) | func (*resolverDefaultsOpsImpl) IsReadOnly() bool {
method IsTrackingUpdate (line 4062) | func (*resolverDefaultsOpsImpl) IsTrackingUpdate() bool {
method Start (line 4066) | func (*resolverDefaultsOpsImpl) Start(*Server) error {
method Reload (line 4070) | func (*resolverDefaultsOpsImpl) Reload() error {
method Close (line 4074) | func (*resolverDefaultsOpsImpl) Close() {
method Store (line 4077) | func (*resolverDefaultsOpsImpl) Store(_, _ string) error {
type MemAccResolver (line 4083) | type MemAccResolver struct
method Fetch (line 4089) | func (m *MemAccResolver) Fetch(name string) (string, error) {
method Store (line 4097) | func (m *MemAccResolver) Store(name, jwt string) error {
method IsReadOnly (line 4102) | func (m *MemAccResolver) IsReadOnly() bool {
type URLAccResolver (line 4107) | type URLAccResolver struct
method Fetch (line 4133) | func (ur *URLAccResolver) Fetch(name string) (string, error) {
function NewURLAccResolver (line 4114) | func NewURLAccResolver(url string) (*URLAccResolver, error) {
type DirAccResolver (line 4153) | type DirAccResolver struct
method IsTrackingUpdate (line 4160) | func (dr *DirAccResolver) IsTrackingUpdate() bool {
method Reload (line 4164) | func (dr *DirAccResolver) Reload() error {
method Start (line 4362) | func (dr *DirAccResolver) Start(s *Server) error {
method Fetch (line 4543) | func (dr *DirAccResolver) Fetch(name string) (string, error) {
method Store (line 4558) | func (dr *DirAccResolver) Store(name, jwt string) error {
method apply (line 4575) | func (dr *DirAccResolver) apply(opts ...DirResOption) error {
type ServerAPIClaimUpdateResponse (line 4169) | type ServerAPIClaimUpdateResponse struct
type ClaimUpdateError (line 4175) | type ClaimUpdateError struct
type ClaimUpdateStatus (line 4181) | type ClaimUpdateStatus struct
function respondToUpdate (line 4187) | func respondToUpdate(s *Server, respSubj string, acc string, message str...
function handleListRequest (line 4226) | func handleListRequest(store *DirJWTStore, s *Server, reply string) {
function handleDeleteRequest (line 4246) | func handleDeleteRequest(store *DirJWTStore, s *Server, msg []byte, repl...
function getOperatorKeys (line 4300) | func getOperatorKeys(s *Server) (string, map[string]struct{}, bool, erro...
function claimValidate (line 4320) | func claimValidate(claim *jwt.AccountClaims) error {
function removeCb (line 4329) | func removeCb(s *Server, pubKey string) {
type DirResOption (line 4562) | type DirResOption
function FetchTimeout (line 4565) | func FetchTimeout(to time.Duration) DirResOption {
function NewDirAccResolver (line 4584) | func NewDirAccResolver(path string, limit int64, syncInterval time.Durat...
type CacheDirAccResolver (line 4604) | type CacheDirAccResolver struct
method Start (line 4689) | func (dr *CacheDirAccResolver) Start(s *Server) error {
method Reload (line 4782) | func (dr *CacheDirAccResolver) Reload() error {
method fetch (line 4609) | func (s *Server) fetch(res AccountResolver, name string, timeout time.Du...
function NewCacheDirAccResolver (line 4674) | func NewCacheDirAccResolver(path string, limit int64, ttl time.Duration,...
FILE: server/accounts_test.go
function simpleAccountServer (line 34) | func simpleAccountServer(t *testing.T) (*Server, *Account, *Account) {
function TestRegisterDuplicateAccounts (line 50) | func TestRegisterDuplicateAccounts(t *testing.T) {
function TestAccountIsolation (line 57) | func TestAccountIsolation(t *testing.T) {
function TestAccountIsolationExportImport (line 111) | func TestAccountIsolationExportImport(t *testing.T) {
function TestMultiAccountsIsolation (line 304) | func TestMultiAccountsIsolation(t *testing.T) {
function TestAccountFromOptions (line 386) | func TestAccountFromOptions(t *testing.T) {
function TestNewAccountAndRequireNewAlwaysError (line 410) | func TestNewAccountAndRequireNewAlwaysError(t *testing.T) {
function accountNameExists (line 471) | func accountNameExists(name string, accounts []*Account) bool {
function TestAccountSimpleConfig (line 480) | func TestAccountSimpleConfig(t *testing.T) {
function TestAccountParseConfig (line 512) | func TestAccountParseConfig(t *testing.T) {
function TestAccountParseConfigDuplicateUsers (line 568) | func TestAccountParseConfigDuplicateUsers(t *testing.T) {
function TestAccountParseConfigImportsExports (line 590) | func TestAccountParseConfigImportsExports(t *testing.T) {
function TestImportExportConfigFailures (line 692) | func TestImportExportConfigFailures(t *testing.T) {
function TestImportAuthorized (line 761) | func TestImportAuthorized(t *testing.T) {
function TestSimpleMapping (line 845) | func TestSimpleMapping(t *testing.T) {
function TestStreamImportLengthBug (line 939) | func TestStreamImportLengthBug(t *testing.T) {
function TestShadowSubsCleanupOnClientClose (line 988) | func TestShadowSubsCleanupOnClientClose(t *testing.T) {
function TestNoPrefixWildcardMapping (line 1028) | func TestNoPrefixWildcardMapping(t *testing.T) {
function TestPrefixWildcardMapping (line 1081) | func TestPrefixWildcardMapping(t *testing.T) {
function TestPrefixWildcardMappingWithLiteralSub (line 1135) | func TestPrefixWildcardMappingWithLiteralSub(t *testing.T) {
function TestMultipleImportsAndSingleWCSub (line 1188) | func TestMultipleImportsAndSingleWCSub(t *testing.T) {
function TestAddServiceExport (line 1282) | func TestAddServiceExport(t *testing.T) {
function TestServiceExportWithWildcards (line 1319) | func TestServiceExportWithWildcards(t *testing.T) {
function TestAccountAddServiceImportRace (line 1424) | func TestAccountAddServiceImportRace(t *testing.T) {
function TestServiceImportWithWildcards (line 1463) | func TestServiceImportWithWildcards(t *testing.T) {
function TestAddStreamExport (line 1560) | func TestAddStreamExport(t *testing.T) {
function TestCrossAccountRequestReply (line 1597) | func TestCrossAccountRequestReply(t *testing.T) {
function TestAccountRequestReplyTrackLatency (line 1692) | func TestAccountRequestReplyTrackLatency(t *testing.T) {
function TestAccountTrackLatencyRemoteLeaks (line 1818) | func TestAccountTrackLatencyRemoteLeaks(t *testing.T) {
function TestCrossAccountServiceResponseTypes (line 2005) | func TestCrossAccountServiceResponseTypes(t *testing.T) {
function TestAccountMapsUsers (line 2138) | func TestAccountMapsUsers(t *testing.T) {
function TestAccountGlobalDefault (line 2254) | func TestAccountGlobalDefault(t *testing.T) {
function TestAccountCheckStreamImportsEqual (line 2274) | func TestAccountCheckStreamImportsEqual(t *testing.T) {
function TestAccountNoDeadlockOnQueueSubRouteMapUpdate (line 2370) | func TestAccountNoDeadlockOnQueueSubRouteMapUpdate(t *testing.T) {
function TestAccountDuplicateServiceImportSubject (line 2411) | func TestAccountDuplicateServiceImportSubject(t *testing.T) {
function TestAccountRemoveServiceImport (line 2447) | func TestAccountRemoveServiceImport(t *testing.T) {
function TestAccountMultipleServiceImportsWithSameSubjectFromDifferentAccounts (line 2535) | func TestAccountMultipleServiceImportsWithSameSubjectFromDifferentAccoun...
function TestMultipleStreamImportsWithSameSubjectDifferentPrefix (line 2590) | func TestMultipleStreamImportsWithSameSubjectDifferentPrefix(t *testing....
function TestMultipleStreamImportsWithSameSubject (line 2657) | func TestMultipleStreamImportsWithSameSubject(t *testing.T) {
function TestAccountBasicRouteMapping (line 2728) | func TestAccountBasicRouteMapping(t *testing.T) {
function TestAccountWildcardRouteMapping (line 2764) | func TestAccountWildcardRouteMapping(t *testing.T) {
function TestAccountRouteMappingChangesAfterClientStart (line 2814) | func TestAccountRouteMappingChangesAfterClientStart(t *testing.T) {
function TestAccountSimpleWeightedRouteMapping (line 2853) | func TestAccountSimpleWeightedRouteMapping(t *testing.T) {
function TestAccountMultiWeightedRouteMappings (line 2885) | func TestAccountMultiWeightedRouteMappings(t *testing.T) {
function TestGlobalAccountRouteMappingsConfiguration (line 2954) | func TestGlobalAccountRouteMappingsConfiguration(t *testing.T) {
function TestAccountRouteMappingsConfiguration (line 3004) | func TestAccountRouteMappingsConfiguration(t *testing.T) {
function TestAccountRouteMappingsWithLossInjection (line 3040) | func TestAccountRouteMappingsWithLossInjection(t *testing.T) {
function TestAccountRouteMappingsWithOriginClusterFilter (line 3078) | func TestAccountRouteMappingsWithOriginClusterFilter(t *testing.T) {
function TestAccountServiceImportWithRouteMappings (line 3116) | func TestAccountServiceImportWithRouteMappings(t *testing.T) {
function TestAccountImportsWithWildcardSupport (line 3159) | func TestAccountImportsWithWildcardSupport(t *testing.T) {
function TestAccountImportsWithWildcardSupportStreamAndService (line 3254) | func TestAccountImportsWithWildcardSupportStreamAndService(t *testing.T) {
function BenchmarkNewRouteReply (line 3319) | func BenchmarkNewRouteReply(b *testing.B) {
function TestSamplingHeader (line 3329) | func TestSamplingHeader(t *testing.T) {
function TestAccountSystemPermsWithGlobalAccess (line 3391) | func TestAccountSystemPermsWithGlobalAccess(t *testing.T) {
constant importSubscriptionOverlapTemplate (line 3417) | importSubscriptionOverlapTemplate = `
function TestImportSubscriptionPartialOverlapWithPrefix (line 3438) | func TestImportSubscriptionPartialOverlapWithPrefix(t *testing.T) {
function TestImportSubscriptionPartialOverlapWithTransform (line 3466) | func TestImportSubscriptionPartialOverlapWithTransform(t *testing.T) {
function TestAccountLimitsServerConfig (line 3498) | func TestAccountLimitsServerConfig(t *testing.T) {
function TestAccountMaxConnectionsDisconnectsNewestFirst (line 3541) | func TestAccountMaxConnectionsDisconnectsNewestFirst(t *testing.T) {
function TestAccountUpdateRemoteServerDisconnectsNewestFirst (line 3619) | func TestAccountUpdateRemoteServerDisconnectsNewestFirst(t *testing.T) {
function TestAccountMaxConnectionsDuringLameDuckMode (line 3694) | func TestAccountMaxConnectionsDuringLameDuckMode(t *testing.T) {
function TestAccountUserSubPermsWithQueueGroups (line 3761) | func TestAccountUserSubPermsWithQueueGroups(t *testing.T) {
function TestAccountImportCycle (line 3796) | func TestAccountImportCycle(t *testing.T) {
function TestAccountImportOwnExport (line 3858) | func TestAccountImportOwnExport(t *testing.T) {
function TestAccountImportDuplicateResponseDeliveryWithLeafnodes (line 3890) | func TestAccountImportDuplicateResponseDeliveryWithLeafnodes(t *testing....
function TestAccountReloadServiceImportPanic (line 3961) | func TestAccountReloadServiceImportPanic(t *testing.T) {
function TestAccountServiceAndStreamExportDoubleDelivery (line 4035) | func TestAccountServiceAndStreamExportDoubleDelivery(t *testing.T) {
function TestAccountServiceImportNoResponders (line 4077) | func TestAccountServiceImportNoResponders(t *testing.T) {
FILE: server/ats/ats.go
constant TickInterval (line 25) | TickInterval = 100 * time.Millisecond
function init (line 36) | func init() {
function Register (line 42) | func Register() {
function Unregister (line 64) | func Unregister() {
function AccessTime (line 76) | func AccessTime() int64 {
FILE: server/ats/ats_test.go
function TestNotRunningValue (line 22) | func TestNotRunningValue(t *testing.T) {
function TestRegisterAndUnregister (line 36) | func TestRegisterAndUnregister(t *testing.T) {
function TestUnbalancedUnregister (line 91) | func TestUnbalancedUnregister(t *testing.T) {
FILE: server/auth.go
type Authentication (line 40) | type Authentication interface
type ClientAuthentication (line 46) | type ClientAuthentication interface
type NkeyUser (line 62) | type NkeyUser struct
method clone (line 106) | func (n *NkeyUser) clone() *NkeyUser {
type User (line 73) | type User struct
method clone (line 85) | func (u *User) clone() *User {
type SubjectPermission (line 127) | type SubjectPermission struct
method clone (line 156) | func (p *SubjectPermission) clone() *SubjectPermission {
type ResponsePermission (line 134) | type ResponsePermission struct
type Permissions (line 141) | type Permissions struct
method clone (line 174) | func (p *Permissions) clone() *Permissions {
type RoutePermissions (line 150) | type RoutePermissions struct
method checkAuthforWarnings (line 196) | func (s *Server) checkAuthforWarnings() {
method assignGlobalAccountToOrphanUsers (line 226) | func (s *Server) assignGlobalAccountToOrphanUsers(nkeys map[string]*Nkey...
function validateResponsePermissions (line 243) | func validateResponsePermissions(p *Permissions) {
method configureAuthorization (line 266) | func (s *Server) configureAuthorization() {
method buildNkeysAndUsersFromOptions (line 325) | func (s *Server) buildNkeysAndUsersFromOptions(nko []*NkeyUser, uo []*Us...
method checkAuthentication (line 365) | func (s *Server) checkAuthentication(c *client) bool {
method isClientAuthorized (line 382) | func (s *Server) isClientAuthorized(c *client) bool {
method matchesPinnedCert (line 405) | func (c *client) matchesPinnedCert(tlsPinnedCerts PinnedCertSet) bool {
function processUserPermissionsTemplate (line 429) | func processUserPermissionsTemplate(lim jwt.UserPermissionLimits, ujwt *...
method processClientOrLeafAuthentication (line 604) | func (s *Server) processClientOrLeafAuthentication(c *client, opts *Opti...
method proxyCheck (line 1169) | func (s *Server) proxyCheck(c *client, opts *Options) (bool, bool) {
function getTLSAuthDCs (line 1214) | func getTLSAuthDCs(rdns *pkix.RDNSequence) string {
type tlsMapAuthFn (line 1234) | type tlsMapAuthFn
function checkClientTLSCertSubject (line 1236) | func checkClientTLSCertSubject(c *client, fn tlsMapAuthFn) bool {
function dnsAltNameLabels (line 1332) | func dnsAltNameLabels(dnsAltName string) []string {
function dnsAltNameMatches (line 1337) | func dnsAltNameMatches(dnsAltNameLabels []string, urls []*url.URL) bool {
method isRouterAuthorized (line 1365) | func (s *Server) isRouterAuthorized(c *client) bool {
method isGatewayAuthorized (line 1406) | func (s *Server) isGatewayAuthorized(c *client) bool {
method registerLeafWithAccount (line 1441) | func (s *Server) registerLeafWithAccount(c *client, account string) bool {
method isLeafNodeAuthorized (line 1459) | func (s *Server) isLeafNodeAuthorized(c *client) bool {
function isBcrypt (line 1585) | func isBcrypt(password string) bool {
function comparePasswords (line 1593) | func comparePasswords(serverPassword, clientPassword string) bool {
function validateAuth (line 1611) | func validateAuth(o *Options) error {
function validateAllowedConnectionTypes (line 1628) | func validateAllowedConnectionTypes(m map[string]struct{}) error {
function validateNoAuthUser (line 1647) | func validateNoAuthUser(o *Options, noAuthUser string) error {
function validateProxies (line 1673) | func validateProxies(o *Options) error {
method processProxiesTrustedKeys (line 1688) | func (s *Server) processProxiesTrustedKeys() {
function getAuthErrClosedState (line 1704) | func getAuthErrClosedState(authErr error) ClosedState {
FILE: server/auth_callout.go
constant AuthCalloutSubject (line 30) | AuthCalloutSubject = "$SYS.REQ.USER.AUTH"
constant AuthRequestSubject (line 31) | AuthRequestSubject = "nats-authorization-request"
constant AuthRequestXKeyHeader (line 32) | AuthRequestXKeyHeader = "Nats-Server-Xkey"
function titleCase (line 35) | func titleCase(m string) string {
method processClientOrLeafCallout (line 44) | func (s *Server) processClientOrLeafCallout(c *client, opts *Options, pr...
method fillClientInfo (line 459) | func (c *client) fillClientInfo(ci *jwt.ClientInformation) {
method fillConnectOpts (line 480) | func (c *client) fillConnectOpts(opts *jwt.ConnectOptions) {
FILE: server/auth_callout_test.go
function decodeAuthRequest (line 38) | func decodeAuthRequest(t *testing.T, ejwt []byte) (string, *jwt.ServerID...
function TestTitleCaseEmptyString (line 45) | func TestTitleCaseEmptyString(t *testing.T) {
constant authCalloutPub (line 51) | authCalloutPub = "UBO2MQV67TQTVIRV3XFTEZOACM4WLOCMCDMAWN5QVN5PI2N...
constant authCalloutSeed (line 52) | authCalloutSeed = "SUAP277QP7U4JMFFPVZHLJYEQJ2UHOTYVEIZJYAWRJXQLP4...
constant authCalloutIssuer (line 53) | authCalloutIssuer = "ABJHLOVMPA4CI6R5KLNGOB4GSLNIY7IOUPAJC4YFNDLQVIO...
constant authCalloutIssuerSeed (line 54) | authCalloutIssuerSeed = "SAANDLKMXL6CUS3CP52WIXBEDN6YJ545GDKC65U5JZPPV6W...
constant authCalloutIssuerSK (line 55) | authCalloutIssuerSK = "SAAE46BB675HKZKSVJEUZAKKWIV6BJJO6XYE46Z3ZHO7TCI...
function serviceResponse (line 58) | func serviceResponse(t *testing.T, userID string, serverID string, uJwt ...
function newScopedRole (line 73) | func newScopedRole(t *testing.T, role string, pub []string, sub []string...
function createAuthUser (line 90) | func createAuthUser(t *testing.T, user, name, account, issuerAccount str...
type authTest (line 134) | type authTest struct
method NewClient (line 154) | func (at *authTest) NewClient(clientOptions ...nats.Option) (*nats.Con...
method ConnectCallout (line 163) | func (at *authTest) ConnectCallout(clientOptions ...nats.Option) *nats...
method Connect (line 172) | func (at *authTest) Connect(clientOptions ...nats.Option) *nats.Conn {
method WSNewClient (line 178) | func (at *authTest) WSNewClient(clientOptions ...nats.Option) (*nats.C...
method WSConnect (line 196) | func (at *authTest) WSConnect(clientOptions ...nats.Option) *nats.Conn {
method RequireConnectError (line 202) | func (at *authTest) RequireConnectError(clientOptions ...nats.Option) {
method Cleanup (line 207) | func (at *authTest) Cleanup() {
function NewAuthTest (line 142) | func NewAuthTest(t *testing.T, config string, authHandler nats.MsgHandle...
function TestAuthCalloutBasics (line 217) | func TestAuthCalloutBasics(t *testing.T) {
function TestAuthCalloutMultiAccounts (line 336) | func TestAuthCalloutMultiAccounts(t *testing.T) {
function TestAuthCalloutAllowedAccounts (line 388) | func TestAuthCalloutAllowedAccounts(t *testing.T) {
function TestAuthCalloutClientTLSCerts (line 470) | func TestAuthCalloutClientTLSCerts(t *testing.T) {
function TestAuthCalloutVerifiedUserCalloutsWithSig (line 540) | func TestAuthCalloutVerifiedUserCalloutsWithSig(t *testing.T) {
function createAuthServiceUser (line 611) | func createAuthServiceUser(t *testing.T, accKp nkeys.KeyPair) (pub, cred...
function createBasicAccountUser (line 627) | func createBasicAccountUser(t *testing.T, accKp nkeys.KeyPair) (creds st...
function createBasicAccountLeaf (line 631) | func createBasicAccountLeaf(t *testing.T, accKp nkeys.KeyPair) (creds st...
function createBasicAccountBearer (line 635) | func createBasicAccountBearer(t *testing.T, accKp nkeys.KeyPair) string {
function createBasicAccount (line 655) | func createBasicAccount(t *testing.T, name string, accKp nkeys.KeyPair, ...
function createScopedUser (line 676) | func createScopedUser(t *testing.T, accKp nkeys.KeyPair, sk nkeys.KeyPai...
function TestAuthCalloutOperatorNoServerConfigCalloutAllowed (line 698) | func TestAuthCalloutOperatorNoServerConfigCalloutAllowed(t *testing.T) {
function TestAuthCalloutOperatorModeBasics (line 717) | func TestAuthCalloutOperatorModeBasics(t *testing.T) {
function testAuthCalloutScopedUser (line 915) | func testAuthCalloutScopedUser(t *testing.T, allowAnyAccount bool) {
function TestAuthCalloutScopedUserAssignedAccount (line 1055) | func TestAuthCalloutScopedUserAssignedAccount(t *testing.T) {
function TestAuthCalloutScopedUserAllAccount (line 1059) | func TestAuthCalloutScopedUserAllAccount(t *testing.T) {
constant curveSeed (line 1064) | curveSeed = "SXAAXMRAEP6JWWHNB6IKFL554IE6LZVT6EY5MBRICPILTLOPHAG73I3YX4"
constant curvePublic (line 1065) | curvePublic = "XAB3NANV3M6N7AHSQP2U5FRWKKUT7EG2ZXXABV4XVXYQRJGM4S2CZGHT"
function TestAuthCalloutServerConfigEncryption (line 1068) | func TestAuthCalloutServerConfigEncryption(t *testing.T) {
function TestAuthCalloutOperatorModeEncryption (line 1131) | func TestAuthCalloutOperatorModeEncryption(t *testing.T) {
function TestAuthCalloutServerTags (line 1228) | func TestAuthCalloutServerTags(t *testing.T) {
function TestAuthCalloutServerClusterAndVersion (line 1262) | func TestAuthCalloutServerClusterAndVersion(t *testing.T) {
function TestAuthCalloutErrorResponse (line 1300) | func TestAuthCalloutErrorResponse(t *testing.T) {
function TestAuthCalloutAuthUserFailDoesNotInvokeCallout (line 1323) | func TestAuthCalloutAuthUserFailDoesNotInvokeCallout(t *testing.T) {
function TestAuthCalloutAuthErrEvents (line 1352) | func TestAuthCalloutAuthErrEvents(t *testing.T) {
function TestAuthCalloutConnectEvents (line 1425) | func TestAuthCalloutConnectEvents(t *testing.T) {
function TestAuthCalloutBadServer (line 1553) | func TestAuthCalloutBadServer(t *testing.T) {
function TestAuthCalloutBadUser (line 1604) | func TestAuthCalloutBadUser(t *testing.T) {
function TestAuthCalloutExpiredUser (line 1655) | func TestAuthCalloutExpiredUser(t *testing.T) {
function TestAuthCalloutExpiredResponse (line 1702) | func TestAuthCalloutExpiredResponse(t *testing.T) {
function TestAuthCalloutOperator_AnyAccount (line 1749) | func TestAuthCalloutOperator_AnyAccount(t *testing.T) {
function TestAuthCalloutWSClientTLSCerts (line 1858) | func TestAuthCalloutWSClientTLSCerts(t *testing.T) {
function testConfClientClose (line 1938) | func testConfClientClose(t *testing.T, respondNil bool) {
function TestAuthCallout_ClientAuthErrorConf (line 1973) | func TestAuthCallout_ClientAuthErrorConf(t *testing.T) {
function testAuthCall_ClientAuthErrorOperatorMode (line 1978) | func testAuthCall_ClientAuthErrorOperatorMode(t *testing.T, respondNil b...
function TestAuthCallout_ClientAuthErrorOperatorMode (line 2048) | func TestAuthCallout_ClientAuthErrorOperatorMode(t *testing.T) {
function TestOperatorModeUserRevocation (line 2053) | func TestOperatorModeUserRevocation(t *testing.T) {
function updateAccount (line 2204) | func updateAccount(t *testing.T, sys *nats.Conn, jwtToken string) {
function TestAuthCalloutLeafNodeAndOperatorMode (line 2225) | func TestAuthCalloutLeafNodeAndOperatorMode(t *testing.T) {
function TestAuthCalloutLeafNodeAndConfigMode (line 2350) | func TestAuthCalloutLeafNodeAndConfigMode(t *testing.T) {
function TestAuthCalloutProxyRequiredInUserNotInAuthJWT (line 2437) | func TestAuthCalloutProxyRequiredInUserNotInAuthJWT(t *testing.T) {
function TestAuthCalloutOperatorModeMismatchedCalloutCreds (line 2508) | func TestAuthCalloutOperatorModeMismatchedCalloutCreds(t *testing.T) {
function TestAuthCalloutLeafNodeOperatorModeMismatchedCreds (line 2567) | func TestAuthCalloutLeafNodeOperatorModeMismatchedCreds(t *testing.T) {
function TestAuthCalloutRegisterWithAccountAfterClose (line 2687) | func TestAuthCalloutRegisterWithAccountAfterClose(t *testing.T) {
function TestAuthCalloutZombieInflatesAccountConnections (line 2774) | func TestAuthCalloutZombieInflatesAccountConnections(t *testing.T) {
FILE: server/auth_test.go
function TestUserCloneNilPermissions (line 34) | func TestUserCloneNilPermissions(t *testing.T) {
function TestUserClone (line 53) | func TestUserClone(t *testing.T) {
function TestUserClonePermissionsNoLists (line 80) | func TestUserClonePermissionsNoLists(t *testing.T) {
function TestUserCloneNoPermissions (line 97) | func TestUserCloneNoPermissions(t *testing.T) {
function TestUserCloneNil (line 110) | func TestUserCloneNil(t *testing.T) {
function TestUserUnknownAllowedConnectionType (line 118) | func TestUserUnknownAllowedConnectionType(t *testing.T) {
function TestDNSAltNameMatching (line 168) | func TestDNSAltNameMatching(t *testing.T) {
function TestProcessUserPermissionsTemplateMalformedOpDoesNotPanic (line 225) | func TestProcessUserPermissionsTemplateMalformedOpDoesNotPanic(t *testin...
function TestProcessUserPermissionsTemplateUnknownAllowOpDoesNotPanic (line 235) | func TestProcessUserPermissionsTemplateUnknownAllowOpDoesNotPanic(t *tes...
function TestProcessUserPermissionsTemplateRejectsExcessiveTagExpansions (line 245) | func TestProcessUserPermissionsTemplateRejectsExcessiveTagExpansions(t *...
function TestNoAuthUser (line 261) | func TestNoAuthUser(t *testing.T) {
function TestNoAuthUserNkey (line 319) | func TestNoAuthUserNkey(t *testing.T) {
function TestUserConnectionDeadline (line 344) | func TestUserConnectionDeadline(t *testing.T) {
function TestNoAuthUserNoConnectProto (line 387) | func TestNoAuthUserNoConnectProto(t *testing.T) {
type captureProxyRequiredLogger (line 430) | type captureProxyRequiredLogger struct
method Debugf (line 435) | func (l *captureProxyRequiredLogger) Debugf(format string, args ...any) {
function TestAuthProxyRequired (line 445) | func TestAuthProxyRequired(t *testing.T) {
FILE: server/avl/norace_test.go
function TestNoRaceSeqSetSizeComparison (line 33) | func TestNoRaceSeqSetSizeComparison(t *testing.T) {
function TestNoRaceSeqSetEncodeLarge (line 81) | func TestNoRaceSeqSetEncodeLarge(t *testing.T) {
function TestNoRaceSeqSetRelativeSpeed (line 122) | func TestNoRaceSeqSetRelativeSpeed(t *testing.T) {
function friendlyBytes (line 182) | func friendlyBytes[T int | uint64 | int64](bytes T) string {
function logResults (line 194) | func logResults(format string, args ...any) {
FILE: server/avl/seqset.go
type SequenceSet (line 33) | type SequenceSet struct
method Insert (line 44) | func (ss *SequenceSet) Insert(seq uint64) {
method Exists (line 52) | func (ss *SequenceSet) Exists(seq uint64) bool {
method SetInitialMin (line 69) | func (ss *SequenceSet) SetInitialMin(min uint64) error {
method Delete (line 80) | func (ss *SequenceSet) Delete(seq uint64) bool {
method Size (line 97) | func (ss *SequenceSet) Size() int {
method Nodes (line 102) | func (ss *SequenceSet) Nodes() int {
method Empty (line 107) | func (ss *SequenceSet) Empty() {
method IsEmpty (line 114) | func (ss *SequenceSet) IsEmpty() bool {
method Range (line 124) | func (ss *SequenceSet) Range(f func(uint64) bool) {
method Heights (line 129) | func (ss *SequenceSet) Heights() (l, r int) {
method State (line 143) | func (ss *SequenceSet) State() (min, max, num uint64) {
method MinMax (line 152) | func (ss *SequenceSet) MinMax() (min, max uint64) {
method Clone (line 180) | func (ss *SequenceSet) Clone() *SequenceSet {
method Union (line 191) | func (ss *SequenceSet) Union(ssa ...*SequenceSet) {
method EncodeLen (line 238) | func (ss SequenceSet) EncodeLen() int {
method Encode (line 242) | func (ss SequenceSet) Encode(buf []byte) []byte {
method insertNode (line 376) | func (ss *SequenceSet) insertNode(n *node) {
function clone (line 169) | func clone(src *node, target **node) {
function Union (line 208) | func Union(ssa ...*SequenceSet) *SequenceSet {
constant magic (line 228) | magic = uint8(22)
constant version (line 230) | version = uint8(2)
constant hdrLen (line 232) | hdrLen = 2
constant minLen (line 234) | minLen = 2 + 8
function Decode (line 282) | func Decode(buf []byte) (*SequenceSet, int, error) {
function decodev2 (line 298) | func decodev2(buf []byte) (*SequenceSet, int, error) {
function decodev1 (line 329) | func decodev1(buf []byte) (*SequenceSet, int, error) {
constant bitsPerBucket (line 402) | bitsPerBucket = 64
constant numBuckets (line 403) | numBuckets = 32
constant numEntries (line 404) | numEntries = numBuckets * bitsPerBucket
type node (line 407) | type node struct
method set (line 418) | func (n *node) set(seq uint64, inserted *bool) {
method insert (line 428) | func (n *node) insert(seq uint64, inserted *bool, nodes *int) *node {
method rotateL (line 464) | func (n *node) rotateL() *node {
method rotateR (line 478) | func (n *node) rotateR() *node {
method clear (line 526) | func (n *node) clear(seq uint64, deleted *bool) bool {
method delete (line 542) | func (n *node) delete(seq uint64, deleted *bool, nodes *int) *node {
method insertNodePrev (line 588) | func (n *node) insertNodePrev(nn *node) *node {
method exists (line 613) | func (n *node) exists(seq uint64) bool {
method min (line 622) | func (n *node) min() uint64 {
method max (line 635) | func (n *node) max() uint64 {
method nodeIter (line 647) | func (n *node) nodeIter(f func(n *node)) {
method iter (line 658) | func (n *node) iter(f func(uint64) bool) bool {
function balanceF (line 492) | func balanceF(n *node) int {
function maxH (line 506) | func maxH(n *node) int {
FILE: server/avl/seqset_test.go
function TestSeqSetBasics (line 22) | func TestSeqSetBasics(t *testing.T) {
function TestSeqSetLeftLean (line 38) | func TestSeqSetLeftLean(t *testing.T) {
function TestSeqSetRightLean (line 52) | func TestSeqSetRightLean(t *testing.T) {
function TestSeqSetCorrectness (line 66) | func TestSeqSetCorrectness(t *testing.T) {
function TestSeqSetRange (line 85) | func TestSeqSetRange(t *testing.T) {
function TestSeqSetDelete (line 123) | func TestSeqSetDelete(t *testing.T) {
function TestSeqSetInsertAndDeletePedantic (line 139) | func TestSeqSetInsertAndDeletePedantic(t *testing.T) {
function TestSeqSetMinMax (line 181) | func TestSeqSetMinMax(t *testing.T) {
function TestSeqSetClone (line 210) | func TestSeqSetClone(t *testing.T) {
function TestSeqSetUnion (line 225) | func TestSeqSetUnion(t *testing.T) {
function TestSeqSetFirst (line 247) | func TestSeqSetFirst(t *testing.T) {
function TestSeqSetDistinctUnion (line 265) | func TestSeqSetDistinctUnion(t *testing.T) {
function TestSeqSetDecodeV1 (line 289) | func TestSeqSetDecodeV1(t *testing.T) {
function require_NoError (line 308) | func require_NoError(t *testing.T, err error) {
function require_True (line 315) | func require_True(t *testing.T, b bool) {
FILE: server/benchmark_publish_test.go
function BenchmarkPublish (line 25) | func BenchmarkPublish(b *testing.B) {
FILE: server/certidp/certidp.go
constant DefaultAllowedClockSkew (line 30) | DefaultAllowedClockSkew = 30 * time.Second
constant DefaultOCSPResponderTimeout (line 31) | DefaultOCSPResponderTimeout = 2 * time.Second
constant DefaultTTLUnsetNextUpdate (line 32) | DefaultTTLUnsetNextUpdate = 1 * time.Hour
type StatusAssertion (line 35) | type StatusAssertion
method MarshalJSON (line 70) | func (sa StatusAssertion) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 81) | func (sa *StatusAssertion) UnmarshalJSON(in []byte) error {
function GetStatusAssertionStr (line 56) | func GetStatusAssertionStr(sa int) string {
type ChainLink (line 93) | type ChainLink struct
type OCSPPeerConfig (line 100) | type OCSPPeerConfig struct
function NewOCSPPeerConfig (line 110) | func NewOCSPPeerConfig() *OCSPPeerConfig {
type Log (line 123) | type Log struct
type CertInfo (line 131) | type CertInfo struct
function GenerateFingerprint (line 179) | func GenerateFingerprint(cert *x509.Certificate) string {
function getWebEndpoints (line 184) | func getWebEndpoints(uris []string) []*url.URL {
function GetSubjectDNForm (line 203) | func GetSubjectDNForm(cert *x509.Certificate) string {
function GetIssuerDNForm (line 212) | func GetIssuerDNForm(cert *x509.Certificate) string {
function CertOCSPEligible (line 221) | func CertOCSPEligible(link *ChainLink) bool {
function GetLeafIssuerCert (line 237) | func GetLeafIssuerCert(chain []*x509.Certificate, leafPos int) *x509.Cer...
function OCSPResponseCurrent (line 250) | func OCSPResponseCurrent(ocspr *ocsp.Response, opts *OCSPPeerConfig, log...
function ValidDelegationCheck (line 288) | func ValidDelegationCheck(iss *x509.Certificate, ocspr *ocsp.Response) b...
FILE: server/certidp/certidp_test.go
function TestGetStatusAssertionStr (line 19) | func TestGetStatusAssertionStr(t *testing.T) {
FILE: server/certidp/ocsp_responder.go
function FetchOCSPResponse (line 29) | func FetchOCSPResponse(link *ChainLink, opts *OCSPPeerConfig, log *Log) ...
function encodeOCSPRequest (line 89) | func encodeOCSPRequest(reqDER []byte) string {
FILE: server/certidp/ocsp_responder_test.go
function TestEncodeOCSPRequest (line 10) | func TestEncodeOCSPRequest(t *testing.T) {
FILE: server/certstore/certstore.go
type StoreType (line 24) | type StoreType
constant MATCHBYEMPTY (line 26) | MATCHBYEMPTY = 0
constant STOREEMPTY (line 27) | STOREEMPTY = 0
constant windowsCurrentUser (line 30) | windowsCurrentUser StoreType = iota + 1
constant windowsLocalMachine (line 31) | windowsLocalMachine
type MatchByType (line 44) | type MatchByType
constant matchByIssuer (line 47) | matchByIssuer MatchByType = iota + 1
constant matchBySubject (line 48) | matchBySubject
constant matchByThumbprint (line 49) | matchByThumbprint
function ParseCertStore (line 68) | func ParseCertStore(certStore string) (StoreType, error) {
function ParseCertMatchBy (line 80) | func ParseCertMatchBy(certMatchBy string) (MatchByType, error) {
function GetLeafIssuer (line 88) | func GetLeafIssuer(leaf *x509.Certificate, vOpts x509.VerifyOptions) (is...
type credential (line 99) | type credential interface
FILE: server/certstore/certstore_other.go
type otherKey (line 27) | type otherKey struct
method Public (line 34) | func (k otherKey) Public() crypto.PublicKey {
method Sign (line 39) | func (k otherKey) Sign(rand io.Reader, digest []byte, opts crypto.Sign...
function TLSConfig (line 29) | func TLSConfig(_ StoreType, _ MatchByType, _ string, _ []string, _ bool,...
FILE: server/certstore/certstore_windows.go
constant winAcquireCached (line 44) | winAcquireCached = windows.CRYPT_ACQUIRE_CACHE_FLAG
constant winAcquireSilent (line 45) | winAcquireSilent = windows.CRYPT_ACQUIRE_SILENT_FLAG
constant winAcquireOnlyNCryptKey (line 46) | winAcquireOnlyNCryptKey = windows.CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG
constant winEncodingX509ASN (line 47) | winEncodingX509ASN = windows.X509_ASN_ENCODING
constant winEncodingPKCS7 (line 48) | winEncodingPKCS7 = windows.PKCS_7_ASN_ENCODING
constant winCertStoreProvSystem (line 49) | winCertStoreProvSystem = windows.CERT_STORE_PROV_SYSTEM
constant winCertStoreCurrentUser (line 50) | winCertStoreCurrentUser = windows.CERT_SYSTEM_STORE_CURRENT_USER
constant winCertStoreLocalMachine (line 51) | winCertStoreLocalMachine = windows.CERT_SYSTEM_STORE_LOCAL_MACHINE
constant winCertStoreReadOnly (line 52) | winCertStoreReadOnly = windows.CERT_STORE_READONLY_FLAG
constant winInfoIssuerFlag (line 53) | winInfoIssuerFlag = windows.CERT_INFO_ISSUER_FLAG
constant winInfoSubjectFlag (line 54) | winInfoSubjectFlag = windows.CERT_INFO_SUBJECT_FLAG
constant winCompareNameStrW (line 55) | winCompareNameStrW = windows.CERT_COMPARE_NAME_STR_W
constant winCompareShift (line 56) | winCompareShift = windows.CERT_COMPARE_SHIFT
constant winFindIssuerStr (line 59) | winFindIssuerStr = windows.CERT_FIND_ISSUER_STR_W
constant winFindSubjectStr (line 60) | winFindSubjectStr = windows.CERT_FIND_SUBJECT_STR_W
constant winFindHashStr (line 61) | winFindHashStr = windows.CERT_FIND_HASH_STR
constant winNcryptKeySpec (line 63) | winNcryptKeySpec = windows.CERT_NCRYPT_KEY_SPEC
constant winBCryptPadPKCS1 (line 65) | winBCryptPadPKCS1 uintptr = 0x2
constant winBCryptPadPSS (line 66) | winBCryptPadPSS uintptr = 0x8
constant winBCryptPadPSSSalt (line 67) | winBCryptPadPSSSalt uint32 = 32
constant winRSA1Magic (line 69) | winRSA1Magic = 0x31415352
constant winECS1Magic (line 71) | winECS1Magic = 0x31534345
constant winECS3Magic (line 72) | winECS3Magic = 0x33534345
constant winECS5Magic (line 73) | winECS5Magic = 0x35534345
constant winECK1Magic (line 75) | winECK1Magic = 0x314B4345
constant winECK3Magic (line 76) | winECK3Magic = 0x334B4345
constant winECK5Magic (line 77) | winECK5Magic = 0x354B4345
constant winCryptENotFound (line 79) | winCryptENotFound = windows.CRYPT_E_NOT_FOUND
constant providerMSSoftware (line 81) | providerMSSoftware = "Microsoft Software Key Storage Provider"
function init (line 141) | func init() {
type winPKCS1PaddingInfo (line 160) | type winPKCS1PaddingInfo struct
type winPSSPaddingInfo (line 164) | type winPSSPaddingInfo struct
function createCACertsPool (line 173) | func createCACertsPool(cs *winCertStore, storeType uint32, caCertsMatch ...
function TLSConfig (line 202) | func TLSConfig(certStore StoreType, certMatchBy MatchByType, certMatch s...
function winWide (line 301) | func winWide(s string) *uint16 {
function winOpenProvider (line 308) | func winOpenProvider(provider string) (uintptr, error) {
function winFindCert (line 321) | func winFindCert(store windows.Handle, enc, findFlags, findType uint32, ...
function winVerifyCertValid (line 342) | func winVerifyCertValid(timeToVerify *windows.Filetime, certInfo *window...
type winCertStore (line 352) | type winCertStore struct
method certByIssuer (line 390) | func (w *winCertStore) certByIssuer(issuer string, storeType uint32, s...
method certBySubject (line 398) | func (w *winCertStore) certBySubject(subject string, storeType uint32,...
method certByThumbprint (line 406) | func (w *winCertStore) certByThumbprint(hash string, storeType uint32,...
method caCertsBySubjectMatch (line 419) | func (w *winCertStore) caCertsBySubjectMatch(subject string, storeType...
method certSearch (line 453) | func (w *winCertStore) certSearch(searchType uint32, matchValue string...
method certKey (line 697) | func (w *winCertStore) certKey(cert *windows.CertContext) (*winKey, er...
method storeHandle (line 949) | func (w *winCertStore) storeHandle(provider uint32, store *uint16) (wi...
function winOpenCertStore (line 360) | func winOpenCertStore(provider string) (*winCertStore, error) {
function winCertContextToX509 (line 377) | func winCertContextToX509(ctx *windows.CertContext) (*x509.Certificate, ...
type winStoreHandle (line 505) | type winStoreHandle struct
function winNewStoreHandle (line 509) | func winNewStoreHandle(provider uint32, store *uint16) (*winStoreHandle,...
type winKey (line 528) | type winKey struct
method Public (line 536) | func (k winKey) Public() crypto.PublicKey {
method Sign (line 541) | func (k winKey) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpt...
function winSignECDSA (line 562) | func winSignECDSA(kh uintptr, digest []byte) ([]byte, error) {
function winPackECDSASigValue (line 599) | func winPackECDSASigValue(r io.Reader, digestLength int) ([]byte, error) {
function winSignRSAPKCS1Padding (line 618) | func winSignRSAPKCS1Padding(kh uintptr, digest []byte, algID *uint16) ([...
function winSignRSAPSSPadding (line 654) | func winSignRSAPSSPadding(kh uintptr, digest []byte, algID *uint16) ([]b...
function winKeyMetadata (line 729) | func winKeyMetadata(kh uintptr) (*winKey, error) {
function winGetProperty (line 772) | func winGetProperty(kh uintptr, property *uint16) ([]byte, error) {
function winGetPropertyStr (line 802) | func winGetPropertyStr(kh uintptr, property *uint16) (string, error) {
function winExport (line 811) | func winExport(kh uintptr, blobType *uint16) ([]byte, error) {
function unmarshalECC (line 844) | func unmarshalECC(buf []byte, kh uintptr) (*ecdsa.PublicKey, error) {
function winCurveName (line 889) | func winCurveName(kh uintptr) (elliptic.Curve, error) {
function winUnmarshalRSA (line 903) | func winUnmarshalRSA(buf []byte) (*rsa.PublicKey, error) {
FILE: server/certstore_windows_test.go
function runPowershellScript (line 31) | func runPowershellScript(scriptFile string, args []string) error {
function runConfiguredLeaf (line 48) | func runConfiguredLeaf(t *testing.T, hubPort int, certStore string, matc...
function TestLeafTLSWindowsCertStore (line 94) | func TestLeafTLSWindowsCertStore(t *testing.T) {
function TestServerTLSWindowsCertStore (line 191) | func TestServerTLSWindowsCertStore(t *testing.T) {
function TestServerIgnoreExpiredCerts (line 261) | func TestServerIgnoreExpiredCerts(t *testing.T) {
function TestWindowsTLS12ECDSA (line 312) | func TestWindowsTLS12ECDSA(t *testing.T) {
FILE: server/ciphersuites.go
function init (line 21) | func init() {
function defaultCipherSuites (line 35) | func defaultCipherSuites() []uint16 {
function defaultCurvePreferences (line 55) | func defaultCurvePreferences() []tls.CurveID {
FILE: server/client.go
constant CLIENT (line 47) | CLIENT = iota
constant ROUTER (line 49) | ROUTER
constant GATEWAY (line 51) | GATEWAY
constant SYSTEM (line 53) | SYSTEM
constant LEAF (line 55) | LEAF
constant JETSTREAM (line 57) | JETSTREAM
constant ACCOUNT (line 59) | ACCOUNT
function isInternalClient (line 63) | func isInternalClient(kind int) bool {
constant NON_CLIENT (line 72) | NON_CLIENT = iota
constant NATS (line 74) | NATS
constant MQTT (line 76) | MQTT
constant WS (line 78) | WS
constant ClientProtoZero (line 84) | ClientProtoZero = iota
constant ClientProtoInfo (line 87) | ClientProtoInfo
constant pingProto (line 91) | pingProto = "PING" + _CRLF_
constant pongProto (line 92) | pongProto = "PONG" + _CRLF_
constant errProto (line 93) | errProto = "-ERR '%s'" + _CRLF_
constant okProto (line 94) | okProto = "+OK" + _CRLF_
constant tlsHandshakeLeaf (line 99) | tlsHandshakeLeaf = "leafnode"
constant tlsHandshakeMQTT (line 100) | tlsHandshakeMQTT = "mqtt"
constant msgScratchSize (line 105) | msgScratchSize = 1024
constant msgHeadProto (line 106) | msgHeadProto = "RMSG "
constant msgHeadProtoLen (line 107) | msgHeadProtoLen = len(msgHeadProto)
constant startBufSize (line 110) | startBufSize = 512
constant minBufSize (line 111) | minBufSize = 64
constant maxBufSize (line 112) | maxBufSize = 65536
constant shortsToShrink (line 113) | shortsToShrink = 2
constant maxFlushPending (line 114) | maxFlushPending = 10
constant readLoopReport (line 115) | readLoopReport = 2 * time.Second
constant maxNoRTTPingBeforeFirstPong (line 121) | maxNoRTTPingBeforeFirstPong = 2 * time.Second
constant stallClientMinDuration (line 124) | stallClientMinDuration = 2 * time.Millisecond
constant stallClientMaxDuration (line 125) | stallClientMaxDuration = 5 * time.Millisecond
constant stallTotalAllowed (line 126) | stallTotalAllowed = 10 * time.Millisecond
type clientFlag (line 132) | type clientFlag
method set (line 159) | func (cf *clientFlag) set(c clientFlag) {
method clear (line 164) | func (cf *clientFlag) clear(c clientFlag) {
method isSet (line 169) | func (cf clientFlag) isSet(c clientFlag) bool {
method setIfNotSet (line 176) | func (cf *clientFlag) setIfNotSet(c clientFlag) bool {
constant hdrLine (line 135) | hdrLine = "NATS/1.0\r\n"
constant emptyHdrLine (line 136) | emptyHdrLine = "NATS/1.0\r\n\r\n"
constant connectReceived (line 141) | connectReceived clientFlag = 1 << iota
constant infoReceived (line 142) | infoReceived
constant firstPongSent (line 143) | firstPongSent
constant handshakeComplete (line 144) | handshakeComplete
constant flushOutbound (line 145) | flushOutbound
constant noReconnect (line 146) | noReconnect
constant closeConnection (line 147) | closeConnection
constant connMarkedClosed (line 148) | connMarkedClosed
constant writeLoopStarted (line 149) | writeLoopStarted
constant skipFlushOnClose (line 150) | skipFlushOnClose
constant expectConnect (line 151) | expectConnect
constant connectProcessFinished (line 152) | connectProcessFinished
constant compressionNegotiated (line 153) | compressionNegotiated
constant didTLSFirst (line 154) | didTLSFirst
constant isSlowConsumer (line 155) | isSlowConsumer
type ClosedState (line 187) | type ClosedState
constant ClientClosed (line 190) | ClientClosed = ClosedState(iota + 1)
constant AuthenticationTimeout (line 191) | AuthenticationTimeout
constant AuthenticationViolation (line 192) | AuthenticationViolation
constant TLSHandshakeError (line 193) | TLSHandshakeError
constant SlowConsumerPendingBytes (line 194) | SlowConsumerPendingBytes
constant SlowConsumerWriteDeadline (line 195) | SlowConsumerWriteDeadline
constant WriteError (line 196) | WriteError
constant ReadError (line 197) | ReadError
constant ParseError (line 198) | ParseError
constant StaleConnection (line 199) | StaleConnection
constant ProtocolViolation (line 200) | ProtocolViolation
constant BadClientProtocolVersion (line 201) | BadClientProtocolVersion
constant WrongPort (line 202) | WrongPort
constant MaxAccountConnectionsExceeded (line 203) | MaxAccountConnectionsExceeded
constant MaxConnectionsExceeded (line 204) | MaxConnectionsExceeded
constant MaxPayloadExceeded (line 205) | MaxPayloadExceeded
constant MaxControlLineExceeded (line 206) | MaxControlLineExceeded
constant MaxSubscriptionsExceeded (line 207) | MaxSubscriptionsExceeded
constant DuplicateRoute (line 208) | DuplicateRoute
constant RouteRemoved (line 209) | RouteRemoved
constant ServerShutdown (line 210) | ServerShutdown
constant AuthenticationExpired (line 211) | AuthenticationExpired
constant WrongGateway (line 212) | WrongGateway
constant MissingAccount (line 213) | MissingAccount
constant Revocation (line 214) | Revocation
constant InternalClient (line 215) | InternalClient
constant MsgHeaderViolation (line 216) | MsgHeaderViolation
constant NoRespondersRequiresHeaders (line 217) | NoRespondersRequiresHeaders
constant ClusterNameConflict (line 218) | ClusterNameConflict
constant DuplicateRemoteLeafnodeConnection (line 219) | DuplicateRemoteLeafnodeConnection
constant DuplicateClientID (line 220) | DuplicateClientID
constant DuplicateServerName (line 221) | DuplicateServerName
constant MinimumVersionRequired (line 222) | MinimumVersionRequired
constant ClusterNamesIdentical (line 223) | ClusterNamesIdentical
constant Kicked (line 224) | Kicked
constant ProxyNotTrusted (line 225) | ProxyNotTrusted
constant ProxyRequired (line 226) | ProxyRequired
constant pmrNoFlag (line 230) | pmrNoFlag int = 0
constant pmrCollectQueueNames (line 232) | pmrCollectQueueNames int = 1 << iota
constant pmrIgnoreEmptyQueueFilter (line 233) | pmrIgnoreEmptyQueueFilter
constant pmrAllowSendFromRouteToRoute (line 234) | pmrAllowSendFromRouteToRoute
constant pmrMsgImportedFromService (line 235) | pmrMsgImportedFromService
type WriteTimeoutPolicy (line 238) | type WriteTimeoutPolicy
method String (line 247) | func (p WriteTimeoutPolicy) String() string {
constant WriteTimeoutPolicyDefault (line 241) | WriteTimeoutPolicyDefault = iota
constant WriteTimeoutPolicyClose (line 242) | WriteTimeoutPolicyClose
constant WriteTimeoutPolicyRetry (line 243) | WriteTimeoutPolicyRetry
type client (line 258) | type client struct
method String (line 546) | func (c *client) String() (id string) {
method GetNonce (line 556) | func (c *client) GetNonce() []byte {
method GetName (line 564) | func (c *client) GetName() string {
method GetOpts (line 572) | func (c *client) GetOpts() *ClientOpts {
method GetTLSConnectionState (line 578) | func (c *client) GetTLSConnectionState() *tls.ConnectionState {
method clientType (line 598) | func (c *client) clientType() int {
method clientTypeString (line 619) | func (c *client) clientTypeString() string {
method setTraceLevel (line 694) | func (c *client) setTraceLevel() {
method initClient (line 703) | func (c *client) initClient() {
method RemoteAddress (line 821) | func (c *client) RemoteAddress() net.Addr {
method reportErrRegisterAccount (line 833) | func (c *client) reportErrRegisterAccount(acc *Account, err error) {
method Kind (line 843) | func (c *client) Kind() int {
method registerWithAccount (line 853) | func (c *client) registerWithAccount(acc *Account) error {
method subsAtLimit (line 904) | func (c *client) subsAtLimit() bool {
method applyAccountLimits (line 927) | func (c *client) applyAccountLimits() {
method RegisterUser (line 985) | func (c *client) RegisterUser(user *User) {
method RegisterNkeyUser (line 1022) | func (c *client) RegisterNkeyUser(user *NkeyUser) error {
method setPermissions (line 1059) | func (c *client) setPermissions(perms *Permissions) {
method publicPermissions (line 1133) | func (c *client) publicPermissions() *Permissions {
method mergeDenyPermissions (line 1196) | func (c *client) mergeDenyPermissions(what denyType, denyPubs []string) {
method mergeDenyPermissionsLocked (line 1239) | func (c *client) mergeDenyPermissionsLocked(what denyType, denyPubs []...
method setExpiration (line 1247) | func (c *client) setExpiration(claims *jwt.ClaimsData, validFor time.D...
method loadMsgDenyFilter (line 1269) | func (c *client) loadMsgDenyFilter() {
method writeLoop (line 1278) | func (c *client) writeLoop() {
method flushClients (line 1328) | func (c *client) flushClients(budget time.Duration) time.Time {
method readLoop (line 1362) | func (c *client) readLoop(pre []byte) {
method collapsePtoNB (line 1609) | func (c *client) collapsePtoNB() (net.Buffers, int64) {
method flushOutbound (line 1619) | func (c *client) flushOutbound() bool {
method handleWriteTimeout (line 1845) | func (c *client) handleWriteTimeout(written, attempted int64, numChunk...
method markConnAsClosed (line 1909) | func (c *client) markConnAsClosed(reason ClosedState) {
method flushSignal (line 1999) | func (c *client) flushSignal() {
method traceMsgInternal (line 2008) | func (c *client) traceMsgInternal(msg []byte, delivered bool, hdrSize ...
method traceMsg (line 2050) | func (c *client) traceMsg(msg []byte) {
method traceMsgDelivery (line 2054) | func (c *client) traceMsgDelivery(msg []byte, hdrSize int) {
method traceInOp (line 2060) | func (c *client) traceInOp(op string, arg []byte) {
method traceOutOp (line 2066) | func (c *client) traceOutOp(op string, arg []byte) {
method traceOp (line 2070) | func (c *client) traceOp(format, op string, arg []byte) {
method processInfo (line 2082) | func (c *client) processInfo(arg []byte) error {
method processErr (line 2098) | func (c *client) processErr(errStr string) {
method processConnect (line 2166) | func (c *client) processConnect(arg []byte) error {
method sendErrAndErr (line 2372) | func (c *client) sendErrAndErr(err string) {
method sendErrAndDebug (line 2377) | func (c *client) sendErrAndDebug(err string) {
method authTimeout (line 2382) | func (c *client) authTimeout() {
method authExpired (line 2387) | func (c *client) authExpired() {
method accountAuthExpired (line 2392) | func (c *client) accountAuthExpired() {
method authViolation (line 2397) | func (c *client) authViolation() {
method maxAccountConnExceeded (line 2422) | func (c *client) maxAccountConnExceeded() {
method maxConnExceeded (line 2427) | func (c *client) maxConnExceeded() {
method maxSubsExceeded (line 2432) | func (c *client) maxSubsExceeded() {
method maxPayloadViolation (line 2439) | func (c *client) maxPayloadViolation(sz int, max int32) {
method queueOutbound (line 2447) | func (c *client) queueOutbound(data []byte) {
method enqueueProtoAndFlush (line 2515) | func (c *client) enqueueProtoAndFlush(proto []byte, doFlush bool) {
method sendProtoNow (line 2528) | func (c *client) sendProtoNow(proto []byte) {
method enqueueProto (line 2534) | func (c *client) enqueueProto(proto []byte) {
method sendPong (line 2539) | func (c *client) sendPong() {
method sendRTTPing (line 2547) | func (c *client) sendRTTPing() bool {
method sendRTTPingLocked (line 2558) | func (c *client) sendRTTPingLocked() bool {
method sendPing (line 2576) | func (c *client) sendPing() {
method generateClientInfoJSON (line 2588) | func (c *client) generateClientInfoJSON(info Info, includeClientIP boo...
method sendErr (line 2607) | func (c *client) sendErr(err string) {
method sendOK (line 2618) | func (c *client) sendOK() {
method processPing (line 2627) | func (c *client) processPing() {
method processPong (line 2679) | func (c *client) processPong() {
method updateS2AutoCompressionLevel (line 2720) | func (c *client) updateS2AutoCompressionLevel(co *CompressionOpts, com...
method msgParts (line 2734) | func (c *client) msgParts(data []byte) (hdr []byte, msg []byte) {
method processHeaderPub (line 2742) | func (c *client) processHeaderPub(arg, remaining []byte) error {
method processPub (line 2820) | func (c *client) processPub(arg []byte) error {
method parseSub (line 2896) | func (c *client) parseSub(argo []byte, noForward bool) error {
method processSub (line 2925) | func (c *client) processSub(subject, queue, bsid []byte, cb msgHandler...
method processSubEx (line 2929) | func (c *client) processSubEx(subject, queue, bsid []byte, cb msgHandl...
method addShadowSubscriptions (line 3055) | func (c *client) addShadowSubscriptions(acc *Account, sub *subscriptio...
method addShadowSub (line 3175) | func (c *client) addShadowSub(sub *subscription, ime *ime) (*subscript...
method canSubscribe (line 3228) | func (c *client) canSubscribe(subject string, optQueue ...string) bool {
method unsubscribe (line 3308) | func (c *client) unsubscribe(acc *Account, sub *subscription, force, r...
method processUnsub (line 3364) | func (c *client) processUnsub(arg []byte) error {
method checkDenySub (line 3429) | func (c *client) checkDenySub(subject string) bool {
method msgHeaderForRouteOrLeaf (line 3445) | func (c *client) msgHeaderForRouteOrLeaf(subj, reply []byte, rt *route...
method msgHeader (line 3532) | func (c *client) msgHeader(subj, reply []byte, sub *subscription) []by...
method stalledWait (line 3573) | func (c *client) stalledWait(producer *client) {
method deliverMsg (line 3618) | func (c *client) deliverMsg(prodIsMQTT bool, sub *subscription, acc *A...
method addToPCD (line 3903) | func (c *client) addToPCD(client *client) {
method trackRemoteReply (line 3913) | func (c *client) trackRemoteReply(subject, reply string) {
method pruneRemoteTracking (line 3954) | func (c *client) pruneRemoteTracking() {
method pruneReplyPerms (line 3979) | func (c *client) pruneReplyPerms() {
method pruneDenyCache (line 4005) | func (c *client) pruneDenyCache() {
method prunePubPermsCache (line 4017) | func (c *client) prunePubPermsCache() {
method pubAllowed (line 4050) | func (c *client) pubAllowed(subject string) bool {
method pubAllowedFullCheck (line 4056) | func (c *client) pubAllowedFullCheck(subject string, fullCheck, hasLoc...
method processInboundMsg (line 4137) | func (c *client) processInboundMsg(msg []byte) {
method selectMappedSubject (line 4151) | func (c *client) selectMappedSubject() bool {
method processInboundClientMsg (line 4167) | func (c *client) processInboundClientMsg(msg []byte) (bool, bool) {
method subForReply (line 4346) | func (c *client) subForReply(reply []byte) *subscription {
method handleGWReplyMap (line 4359) | func (c *client) handleGWReplyMap(msg []byte) bool {
method setupResponseServiceImport (line 4378) | func (c *client) setupResponseServiceImport(acc *Account, si *serviceI...
method setHeader (line 4460) | func (c *client) setHeader(key, value string, msg []byte) []byte {
method processServiceImport (line 4644) | func (c *client) processServiceImport(si *serviceImport, acc *Account,...
method addSubToRouteTargets (line 4897) | func (c *client) addSubToRouteTargets(sub *subscription) {
method processMsgResults (line 4934) | func (c *client) processMsgResults(acc *Account, r *SublistResult, msg...
method checkLeafClientInfoHeader (line 5475) | func (c *client) checkLeafClientInfoHeader(msg []byte) (dmsg []byte, s...
method pubPermissionViolation (line 5501) | func (c *client) pubPermissionViolation(subject []byte) {
method subPermissionViolation (line 5510) | func (c *client) subPermissionViolation(sub *subscription) {
method replySubjectViolation (line 5523) | func (c *client) replySubjectViolation(reply []byte) {
method maxTokensViolation (line 5532) | func (c *client) maxTokensViolation(sub *subscription) {
method processPingTimer (line 5539) | func (c *client) processPingTimer() {
method watchForStaleConnection (line 5622) | func (c *client) watchForStaleConnection(pingInterval time.Duration, p...
method setPingTimer (line 5633) | func (c *client) setPingTimer() {
method clearPingTimer (line 5650) | func (c *client) clearPingTimer() {
method clearTlsToTimer (line 5658) | func (c *client) clearTlsToTimer() {
method setAuthTimer (line 5667) | func (c *client) setAuthTimer(d time.Duration) {
method clearAuthTimer (line 5672) | func (c *client) clearAuthTimer() bool {
method awaitingAuth (line 5684) | func (c *client) awaitingAuth() bool {
method setExpirationTimer (line 5690) | func (c *client) setExpirationTimer(d time.Duration) {
method setExpirationTimerUnlocked (line 5697) | func (c *client) setExpirationTimerUnlocked(d time.Duration) {
method claimExpiration (line 5706) | func (c *client) claimExpiration() time.Duration {
method flushAndClose (line 5719) | func (c *client) flushAndClose(minimalFlush bool) {
method kindString (line 5773) | func (c *client) kindString() string {
method swapAccountAfterReload (line 5783) | func (c *client) swapAccountAfterReload() {
method processSubsOnConfigReload (line 5802) | func (c *client) processSubsOnConfigReload(awcsti map[string]struct{}) {
method closeConnection (line 5870) | func (c *client) closeConnection(reason ClosedState) {
method reconnect (line 6019) | func (c *client) reconnect() {
method setNoReconnect (line 6114) | func (c *client) setNoReconnect() {
method getRTTValue (line 6121) | func (c *client) getRTTValue() time.Duration {
method getAccAndResultFromCache (line 6134) | func (c *client) getAccAndResultFromCache() (*Account, *SublistResult) {
method Account (line 6206) | func (c *client) Account() *Account {
method pruneClosedSubFromPerAccountCache (line 6218) | func (c *client) pruneClosedSubFromPerAccountCache() {
method addServerAndClusterInfo (line 6250) | func (c *client) addServerAndClusterInfo(ci *ClientInfo) {
method getClientInfo (line 6277) | func (c *client) getClientInfo(detailed bool) *ClientInfo {
method doTLSServerHandshake (line 6313) | func (c *client) doTLSServerHandshake(typ string, tlsConfig *tls.Confi...
method doTLSClientHandshake (line 6318) | func (c *client) doTLSClientHandshake(typ string, url *url.URL, tlsCon...
method doTLSHandshake (line 6327) | func (c *client) doTLSHandshake(typ string, solicit bool, url *url.URL...
method getRawAuthUserLock (line 6431) | func (c *client) getRawAuthUserLock() string {
method getRawAuthUser (line 6439) | func (c *client) getRawAuthUser() string {
method getAuthUser (line 6456) | func (c *client) getAuthUser() string {
method getAuthUserLabel (line 6472) | func (c *client) getAuthUserLabel() string {
method connectionTypeAllowed (line 6521) | func (c *client) connectionTypeAllowed(acts map[string]struct{}) bool {
method isClosed (line 6558) | func (c *client) isClosed() bool {
method format (line 6562) | func (c *client) format(format string) string {
method formatNoClientInfo (line 6570) | func (c *client) formatNoClientInfo(format string) string {
method formatClientSuffix (line 6579) | func (c *client) formatClientSuffix() string {
method Error (line 6588) | func (c *client) Error(err error) {
method Errorf (line 6592) | func (c *client) Errorf(format string, v ...any) {
method Debugf (line 6596) | func (c *client) Debugf(format string, v ...any) {
method Noticef (line 6600) | func (c *client) Noticef(format string, v ...any) {
method Tracef (line 6604) | func (c *client) Tracef(format string, v ...any) {
method Warnf (line 6608) | func (c *client) Warnf(format string, v ...any) {
method RateLimitErrorf (line 6612) | func (c *client) RateLimitErrorf(format string, v ...any) {
method rateLimitFormatWarnf (line 6625) | func (c *client) rateLimitFormatWarnf(format string, v ...any) {
method RateLimitWarnf (line 6639) | func (c *client) RateLimitWarnf(format string, v ...any) {
method RateLimitDebugf (line 6652) | func (c *client) RateLimitDebugf(format string, v ...any) {
method setFirstPingTimer (line 6668) | func (c *client) setFirstPingTimer() {
method setAuthError (line 6707) | func (c *client) setAuthError(err error) {
method getAuthError (line 6714) | func (c *client) getAuthError() error {
type rrTracking (line 335) | type rrTracking struct
type pinfo (line 342) | type pinfo struct
type outbound (line 348) | type outbound struct
constant nbMaxVectorSize (line 362) | nbMaxVectorSize = 1024
constant nbPoolSizeSmall (line 364) | nbPoolSizeSmall = 512
constant nbPoolSizeMedium (line 365) | nbPoolSizeMedium = 4096
constant nbPoolSizeLarge (line 366) | nbPoolSizeLarge = 65536
function nbPoolGet (line 392) | func nbPoolGet(sz int) []byte {
function nbPoolPut (line 407) | func nbPoolPut(b []byte) {
type perm (line 424) | type perm struct
type permissions (line 429) | type permissions struct
type resp (line 441) | type resp struct
type msgDeny (line 450) | type msgDeny struct
type routeTarget (line 457) | type routeTarget struct
constant maxResultCacheSize (line 464) | maxResultCacheSize = 512
constant maxDenyPermCacheSize (line 465) | maxDenyPermCacheSize = 256
constant maxPermCacheSize (line 466) | maxPermCacheSize = 128
constant pruneSize (line 467) | pruneSize = 32
constant routeTargetInit (line 468) | routeTargetInit = 8
constant replyPermLimit (line 469) | replyPermLimit = 4096
constant replyPruneTime (line 470) | replyPruneTime = time.Second
type readCacheFlag (line 474) | type readCacheFlag
method set (line 515) | func (rcf *readCacheFlag) set(c readCacheFlag) {
method clear (line 520) | func (rcf *readCacheFlag) clear(c readCacheFlag) {
method isSet (line 525) | func (rcf readCacheFlag) isSet(c readCacheFlag) bool {
constant hasMappings (line 477) | hasMappings readCacheFlag = 1 << iota
constant switchToCompression (line 478) | switchToCompression readCacheFlag = 1 << 1
constant sysGroup (line 481) | sysGroup = "_sys_"
type readCache (line 484) | type readCache struct
constant defaultMaxPerAccountCacheSize (line 530) | defaultMaxPerAccountCacheSize = 8192
constant defaultClosedSubsCheckInterval (line 531) | defaultClosedSubsCheckInterval = 5 * time.Minute
type perAccountCache (line 540) | type perAccountCache struct
type subscription (line 630) | type subscription struct
method close (line 650) | func (s *subscription) close() {
method isClosed (line 656) | func (s *subscription) isClosed() bool {
type ClientOpts (line 660) | type ClientOpts struct
function minLimit (line 908) | func minLimit(value *int32, limit int32) bool {
function splitSubjectQueue (line 1045) | func splitSubjectQueue(sq string) ([]byte, []byte, error) {
type denyType (line 1186) | type denyType
constant pub (line 1189) | pub = denyType(iota + 1)
constant sub (line 1190) | sub
constant both (line 1191) | both
function closedStateForErr (line 1600) | func closedStateForErr(err error) ClosedState {
function removeSecretsFromTrace (line 2128) | func removeSecretsFromTrace(arg []byte) []byte {
function redact (line 2133) | func redact(pat *regexp.Regexp, proto []byte) []byte {
function computeRTT (line 2157) | func computeRTT(start time.Time) time.Duration {
function splitArg (line 2873) | func splitArg(arg []byte) [][]byte {
type ime (line 3046) | type ime struct
function queueMatches (line 3289) | func queueMatches(queue string, qsubs [][]*subscription) bool {
function isServiceReply (line 4115) | func isServiceReply(reply []byte) bool {
function isReservedReply (line 4122) | func isReservedReply(reply []byte) bool {
function removeHeaderIfPresent (line 4393) | func removeHeaderIfPresent(hdr []byte, key string) []byte {
function removeHeaderIfPrefixPresent (line 4414) | func removeHeaderIfPrefixPresent(hdr []byte, prefix string) []byte {
function genHeader (line 4444) | func genHeader(hdr []byte, key, value string) []byte {
function getHeader (line 4498) | func getHeader(key string, hdr []byte) []byte {
function sliceHeader (line 4508) | func sliceHeader(key string, hdr []byte) []byte {
function getHeaderKeyIndex (line 4536) | func getHeaderKeyIndex(key string, hdr []byte) int {
function setHeader (line 4581) | func setHeader(key, val string, hdr []byte) []byte {
function adjustPingInterval (line 5601) | func adjustPingInterval(kind int, d time.Duration) time.Duration {
type qsub (line 5865) | type qsub struct
method serviceAccount (line 6239) | func (ci *ClientInfo) serviceAccount() string {
function convertAllowedConnectionTypes (line 6495) | func convertAllowedConnectionTypes(cts []string) (map[string]struct{}, e...
FILE: server/client_proxyproto.go
constant proxyProtoV2Sig (line 30) | proxyProtoV2Sig = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"
constant proxyProtoV2VerMask (line 33) | proxyProtoV2VerMask = 0xF0
constant proxyProtoV2Ver (line 34) | proxyProtoV2Ver = 0x20
constant proxyProtoCmdMask (line 37) | proxyProtoCmdMask = 0x0F
constant proxyProtoCmdLocal (line 38) | proxyProtoCmdLocal = 0x00
constant proxyProtoCmdProxy (line 39) | proxyProtoCmdProxy = 0x01
constant proxyProtoFamilyMask (line 42) | proxyProtoFamilyMask = 0xF0
constant proxyProtoFamilyUnspec (line 43) | proxyProtoFamilyUnspec = 0x00
constant proxyProtoFamilyInet (line 44) | proxyProtoFamilyInet = 0x10
constant proxyProtoFamilyInet6 (line 45) | proxyProtoFamilyInet6 = 0x20
constant proxyProtoFamilyUnix (line 46) | proxyProtoFamilyUnix = 0x30
constant proxyProtoProtoMask (line 47) | proxyProtoProtoMask = 0x0F
constant proxyProtoProtoUnspec (line 48) | proxyProtoProtoUnspec = 0x00
constant proxyProtoProtoStream (line 49) | proxyProtoProtoStream = 0x01
constant proxyProtoProtoDatagram (line 50) | proxyProtoProtoDatagram = 0x02
constant proxyProtoAddrSizeIPv4 (line 53) | proxyProtoAddrSizeIPv4 = 12
constant proxyProtoAddrSizeIPv6 (line 54) | proxyProtoAddrSizeIPv6 = 36
constant proxyProtoV2HeaderSize (line 57) | proxyProtoV2HeaderSize = 16
constant proxyProtoReadTimeout (line 60) | proxyProtoReadTimeout = 5 * time.Second
constant proxyProtoV1Prefix (line 65) | proxyProtoV1Prefix = "PROXY "
constant proxyProtoV1MaxLineLen (line 66) | proxyProtoV1MaxLineLen = 107
constant proxyProtoV1TCP4 (line 67) | proxyProtoV1TCP4 = "TCP4"
constant proxyProtoV1TCP6 (line 68) | proxyProtoV1TCP6 = "TCP6"
constant proxyProtoV1Unknown (line 69) | proxyProtoV1Unknown = "UNKNOWN"
type proxyProtoAddr (line 81) | type proxyProtoAddr struct
method String (line 89) | func (p *proxyProtoAddr) String() string {
method Network (line 94) | func (p *proxyProtoAddr) Network() string {
type proxyConn (line 103) | type proxyConn struct
method RemoteAddr (line 109) | func (pc *proxyConn) RemoteAddr() net.Addr {
function detectProxyProtoVersion (line 116) | func detectProxyProtoVersion(conn net.Conn) (version int, header []byte,...
function readProxyProtoV1Header (line 136) | func readProxyProtoV1Header(conn net.Conn) (*proxyProtoAddr, []byte, err...
function readProxyProtoHeader (line 232) | func readProxyProtoHeader(conn net.Conn) (*proxyProtoAddr, []byte, error) {
function readProxyProtoV2Header (line 281) | func readProxyProtoV2Header(conn net.Conn) (*proxyProtoAddr, error) {
function parseProxyProtoV2Header (line 308) | func parseProxyProtoV2Header(conn net.Conn, header []byte) (*proxyProtoA...
function parseIPv4Addr (line 372) | func parseIPv4Addr(conn net.Conn, addrLen uint16) (*proxyProtoAddr, erro...
function parseIPv6Addr (line 390) | func parseIPv6Addr(conn net.Conn, addrLen uint16) (*proxyProtoAddr, erro...
FILE: server/client_proxyproto_test.go
type mockConn (line 29) | type mockConn struct
method Read (line 44) | func (m *mockConn) Read(b []byte) (int, error) {
method Write (line 54) | func (m *mockConn) Write(b []byte) (int, error) {
method Close (line 61) | func (m *mockConn) Close() error {
method LocalAddr (line 66) | func (m *mockConn) LocalAddr() net.Addr {
method RemoteAddr (line 70) | func (m *mockConn) RemoteAddr() net.Addr {
method SetDeadline (line 74) | func (m *mockConn) SetDeadline(t time.Time) error {
method SetReadDeadline (line 79) | func (m *mockConn) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 84) | func (m *mockConn) SetWriteDeadline(t time.Time) error {
function newMockConn (line 37) | func newMockConn(data []byte) *mockConn {
function buildProxyV2Header (line 89) | func buildProxyV2Header(t *testing.T, srcIP, dstIP string, srcPort, dstP...
function buildProxyV2LocalHeader (line 128) | func buildProxyV2LocalHeader() []byte {
function buildProxyV1Header (line 139) | func buildProxyV1Header(t *testing.T, protocol, srcIP, dstIP string, src...
function TestClientProxyProtoV2ParseIPv4 (line 156) | func TestClientProxyProtoV2ParseIPv4(t *testing.T) {
function TestClientProxyProtoV2ParseIPv6 (line 175) | func TestClientProxyProtoV2ParseIPv6(t *testing.T) {
function TestClientProxyProtoV2ParseLocalCommand (line 194) | func TestClientProxyProtoV2ParseLocalCommand(t *testing.T) {
function TestClientProxyProtoV2InvalidSignature (line 203) | func TestClientProxyProtoV2InvalidSignature(t *testing.T) {
function TestClientProxyProtoV2InvalidVersion (line 213) | func TestClientProxyProtoV2InvalidVersion(t *testing.T) {
function TestClientProxyProtoV2UnsupportedFamily (line 227) | func TestClientProxyProtoV2UnsupportedFamily(t *testing.T) {
function TestClientProxyProtoV2UnsupportedProtocol (line 241) | func TestClientProxyProtoV2UnsupportedProtocol(t *testing.T) {
function TestClientProxyProtoV2TruncatedHeader (line 255) | func TestClientProxyProtoV2TruncatedHeader(t *testing.T) {
function TestClientProxyProtoV2ShortAddressData (line 264) | func TestClientProxyProtoV2ShortAddressData(t *testing.T) {
function TestProxyConnRemoteAddr (line 281) | func TestProxyConnRemoteAddr(t *testing.T) {
function TestClientProxyProtoV2EndToEnd (line 305) | func TestClientProxyProtoV2EndToEnd(t *testing.T) {
function TestClientProxyProtoV2LocalCommandEndToEnd (line 367) | func TestClientProxyProtoV2LocalCommandEndToEnd(t *testing.T) {
function TestClientProxyProtoV1ParseTCP4 (line 417) | func TestClientProxyProtoV1ParseTCP4(t *testing.T) {
function TestClientProxyProtoV1ParseTCP6 (line 432) | func TestClientProxyProtoV1ParseTCP6(t *testing.T) {
function TestClientProxyProtoV1ParseUnknown (line 447) | func TestClientProxyProtoV1ParseUnknown(t *testing.T) {
function TestClientProxyProtoV1PreservesCoalescedClientBytes (line 456) | func TestClientProxyProtoV1PreservesCoalescedClientBytes(t *testing.T) {
function TestClientProxyProtoV1InvalidFormat (line 471) | func TestClientProxyProtoV1InvalidFormat(t *testing.T) {
function TestClientProxyProtoV1LineTooLong (line 480) | func TestClientProxyProtoV1LineTooLong(t *testing.T) {
function TestClientProxyProtoV1InvalidIP (line 490) | func TestClientProxyProtoV1InvalidIP(t *testing.T) {
function TestClientProxyProtoV1MismatchedProtocol (line 498) | func TestClientProxyProtoV1MismatchedProtocol(t *testing.T) {
function TestClientProxyProtoV1InvalidPort (line 514) | func TestClientProxyProtoV1InvalidPort(t *testing.T) {
function TestClientProxyProtoV1EndToEnd (line 522) | func TestClientProxyProtoV1EndToEnd(t *testing.T) {
function TestClientProxyProtoVersionDetection (line 586) | func TestClientProxyProtoVersionDetection(t *testing.T) {
function TestClientProxyProtoUnrecognizedVersion (line 606) | func TestClientProxyProtoUnrecognizedVersion(t *testing.T) {
FILE: server/client_test.go
type serverInfo (line 43) | type serverInfo struct
type testAsyncClient (line 57) | type testAsyncClient struct
method close (line 63) | func (c *testAsyncClient) close() {
method parse (line 68) | func (c *testAsyncClient) parse(proto []byte) error {
method parseAndClose (line 74) | func (c *testAsyncClient) parseAndClose(proto []byte) {
function createClientAsync (line 80) | func createClientAsync(ch chan *client, s *Server, cli net.Conn) {
function newClientForServer (line 100) | func newClientForServer(s *Server) (*testAsyncClient, *bufio.Reader, str...
function genAsyncParser (line 119) | func genAsyncParser(c *client) (func(string), chan bool) {
function rawSetup (line 147) | func rawSetup(serverOptions Options) (*Server, *testAsyncClient, *bufio....
function setUpClientWithResponse (line 153) | func setUpClientWithResponse() (*testAsyncClient, string) {
function setupClient (line 158) | func setupClient() (*Server, *testAsyncClient, *bufio.Reader) {
function checkClientsCount (line 163) | func checkClientsCount(t *testing.T, s *Server, expected int) {
function checkAccClientsCount (line 173) | func checkAccClientsCount(t *testing.T, acc *Account, expected int) {
function TestAsyncClientWithRunningServer (line 184) | func TestAsyncClientWithRunningServer(t *testing.T) {
function TestClientCreateAndInfo (line 203) | func TestClientCreateAndInfo(t *testing.T) {
function TestClientNoResponderSupport (line 231) | func TestClientNoResponderSupport(t *testing.T) {
function TestServerHeaderSupport (line 260) | func TestServerHeaderSupport(t *testing.T) {
function TestClientHeaderSupport (line 296) | func TestClientHeaderSupport(t *testing.T) {
function TestClientHeaderDeliverMsg (line 331) | func TestClientHeaderDeliverMsg(t *testing.T) {
function TestClientHeaderDeliverStrippedMsg (line 374) | func TestClientHeaderDeliverStrippedMsg(t *testing.T) {
function TestClientHeaderDeliverQueueSubStrippedMsg (line 422) | func TestClientHeaderDeliverQueueSubStrippedMsg(t *testing.T) {
function TestNonTLSConnectionState (line 467) | func TestNonTLSConnectionState(t *testing.T) {
function TestClientConnect (line 476) | func TestClientConnect(t *testing.T) {
function TestClientConnectProto (line 538) | func TestClientConnectProto(t *testing.T) {
function TestRemoteAddress (line 596) | func TestRemoteAddress(t *testing.T) {
function TestClientPing (line 617) | func TestClientPing(t *testing.T) {
constant SUB_INDEX (line 636) | SUB_INDEX = 1
constant SID_INDEX (line 637) | SID_INDEX = 2
constant REPLY_INDEX (line 638) | REPLY_INDEX = 4
constant LEN_INDEX (line 639) | LEN_INDEX = 5
constant HDR_INDEX (line 640) | HDR_INDEX = 5
constant TLEN_INDEX (line 641) | TLEN_INDEX = 6
function grabPayload (line 644) | func grabPayload(cr *bufio.Reader, expected int) []byte {
function checkPayload (line 651) | func checkPayload(cr *bufio.Reader, expected []byte, t *testing.T) {
function TestClientSimplePubSub (line 667) | func TestClientSimplePubSub(t *testing.T) {
function TestClientPubSubNoEcho (line 692) | func TestClientPubSubNoEcho(t *testing.T) {
function TestClientSimplePubSubWithReply (line 713) | func TestClientSimplePubSubWithReply(t *testing.T) {
function TestClientNoBodyPubSubWithReply (line 741) | func TestClientNoBodyPubSubWithReply(t *testing.T) {
function TestClientPubWithQueueSub (line 769) | func TestClientPubWithQueueSub(t *testing.T) {
function TestSplitSubjectQueue (line 812) | func TestSplitSubjectQueue(t *testing.T) {
function TestTypeString (line 852) | func TestTypeString(t *testing.T) {
function TestQueueSubscribePermissions (line 900) | func TestQueueSubscribePermissions(t *testing.T) {
function TestClientPubWithQueueSubNoEcho (line 1044) | func TestClientPubWithQueueSubNoEcho(t *testing.T) {
function TestClientUnSub (line 1111) | func TestClientUnSub(t *testing.T) {
function TestClientUnSubMax (line 1146) | func TestClientUnSubMax(t *testing.T) {
function TestClientAutoUnsubExactReceived (line 1184) | func TestClientAutoUnsubExactReceived(t *testing.T) {
function TestClientUnsubAfterAutoUnsub (line 1206) | func TestClientUnsubAfterAutoUnsub(t *testing.T) {
function TestClientRemoveSubsOnDisconnect (line 1228) | func TestClientRemoveSubsOnDisconnect(t *testing.T) {
function TestClientDoesNotAddSubscriptionsWhenConnectionClosed (line 1242) | func TestClientDoesNotAddSubscriptionsWhenConnectionClosed(t *testing.T) {
function TestClientMapRemoval (line 1254) | func TestClientMapRemoval(t *testing.T) {
function TestAuthorizationTimeout (line 1261) | func TestAuthorizationTimeout(t *testing.T) {
function TestTwoTokenPubMatchSingleTokenSub (line 1288) | func TestTwoTokenPubMatchSingleTokenSub(t *testing.T) {
function TestUnsubRace (line 1307) | func TestUnsubRace(t *testing.T) {
function TestClientCloseTLSConnection (line 1351) | func TestClientCloseTLSConnection(t *testing.T) {
function TestWildcardCharsInLiteralSubjectWorks (line 1445) | func TestWildcardCharsInLiteralSubjectWorks(t *testing.T) {
function TestClientOutboundQueueCoalesce (line 1492) | func TestClientOutboundQueueCoalesce(t *testing.T) {
function TestClientTraceRace (line 1548) | func TestClientTraceRace(t *testing.T) {
function TestClientUserInfo (line 1595) | func TestClientUserInfo(t *testing.T) {
type captureWarnLogger (line 1644) | type captureWarnLogger struct
method Warnf (line 1649) | func (l *captureWarnLogger) Warnf(format string, v ...any) {
function TestReadloopWarning (line 1656) | func TestReadloopWarning(t *testing.T) {
function TestTraceMsg (line 1701) | func TestTraceMsg(t *testing.T) {
function TestTraceMsgHeadersOnly (line 1754) | func TestTraceMsgHeadersOnly(t *testing.T) {
function TestTraceMsgDelivery (line 1822) | func TestTraceMsgDelivery(t *testing.T) {
function TestTraceMsgDeliveryWithHeaders (line 1887) | func TestTraceMsgDeliveryWithHeaders(t *testing.T) {
function TestClientMaxPending (line 1977) | func TestClientMaxPending(t *testing.T) {
function TestResponsePermissions (line 1991) | func TestResponsePermissions(t *testing.T) {
function TestPingNotSentTooSoon (line 2077) | func TestPingNotSentTooSoon(t *testing.T) {
function TestClientCheckUseOfGWReplyPrefix (line 2139) | func TestClientCheckUseOfGWReplyPrefix(t *testing.T) {
function TestNoClientLeakOnSlowConsumer (line 2182) | func TestNoClientLeakOnSlowConsumer(t *testing.T) {
function TestClientSlowConsumerWithoutConnect (line 2237) | func TestClientSlowConsumerWithoutConnect(t *testing.T) {
function TestClientNoSlowConsumerIfConnectExpected (line 2280) | func TestClientNoSlowConsumerIfConnectExpected(t *testing.T) {
function TestClientIPv6Address (line 2301) | func TestClientIPv6Address(t *testing.T) {
function TestPBNotIncreasedOnMaxPending (line 2324) | func TestPBNotIncreasedOnMaxPending(t *testing.T) {
type testConnWritePartial (line 2341) | type testConnWritePartial struct
method Write (line 2347) | func (c *testConnWritePartial) Write(p []byte) (int, error) {
method RemoteAddr (line 2355) | func (c *testConnWritePartial) RemoteAddr() net.Addr {
method SetWriteDeadline (line 2359) | func (c *testConnWritePartial) SetWriteDeadline(_ time.Time) error {
function TestFlushOutboundNoSliceReuseIfPartial (line 2363) | func TestFlushOutboundNoSliceReuseIfPartial(t *testing.T) {
type captureNoticeLogger (line 2401) | type captureNoticeLogger struct
method Noticef (line 2406) | func (l *captureNoticeLogger) Noticef(format string, v ...any) {
function TestCloseConnectionLogsReason (line 2412) | func TestCloseConnectionLogsReason(t *testing.T) {
function TestCloseConnectionVeryEarly (line 2449) | func TestCloseConnectionVeryEarly(t *testing.T) {
type connAddrString (line 2501) | type connAddrString struct
method String (line 2505) | func (a *connAddrString) String() string {
type connString (line 2509) | type connString struct
method RemoteAddr (line 2513) | func (c *connString) RemoteAddr() net.Addr {
function TestClientConnectionName (line 2517) | func TestClientConnectionName(t *testing.T) {
function TestClientLimits (line 2584) | func TestClientLimits(t *testing.T) {
function TestClientClampMaxSubsErrReport (line 2646) | func TestClientClampMaxSubsErrReport(t *testing.T) {
function TestClientDenySysGroupSub (line 2703) | func TestClientDenySysGroupSub(t *testing.T) {
function TestClientAuthRequiredNoAuthUser (line 2719) | func TestClientAuthRequiredNoAuthUser(t *testing.T) {
function TestClientUserInfoReq (line 2740) | func TestClientUserInfoReq(t *testing.T) {
function TestTLSClientHandshakeFirst (line 2818) | func TestTLSClientHandshakeFirst(t *testing.T) {
function TestTLSClientHandshakeFirstFallbackDelayConfigValues (line 2880) | func TestTLSClientHandshakeFirstFallbackDelayConfigValues(t *testing.T) {
type pauseAfterDial (line 2930) | type pauseAfterDial struct
method Dial (line 2934) | func (d *pauseAfterDial) Dial(network, address string) (net.Conn, erro...
function TestTLSClientHandshakeFirstFallbackDelay (line 2943) | func TestTLSClientHandshakeFirstFallbackDelay(t *testing.T) {
function TestTLSClientHandshakeFirstFallbackDelayAndAllowNonTLS (line 3011) | func TestTLSClientHandshakeFirstFallbackDelayAndAllowNonTLS(t *testing.T) {
function TestTLSClientHandshakeFirstAndInProcessConnection (line 3105) | func TestTLSClientHandshakeFirstAndInProcessConnection(t *testing.T) {
function TestRemoveHeaderIfPrefixPresent (line 3161) | func TestRemoveHeaderIfPrefixPresent(t *testing.T) {
function TestSliceHeader (line 3179) | func TestSliceHeader(t *testing.T) {
function TestSliceHeaderOrderingPrefix (line 3202) | func TestSliceHeaderOrderingPrefix(t *testing.T) {
function TestSliceHeaderOrderingSuffix (line 3222) | func TestSliceHeaderOrderingSuffix(t *testing.T) {
function TestRemoveHeaderIfPresentOrderingPrefix (line 3239) | func TestRemoveHeaderIfPresentOrderingPrefix(t *testing.T) {
function TestRemoveHeaderIfPresentOrderingSuffix (line 3252) | func TestRemoveHeaderIfPresentOrderingSuffix(t *testing.T) {
function TestMsgPartsCapsHdrSlice (line 3265) | func TestMsgPartsCapsHdrSlice(t *testing.T) {
function TestSetHeaderDoesNotOverwriteUnderlyingBuffer (line 3286) | func TestSetHeaderDoesNotOverwriteUnderlyingBuffer(t *testing.T) {
function TestSetHeaderOrderingPrefix (line 3324) | func TestSetHeaderOrderingPrefix(t *testing.T) {
function TestSetHeaderOrderingSuffix (line 3352) | func TestSetHeaderOrderingSuffix(t *testing.T) {
function TestInProcessAllowedConnectionType (line 3380) | func TestInProcessAllowedConnectionType(t *testing.T) {
function TestClientFlushOutboundNoSlowConsumer (line 3473) | func TestClientFlushOutboundNoSlowConsumer(t *testing.T) {
function TestClientRejectsNRGSubjects (line 3543) | func TestClientRejectsNRGSubjects(t *testing.T) {
function TestConnectionStringWithLogConnectionInfo (line 3590) | func TestConnectionStringWithLogConnectionInfo(t *testing.T) {
function TestLogConnectionAuthInfo (line 3646) | func TestLogConnectionAuthInfo(t *testing.T) {
function TestClientConfigureWriteTimeoutPolicy (line 3753) | func TestClientConfigureWriteTimeoutPolicy(t *testing.T) {
type writeTimeoutPolicyWriter (line 3787) | type writeTimeoutPolicyWriter struct
method SetWriteDeadline (line 3793) | func (w *writeTimeoutPolicyWriter) SetWriteDeadline(deadline time.Time...
method Write (line 3798) | func (w *writeTimeoutPolicyWriter) Write(b []byte) (int, error) {
function TestClientFlushOutboundWriteTimeoutPolicy (line 3807) | func TestClientFlushOutboundWriteTimeoutPolicy(t *testing.T) {
function TestFlushOutboundS2CompressionPoolBufferRecycling (line 3862) | func TestFlushOutboundS2CompressionPoolBufferRecycling(t *testing.T) {
FILE: server/closed_conns_test.go
function checkClosedConns (line 26) | func checkClosedConns(t *testing.T, s *Server, num int, wait time.Durati...
function checkTotalClosedConns (line 36) | func checkTotalClosedConns(t *testing.T, s *Server, num uint64, wait tim...
function TestClosedConnsAccounting (line 46) | func TestClosedConnsAccounting(t *testing.T) {
function TestClosedConnsSubsAccounting (line 102) | func TestClosedConnsSubsAccounting(t *testing.T) {
function checkReason (line 136) | func checkReason(t *testing.T, reason string, expected ClosedState) {
function TestClosedAuthorizationTimeout (line 143) | func TestClosedAuthorizationTimeout(t *testing.T) {
function TestClosedAuthorizationViolation (line 164) | func TestClosedAuthorizationViolation(t *testing.T) {
function TestClosedUPAuthorizationViolation (line 187) | func TestClosedUPAuthorizationViolation(t *testing.T) {
function TestClosedMaxPayload (line 219) | func TestClosedMaxPayload(t *testing.T) {
function TestClosedTLSHandshake (line 247) | func TestClosedTLSHandshake(t *testing.T) {
FILE: server/config_check_test.go
function TestConfigCheck (line 23) | func TestConfigCheck(t *testing.T) {
function TestConfigCheckIncludes (line 2550) | func TestConfigCheckIncludes(t *testing.T) {
function TestConfigCheckMultipleErrors (line 2573) | func TestConfigCheckMultipleErrors(t *testing.T) {
FILE: server/const.go
type Command (line 23) | type Command
constant CommandStop (line 27) | CommandStop = Command("stop")
constant CommandQuit (line 28) | CommandQuit = Command("quit")
constant CommandReopen (line 29) | CommandReopen = Command("reopen")
constant CommandReload (line 30) | CommandReload = Command("reload")
constant commandLDMode (line 33) | commandLDMode = Command("ldm")
constant commandTerm (line 34) | commandTerm = Command("term")
function formatRevision (line 47) | func formatRevision(revision string) string {
function init (line 54) | func init() {
constant VERSION (line 69) | VERSION = "2.14.0-dev"
constant PROTO (line 75) | PROTO = 1
constant DEFAULT_PORT (line 78) | DEFAULT_PORT = 4222
constant RANDOM_PORT (line 83) | RANDOM_PORT = -1
constant DEFAULT_HOST (line 86) | DEFAULT_HOST = "0.0.0.0"
constant MAX_CONTROL_LINE_SIZE (line 90) | MAX_CONTROL_LINE_SIZE = 4096
constant MAX_PAYLOAD_SIZE (line 94) | MAX_PAYLOAD_SIZE = (1024 * 1024)
constant MAX_PAYLOAD_MAX_SIZE (line 99) | MAX_PAYLOAD_MAX_SIZE = (8 * 1024 * 1024)
constant MAX_PENDING_SIZE (line 102) | MAX_PENDING_SIZE = (64 * 1024 * 1024)
constant DEFAULT_MAX_CONNECTIONS (line 105) | DEFAULT_MAX_CONNECTIONS = (64 * 1024)
constant TLS_TIMEOUT (line 108) | TLS_TIMEOUT = 2 * time.Second
constant DEFAULT_TLS_HANDSHAKE_FIRST_FALLBACK_DELAY (line 114) | DEFAULT_TLS_HANDSHAKE_FIRST_FALLBACK_DELAY = 50 * time.Millisecond
constant AUTH_TIMEOUT (line 117) | AUTH_TIMEOUT = 2 * time.Second
constant DEFAULT_PING_INTERVAL (line 120) | DEFAULT_PING_INTERVAL = 2 * time.Minute
constant DEFAULT_PING_MAX_OUT (line 123) | DEFAULT_PING_MAX_OUT = 2
constant CR_LF (line 126) | CR_LF = "\r\n"
constant LEN_CR_LF (line 129) | LEN_CR_LF = len(CR_LF)
constant DEFAULT_FLUSH_DEADLINE (line 132) | DEFAULT_FLUSH_DEADLINE = 10 * time.Second
constant DEFAULT_HTTP_PORT (line 135) | DEFAULT_HTTP_PORT = 8222
constant DEFAULT_HTTP_BASE_PATH (line 138) | DEFAULT_HTTP_BASE_PATH = "/"
constant ACCEPT_MIN_SLEEP (line 141) | ACCEPT_MIN_SLEEP = 10 * time.Millisecond
constant ACCEPT_MAX_SLEEP (line 144) | ACCEPT_MAX_SLEEP = 1 * time.Second
constant DEFAULT_ROUTE_CONNECT (line 147) | DEFAULT_ROUTE_CONNECT = 1 * time.Second
constant DEFAULT_ROUTE_CONNECT_MAX (line 150) | DEFAULT_ROUTE_CONNECT_MAX = 30 * time.Second
constant DEFAULT_ROUTE_RECONNECT (line 153) | DEFAULT_ROUTE_RECONNECT = 1 * time.Second
constant DEFAULT_ROUTE_DIAL (line 156) | DEFAULT_ROUTE_DIAL = 1 * time.Second
constant DEFAULT_ROUTE_POOL_SIZE (line 159) | DEFAULT_ROUTE_POOL_SIZE = 3
constant DEFAULT_LEAF_NODE_RECONNECT (line 162) | DEFAULT_LEAF_NODE_RECONNECT = time.Second
constant DEFAULT_LEAF_TLS_TIMEOUT (line 165) | DEFAULT_LEAF_TLS_TIMEOUT = 2 * time.Second
constant PROTO_SNIPPET_SIZE (line 168) | PROTO_SNIPPET_SIZE = 32
constant MAX_CONTROL_LINE_SNIPPET_SIZE (line 171) | MAX_CONTROL_LINE_SNIPPET_SIZE = 128
constant MAX_MSG_ARGS (line 174) | MAX_MSG_ARGS = 4
constant MAX_RMSG_ARGS (line 177) | MAX_RMSG_ARGS = 6
constant MAX_HMSG_ARGS (line 180) | MAX_HMSG_ARGS = 7
constant MAX_PUB_ARGS (line 183) | MAX_PUB_ARGS = 3
constant MAX_HPUB_ARGS (line 186) | MAX_HPUB_ARGS = 4
constant MAX_RSUB_ARGS (line 189) | MAX_RSUB_ARGS = 6
constant DEFAULT_MAX_CLOSED_CLIENTS (line 192) | DEFAULT_MAX_CLOSED_CLIENTS = 10000
constant DEFAULT_LAME_DUCK_DURATION (line 196) | DEFAULT_LAME_DUCK_DURATION = 2 * time.Minute
constant DEFAULT_LAME_DUCK_GRACE_PERIOD (line 200) | DEFAULT_LAME_DUCK_GRACE_PERIOD = 10 * time.Second
constant DEFAULT_LEAFNODE_INFO_WAIT (line 203) | DEFAULT_LEAFNODE_INFO_WAIT = 1 * time.Second
constant DEFAULT_LEAFNODE_PORT (line 206) | DEFAULT_LEAFNODE_PORT = 7422
constant DEFAULT_CONNECT_ERROR_REPORTS (line 215) | DEFAULT_CONNECT_ERROR_REPORTS = 3600
constant DEFAULT_RECONNECT_ERROR_REPORTS (line 220) | DEFAULT_RECONNECT_ERROR_REPORTS = 1
constant DEFAULT_RTT_MEASUREMENT_INTERVAL (line 224) | DEFAULT_RTT_MEASUREMENT_INTERVAL = time.Hour
constant DEFAULT_ALLOW_RESPONSE_MAX_MSGS (line 228) | DEFAULT_ALLOW_RESPONSE_MAX_MSGS = 1
constant DEFAULT_ALLOW_RESPONSE_EXPIRATION (line 232) | DEFAULT_ALLOW_RESPONSE_EXPIRATION = 2 * time.Minute
constant DEFAULT_SERVICE_EXPORT_RESPONSE_THRESHOLD (line 237) | DEFAULT_SERVICE_EXPORT_RESPONSE_THRESHOLD = 2 * time.Minute
constant DEFAULT_SERVICE_LATENCY_SAMPLING (line 241) | DEFAULT_SERVICE_LATENCY_SAMPLING = 100
constant DEFAULT_SYSTEM_ACCOUNT (line 244) | DEFAULT_SYSTEM_ACCOUNT = "$SYS"
constant DEFAULT_GLOBAL_ACCOUNT (line 247) | DEFAULT_GLOBAL_ACCOUNT = "$G"
constant DEFAULT_ACCOUNT_FETCH_TIMEOUT (line 250) | DEFAULT_ACCOUNT_FETCH_TIMEOUT = 1900 * time.Millisecond
FILE: server/consumer.go
constant JSPullRequestPendingMsgs (line 43) | JSPullRequestPendingMsgs = "Nats-Pending-Messages"
constant JSPullRequestPendingBytes (line 44) | JSPullRequestPendingBytes = "Nats-Pending-Bytes"
constant JSPullRequestNatsPinId (line 45) | JSPullRequestNatsPinId = "Nats-Pin-Id"
constant JsPullRequestRemainingBytesT (line 53) | JsPullRequestRemainingBytesT = "NATS/1.0 409 Batch Completed\r\n%s: %d\r...
type ConsumerInfo (line 55) | type ConsumerInfo struct
type consumerInfoClusterResponse (line 77) | type consumerInfoClusterResponse struct
type PriorityGroupState (line 82) | type PriorityGroupState struct
type ConsumerConfig (line 88) | type ConsumerConfig struct
method replicas (line 397) | func (consCfg ConsumerConfig) replicas(strCfg *StreamConfig) int {
type SequenceInfo (line 143) | type SequenceInfo struct
type CreateConsumerRequest (line 149) | type CreateConsumerRequest struct
type ConsumerAction (line 156) | type ConsumerAction
method String (line 176) | func (a ConsumerAction) String() string {
method MarshalJSON (line 188) | func (a ConsumerAction) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 201) | func (a *ConsumerAction) UnmarshalJSON(data []byte) error {
constant ActionCreateOrUpdate (line 159) | ActionCreateOrUpdate ConsumerAction = iota
constant ActionUpdate (line 160) | ActionUpdate
constant ActionCreate (line 161) | ActionCreate
constant actionUpdateJSONString (line 165) | actionUpdateJSONString = `"update"`
constant actionCreateJSONString (line 166) | actionCreateJSONString = `"create"`
constant actionCreateOrUpdateJSONString (line 167) | actionCreateOrUpdateJSONString = `""`
type ConsumerNakOptions (line 216) | type ConsumerNakOptions struct
type PriorityPolicy (line 221) | type PriorityPolicy
method String (line 248) | func (pp PriorityPolicy) String() string {
method MarshalJSON (line 261) | func (pp PriorityPolicy) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 276) | func (pp *PriorityPolicy) UnmarshalJSON(data []byte) error {
constant PriorityNone (line 225) | PriorityNone PriorityPolicy = iota
constant PriorityOverflow (line 227) | PriorityOverflow
constant PriorityPinnedClient (line 229) | PriorityPinnedClient
constant PriorityPrioritized (line 231) | PriorityPrioritized
constant PriorityNoneJSONString (line 235) | PriorityNoneJSONString = `"none"`
constant PriorityOverflowJSONString (line 236) | PriorityOverflowJSONString = `"overflow"`
constant PriorityPinnedClientJSONString (line 237) | PriorityPinnedClientJSONString = `"pinned_client"`
constant PriorityPrioritizedJSONString (line 238) | PriorityPrioritizedJSONString = `"prioritized"`
type DeliverPolicy (line 293) | type DeliverPolicy
method String (line 310) | func (dp DeliverPolicy) String() string {
constant DeliverAll (line 297) | DeliverAll DeliverPolicy = iota
constant DeliverLast (line 299) | DeliverLast
constant DeliverNew (line 301) | DeliverNew
constant DeliverByStartSequence (line 303) | DeliverByStartSequence
constant DeliverByStartTime (line 305) | DeliverByStartTime
constant DeliverLastPerSubject (line 307) | DeliverLastPerSubject
type AckPolicy (line 330) | type AckPolicy
method String (line 341) | func (a AckPolicy) String() string {
constant AckNone (line 334) | AckNone AckPolicy = iota
constant AckAll (line 336) | AckAll
constant AckExplicit (line 338) | AckExplicit
type ReplayPolicy (line 353) | type ReplayPolicy
method String (line 362) | func (r ReplayPolicy) String() string {
constant ReplayInstant (line 357) | ReplayInstant ReplayPolicy = iota
constant ReplayOriginal (line 359) | ReplayOriginal
constant OK (line 372) | OK = "+OK"
constant ackTermLimitsReason (line 392) | ackTermLimitsReason = "Message deleted by stream limits"
constant ackTermUnackedLimitsReason (line 393) | ackTermUnackedLimitsReason = "Unacknowledged message was deleted"
type consumer (line 409) | type consumer struct
method updateInactiveThreshold (line 1379) | func (o *consumer) updateInactiveThreshold(cfg *ConsumerConfig) {
method updatePauseState (line 1402) | func (o *consumer) updatePauseState(cfg *ConsumerConfig) {
method consumerAssignment (line 1427) | func (o *consumer) consumerAssignment() *consumerAssignment {
method setConsumerAssignment (line 1433) | func (o *consumer) setConsumerAssignment(ca *consumerAssignment) {
method monitorQuitC (line 1451) | func (o *consumer) monitorQuitC() <-chan struct{} {
method signalMonitorQuit (line 1466) | func (o *consumer) signalMonitorQuit() {
method updateC (line 1475) | func (o *consumer) updateC() <-chan struct{} {
method checkQueueInterest (line 1483) | func (o *consumer) checkQueueInterest() {
method clearNode (line 1503) | func (o *consumer) clearNode() {
method IsLeader (line 1513) | func (o *consumer) IsLeader() bool {
method isLeader (line 1518) | func (o *consumer) isLeader() bool {
method setLeader (line 1522) | func (o *consumer) setLeader(isLeader bool) {
method handleClusterConsumerInfoRequest (line 1762) | func (o *consumer) handleClusterConsumerInfoRequest(sub *subscription,...
method subscribeInternal (line 1767) | func (o *consumer) subscribeInternal(subject string, cb msgHandler) (*...
method unsubscribe (line 1787) | func (o *consumer) unsubscribe(sub *subscription) {
method sendAdvisory (line 1796) | func (o *consumer) sendAdvisory(subject string, e any) {
method sendDeleteAdvisoryLocked (line 1815) | func (o *consumer) sendDeleteAdvisoryLocked() {
method sendPinnedAdvisoryLocked (line 1832) | func (o *consumer) sendPinnedAdvisoryLocked(group string) {
method sendUnpinnedAdvisoryLocked (line 1851) | func (o *consumer) sendUnpinnedAdvisoryLocked(group string, reason str...
method sendCreateAdvisory (line 1871) | func (o *consumer) sendCreateAdvisory() {
method sendPauseAdvisoryLocked (line 1891) | func (o *consumer) sendPauseAdvisoryLocked(cfg *ConsumerConfig) {
method createdTime (line 1913) | func (o *consumer) createdTime() time.Time {
method setCreatedTime (line 1921) | func (o *consumer) setCreatedTime(created time.Time) {
method hasDeliveryInterest (line 1930) | func (o *consumer) hasDeliveryInterest(localInterest bool) bool {
method updateDeliveryInterest (line 1969) | func (o *consumer) updateDeliveryInterest(localInterest bool) bool {
method deleteNotActive (line 2021) | func (o *consumer) deleteNotActive() {
method watchGWinterest (line 2185) | func (o *consumer) watchGWinterest() {
method config (line 2207) | func (o *consumer) config() ConsumerConfig {
method hasMaxDeliveries (line 2216) | func (o *consumer) hasMaxDeliveries(seq uint64) bool {
method forceExpirePending (line 2247) | func (o *consumer) forceExpirePending() {
method setRateLimitNeedsLocks (line 2272) | func (o *consumer) setRateLimitNeedsLocks() {
method setRateLimit (line 2290) | func (o *consumer) setRateLimit(bps uint64) {
method updateConfig (line 2377) | func (o *consumer) updateConfig(cfg *ConsumerConfig) error {
method updateDeliverSubject (line 2524) | func (o *consumer) updateDeliverSubject(newDeliver string) {
method updateDeliverSubjectLocked (line 2533) | func (o *consumer) updateDeliverSubjectLocked(newDeliver string) {
method sendAckReply (line 2557) | func (o *consumer) sendAckReply(subj string) {
method pushAck (line 2596) | func (o *consumer) pushAck(_ *subscription, c *client, _ *Account, sub...
method processAck (line 2602) | func (o *consumer) processAck(subject, reply string, hdr int, rmsg []b...
method progressUpdate (line 2648) | func (o *consumer) progressUpdate(seq uint64) {
method updateSkipped (line 2660) | func (o *consumer) updateSkipped(seq uint64) {
method resetStartingSeq (line 2672) | func (o *consumer) resetStartingSeq(seq uint64, reply string) (uint64,...
method resetLocalStartingSeq (line 2735) | func (o *consumer) resetLocalStartingSeq(seq uint64) {
method loopAndForwardProposals (line 2744) | func (o *consumer) loopAndForwardProposals(qch chan struct{}) {
method propose (line 2805) | func (o *consumer) propose(entry []byte) {
method updateDelivered (line 2822) | func (o *consumer) updateDelivered(dseq, sseq, dc uint64, ts int64) {
method addAckReply (line 2843) | func (o *consumer) addAckReply(sseq uint64, reply string) {
method addReplicatedQueuedMsg (line 2852) | func (o *consumer) addReplicatedQueuedMsg(pmsg *jsPubMsg) {
method updateAcks (line 2873) | func (o *consumer) updateAcks(dseq, sseq uint64, reply string) {
method addClusterPendingRequest (line 2898) | func (o *consumer) addClusterPendingRequest(reply string) {
method removeClusterPendingRequest (line 2910) | func (o *consumer) removeClusterPendingRequest(reply string) {
method setPendingRequestsOk (line 2921) | func (o *consumer) setPendingRequestsOk(ok bool) {
method pendingRequestsOk (line 2928) | func (o *consumer) pendingRequestsOk() bool {
method checkAndSetPendingRequestsOk (line 2934) | func (o *consumer) checkAndSetPendingRequestsOk() {
method checkPendingRequests (line 2959) | func (o *consumer) checkPendingRequests() {
method releaseAnyPendingRequests (line 2975) | func (o *consumer) releaseAnyPendingRequests(isAssigned bool) {
method processNak (line 2994) | func (o *consumer) processNak(sseq, dseq, dc uint64, nak []byte) {
method processTerm (line 3074) | func (o *consumer) processTerm(sseq, dseq, dc uint64, reason, reply st...
method ackWait (line 3107) | func (o *consumer) ackWait(next time.Duration) time.Duration {
method checkRedelivered (line 3116) | func (o *consumer) checkRedelivered() {
method readStoredState (line 3135) | func (o *consumer) readStoredState() error {
method applyState (line 3151) | func (o *consumer) applyState(state *ConsumerState) {
method setStoreState (line 3179) | func (o *consumer) setStoreState(state *ConsumerState) error {
method writeStoreState (line 3196) | func (o *consumer) writeStoreState() error {
method writeStoreStateUnlocked (line 3204) | func (o *consumer) writeStoreStateUnlocked() error {
method initialInfo (line 3225) | func (o *consumer) initialInfo() *ConsumerInfo {
method clearInitialInfo (line 3238) | func (o *consumer) clearInitialInfo() {
method info (line 3245) | func (o *consumer) info() *ConsumerInfo {
method infoWithSnap (line 3249) | func (o *consumer) infoWithSnap(snap bool) *ConsumerInfo {
method infoWithSnapAndReply (line 3253) | func (o *consumer) infoWithSnapAndReply(snap bool, reply string) *Cons...
method signalNewMessages (line 3379) | func (o *consumer) signalNewMessages() {
method shouldSample (line 3388) | func (o *consumer) shouldSample() bool {
method sampleAck (line 3401) | func (o *consumer) sampleAck(sseq, dseq, dc uint64) {
method processAckMsg (line 3431) | func (o *consumer) processAckMsg(sseq, dseq, dc uint64, reply string, ...
method isFiltered (line 3573) | func (o *consumer) isFiltered() bool {
method needAck (line 3620) | func (o *consumer) needAck(sseq uint64, subj string) bool {
method pendingRequests (line 4037) | func (o *consumer) pendingRequests() map[string]*waitingRequest {
method setPinnedTimer (line 4049) | func (o *consumer) setPinnedTimer(priorityGroup string) {
method assignNewPinId (line 4069) | func (o *consumer) assignNewPinId(wr *waitingRequest) {
method unassignPinId (line 4081) | func (o *consumer) unassignPinId() {
method nextWaiting (line 4093) | func (o *consumer) nextWaiting(sz int) *waitingRequest {
method processNextMsgReq (line 4268) | func (o *consumer) processNextMsgReq(_ *subscription, c *client, _ *Ac...
method processResetReq (line 4290) | func (o *consumer) processResetReq(_ *subscription, c *client, a *Acco...
method processNextMsgRequest (line 4325) | func (o *consumer) processNextMsgRequest(reply string, msg []byte) {
method deliveryCount (line 4488) | func (o *consumer) deliveryCount(seq uint64) uint64 {
method incDeliveryCount (line 4501) | func (o *consumer) incDeliveryCount(sseq uint64) uint64 {
method decDeliveryCount (line 4512) | func (o *consumer) decDeliveryCount(sseq uint64) {
method notifyDeliveryExceeded (line 4520) | func (o *consumer) notifyDeliveryExceeded(sseq, dc uint64) {
method isFilteredMatch (line 4539) | func (o *consumer) isFilteredMatch(subj string) bool {
method isEqualOrSubsetMatch (line 4564) | func (o *consumer) isEqualOrSubsetMatch(subj string) bool {
method getNextMsg (line 4589) | func (o *consumer) getNextMsg() (*jsPubMsg, uint64, error) {
method processWaiting (line 4694) | func (o *consumer) processWaiting(eos bool) (int, int, int, time.Time) {
method checkWaitingForInterest (line 4794) | func (o *consumer) checkWaitingForInterest() bool {
method hbTimer (line 4800) | func (o *consumer) hbTimer() (time.Duration, *time.Timer) {
method checkAckFloor (line 4811) | func (o *consumer) checkAckFloor() {
method processInboundAcks (line 4903) | func (o *consumer) processInboundAcks(qch chan struct{}) {
method processInboundNextMsgReqs (line 4951) | func (o *consumer) processInboundNextMsgReqs(qch chan struct{}) {
method suppressDeletion (line 4975) | func (o *consumer) suppressDeletion() {
method loopAndGatherMsgs (line 4997) | func (o *consumer) loopAndGatherMsgs(qch chan struct{}) {
method sendIdleHeartbeat (line 5271) | func (o *consumer) sendIdleHeartbeat(subj string) {
method ackReply (line 5283) | func (o *consumer) ackReply(sseq, dseq, dc uint64, ts int64, pending u...
method setMaxPendingBytes (line 5288) | func (o *consumer) setMaxPendingBytes(limit int) {
method checkNumPending (line 5301) | func (o *consumer) checkNumPending() (uint64, error) {
method numPending (line 5320) | func (o *consumer) numPending() uint64 {
method checkNumPendingOnEOF (line 5330) | func (o *consumer) checkNumPendingOnEOF() {
method streamNumPendingLocked (line 5343) | func (o *consumer) streamNumPendingLocked() (uint64, error) {
method streamNumPending (line 5352) | func (o *consumer) streamNumPending() (uint64, error) {
method calculateNumPending (line 5368) | func (o *consumer) calculateNumPending() (npc, npf uint64, err error) {
method deliverMsg (line 5413) | func (o *consumer) deliverMsg(dsubj, ackReply string, pmsg *jsPubMsg, ...
method replicateDeliveries (line 5477) | func (o *consumer) replicateDeliveries() bool {
method needFlowControl (line 5481) | func (o *consumer) needFlowControl(sz int) bool {
method processFlowControl (line 5497) | func (o *consumer) processFlowControl(_ *subscription, c *client, _ *A...
method fcReply (line 5525) | func (o *consumer) fcReply() string {
method sendFlowControl (line 5544) | func (o *consumer) sendFlowControl() {
method trackPending (line 5556) | func (o *consumer) trackPending(sseq, dseq uint64) {
method creditWaitingRequest (line 5590) | func (o *consumer) creditWaitingRequest(reply string) {
method didNotDeliver (line 5603) | func (o *consumer) didNotDeliver(seq uint64, subj string) {
method addToRedeliverQueue (line 5644) | func (o *consumer) addToRedeliverQueue(seqs ...uint64) {
method hasRedeliveries (line 5652) | func (o *consumer) hasRedeliveries() bool {
method getNextToRedeliver (line 5656) | func (o *consumer) getNextToRedeliver() uint64 {
method onRedeliverQueue (line 5674) | func (o *consumer) onRedeliverQueue(seq uint64) bool {
method removeFromRedeliverQueue (line 5680) | func (o *consumer) removeFromRedeliverQueue(seq uint64) bool {
method checkPending (line 5700) | func (o *consumer) checkPending() {
method seqFromReply (line 5819) | func (o *consumer) seqFromReply(reply string) uint64 {
method streamSeqFromReply (line 5825) | func (o *consumer) streamSeqFromReply(reply string) uint64 {
method nextSeq (line 5890) | func (o *consumer) nextSeq() uint64 {
method hasSkipListPending (line 5905) | func (o *consumer) hasSkipListPending() bool {
method reconcileStateWithStream (line 5913) | func (o *consumer) reconcileStateWithStream(streamLastSeq uint64) {
method selectStartingSeqNo (line 5971) | func (o *consumer) selectStartingSeqNo() error {
method isDurable (line 6092) | func (o *consumer) isDurable() bool {
method isPushMode (line 6097) | func (o *consumer) isPushMode() bool {
method isPullMode (line 6101) | func (o *consumer) isPullMode() bool {
method String (line 6106) | func (o *consumer) String() string {
method getStream (line 6122) | func (o *consumer) getStream() *stream {
method streamName (line 6129) | func (o *consumer) streamName() string {
method isActive (line 6140) | func (o *consumer) isActive() bool {
method hasNoLocalInterest (line 6148) | func (o *consumer) hasNoLocalInterest() bool {
method purge (line 6159) | func (o *consumer) purge(sseq uint64, slseq uint64, isWider bool) {
method stop (line 6254) | func (o *consumer) stop() error {
method deleteWithoutAdvisory (line 6258) | func (o *consumer) deleteWithoutAdvisory() error {
method delete (line 6263) | func (o *consumer) delete() error {
method isClosed (line 6268) | func (o *consumer) isClosed() bool {
method stopWithFlags (line 6274) | func (o *consumer) stopWithFlags(dflag, sdflag, doSignal, advisory boo...
method cleanupNoInterestMessages (line 6453) | func (o *consumer) cleanupNoInterestMessages(mset *stream, ignoreInter...
method switchToEphemeral (line 6529) | func (o *consumer) switchToEphemeral() {
method requestNextMsgSubject (line 6549) | func (o *consumer) requestNextMsgSubject() string {
method decStreamPending (line 6553) | func (o *consumer) decStreamPending(sseq uint64, subj string) {
method account (line 6578) | func (o *consumer) account() *Account {
method signalSubs (line 6587) | func (o *consumer) signalSubs() []string {
method processStreamSignal (line 6613) | func (o *consumer) processStreamSignal(seq uint64) {
method shouldStartMonitor (line 6665) | func (o *consumer) shouldStartMonitor() bool {
method clearMonitorRunning (line 6679) | func (o *consumer) clearMonitorRunning() {
method isMonitorRunning (line 6690) | func (o *consumer) isMonitorRunning() bool {
method checkStateForInterestStream (line 6701) | func (o *consumer) checkStateForInterestStream(ss *StreamState) error {
method resetPtmr (line 6811) | func (o *consumer) resetPtmr(delay time.Duration) {
method stopAndClearPtmr (line 6820) | func (o *consumer) stopAndClearPtmr() {
method resetPendingDeliveries (line 6825) | func (o *consumer) resetPendingDeliveries() {
type subjectFilter (line 529) | type subjectFilter struct
type subjectFilters (line 535) | type subjectFilters
method subjects (line 539) | func (s subjectFilters) subjects() []string {
type proposal (line 547) | type proposal struct
constant JsAckWaitDefault (line 554) | JsAckWaitDefault = 30 * time.Second
constant JsDeleteWaitTimeDefault (line 557) | JsDeleteWaitTimeDefault = 5 * time.Second
constant JsFlowControlMaxPending (line 559) | JsFlowControlMaxPending = 32 * 1024 * 1024
constant JsDefaultMaxAckPending (line 561) | JsDefaultMaxAckPending = 1000
constant JsDefaultPinnedTTL (line 564) | JsDefaultPinnedTTL = 2 * time.Minute
function setConsumerConfigDefaults (line 568) | func setConsumerConfigDefaults(config *ConsumerConfig, streamCfg *Stream...
function checkConsumerCfg (line 680) | func checkConsumerCfg(
method addConsumerWithAction (line 952) | func (mset *stream) addConsumerWithAction(config *ConsumerConfig, action...
method addConsumer (line 956) | func (mset *stream) addConsumer(config *ConsumerConfig) (*consumer, erro...
method addConsumerWithAssignment (line 960) | func (mset *stream) addConsumerWithAssignment(config *ConsumerConfig, on...
method hasGatewayInterest (line 1952) | func (s *Server) hasGatewayInterest(account, subject string) bool {
constant defaultConsumerNotActiveStartInterval (line 2010) | defaultConsumerNotActiveStartInterval = 30 * time.Second
constant defaultConsumerNotActiveMaxInterval (line 2011) | defaultConsumerNotActiveMaxInterval = 5 * time.Minute
method checkNewConsumerConfig (line 2318) | func (acc *Account) checkNewConsumerConfig(cfg, ncfg *ConsumerConfig) er...
function configsEqualSansDelivery (line 2550) | func configsEqualSansDelivery(a, b ConsumerConfig) bool {
type jsAckMsg (line 2563) | type jsAckMsg struct
method returnToPool (line 2587) | func (am *jsAckMsg) returnToPool() {
function newJSAckMsg (line 2572) | func newJSAckMsg(subj, reply string, hdr int, msg []byte) *jsAckMsg {
constant ackWaitDelay (line 3104) | ackWaitDelay = time.Millisecond
type PriorityGroup (line 3684) | type PriorityGroup struct
function nextReqFromMsg (line 3701) | func nextReqFromMsg(msg []byte) (time.Time, int, int, bool, time.Duratio...
type waitingRequest (line 3739) | type waitingRequest struct
method recycleIfDone (line 3763) | func (wr *waitingRequest) recycleIfDone() bool {
method recycle (line 3772) | func (wr *waitingRequest) recycle() {
type waitingDelivery (line 3780) | type waitingDelivery struct
method recycle (line 3794) | func (wd *waitingDelivery) recycle() {
type waitQueue (line 3802) | type waitQueue struct
method insertSorted (line 3820) | func (wq *waitQueue) insertSorted(wr *waitingRequest) {
method addPrioritized (line 3832) | func (wq *waitQueue) addPrioritized(wr *waitingRequest) error {
method add (line 3847) | func (wq *waitQueue) add(wr *waitingRequest) error {
method isFull (line 3870) | func (wq *waitQueue) isFull() bool {
method isEmpty (line 3877) | func (wq *waitQueue) isEmpty() bool {
method len (line 3884) | func (wq *waitQueue) len() int {
method peek (line 3892) | func (wq *waitQueue) peek() *waitingRequest {
method cycle (line 3899) | func (wq *waitQueue) cycle() {
method popOrPopAndRequeue (line 3909) | func (wq *waitQueue) popOrPopAndRequeue(priority PriorityPolicy) *wait...
method pop (line 3922) | func (wq *waitQueue) pop() *waitingRequest {
method popAndRequeue (line 3941) | func (wq *waitQueue) popAndRequeue() *waitingRequest {
method removeCurrent (line 4008) | func (wq *waitQueue) removeCurrent() {
method remove (line 4013) | func (wq *waitQueue) remove(pre, wr *waitingRequest) {
function newWaitQueue (line 3810) | func newWaitQueue(max int) *waitQueue {
function insertAtPosition (line 3974) | func insertAtPosition(wr *waitingRequest, wq *waitQueue) {
type nextMsgReq (line 4235) | type nextMsgReq struct
method returnToPool (line 4257) | func (nmr *nextMsgReq) returnToPool() {
function newNextMsgReq (line 4242) | func newNextMsgReq(reply string, msg []byte) *nextMsgReq {
function trackDownAccountAndInterest (line 4468) | func trackDownAccountAndInterest(acc *Account, interest string) (*Accoun...
function convertToHeadersOnly (line 5385) | func convertToHeadersOnly(pmsg *jsPubMsg) {
function parseAckReplyNum (line 5831) | func parseAckReplyNum(d string) (n int64) {
constant expectedNumReplyTokens (line 5844) | expectedNumReplyTokens = 9
function replyInfo (line 5847) | func replyInfo(subject string) (sseq, dseq, dc uint64, ts int64, pending...
function ackReplyInfo (line 5870) | func ackReplyInfo(subject string) (sseq, dseq, dc uint64) {
type lastSeqSkipList (line 5898) | type lastSeqSkipList struct
function isDurableConsumer (line 6088) | func isDurableConsumer(config *ConsumerConfig) bool {
function createConsumerName (line 6113) | func createConsumerName() string {
method deleteConsumer (line 6118) | func (mset *stream) deleteConsumer(o *consumer) error {
function stopAndClearTimer (line 6243) | func stopAndClearTimer(tp **time.Timer) {
function deliveryFormsCycle (line 6519) | func deliveryFormsCycle(cfg *StreamConfig, deliverySubject string) bool {
function subjectSliceEqual (line 6636) | func subjectSliceEqual(slice1 []string, slice2 []string) bool {
function gatherSubjectFilters (line 6655) | func gatherSubjectFilters(filter string, filters []string) []string {
FILE: server/core_benchmarks_test.go
function BenchmarkCoreRequestReply (line 32) | func BenchmarkCoreRequestReply(b *testing.B) {
function BenchmarkCoreTLSFanOut (line 101) | func BenchmarkCoreTLSFanOut(b *testing.B) {
function BenchmarkCoreFanOut (line 260) | func BenchmarkCoreFanOut(b *testing.B) {
function BenchmarkCoreFanIn (line 397) | func BenchmarkCoreFanIn(b *testing.B) {
function fastRandomMutation (line 610) | func fastRandomMutation(data []byte, mutations int) {
FILE: server/cron.go
function parseCron (line 49) | func parseCron(pattern string, tz string, ts int64) (time.Time, error) {
function getField (line 155) | func getField(field string, r bounds) (uint64, error) {
function getRange (line 170) | func getRange(expr string, r bounds) (uint64, error) {
function parseIntOrName (line 237) | func parseIntOrName(expr string, names map[string]uint) (uint, error) {
function mustParseInt (line 247) | func mustParseInt(expr string) (uint, error) {
function getBits (line 259) | func getBits(min, max, step uint) uint64 {
type bounds (line 275) | type bounds struct
constant starBit (line 313) | starBit = 1 << 63
function dayMatches (line 318) | func dayMatches(dayOfMonth, dayOfWeek uint64, t time.Time) bool {
FILE: server/dirstore.go
constant fileExtension (line 36) | fileExtension = ".jwt"
function validatePathExists (line 40) | func validatePathExists(path string, dir bool) (string, error) {
function validateDirPath (line 68) | func validateDirPath(path string) (string, error) {
type JWTChanged (line 73) | type JWTChanged
type DirJWTStore (line 77) | type DirJWTStore struct
method IsReadOnly (line 193) | func (store *DirJWTStore) IsReadOnly() bool {
method LoadAcc (line 197) | func (store *DirJWTStore) LoadAcc(publicKey string) (string, error) {
method SaveAcc (line 201) | func (store *DirJWTStore) SaveAcc(publicKey string, theJWT string) err...
method LoadAct (line 205) | func (store *DirJWTStore) LoadAct(hash string) (string, error) {
method SaveAct (line 209) | func (store *DirJWTStore) SaveAct(hash string, theJWT string) error {
method Close (line 213) | func (store *DirJWTStore) Close() {
method Pack (line 223) | func (store *DirJWTStore) Pack(maxJWTs int) (string, error) {
method PackWalk (line 267) | func (store *DirJWTStore) PackWalk(maxJWTs int, cb func(partialPackMsg...
method Merge (line 318) | func (store *DirJWTStore) Merge(pack string) error {
method Reload (line 339) | func (store *DirJWTStore) Reload() error {
method pathForKey (line 377) | func (store *DirJWTStore) pathForKey(publicKey string) string {
method load (line 395) | func (store *DirJWTStore) load(publicKey string) (string, error) {
method write (line 412) | func (store *DirJWTStore) write(path string, publicKey string, theJWT ...
method delete (line 449) | func (store *DirJWTStore) delete(publicKey string) error {
method save (line 478) | func (store *DirJWTStore) save(publicKey string, theJWT string) error {
method saveIfNewer (line 506) | func (store *DirJWTStore) saveIfNewer(publicKey string, theJWT string)...
method Hash (line 556) | func (store *DirJWTStore) Hash() [sha256.Size]byte {
method startExpiring (line 680) | func (store *DirJWTStore) startExpiring(reCheck time.Duration, limit i...
function newDir (line 89) | func newDir(dirPath string, create bool) (string, error) {
type dirJWTStoreOption (line 106) | type dirJWTStoreOption
function NewImmutableDirJWTStore (line 110) | func NewImmutableDirJWTStore(dirPath string, shard bool, _ ...dirJWTStor...
function NewDirJWTStore (line 121) | func NewDirJWTStore(dirPath string, shard bool, create bool, _ ...dirJWT...
type deleteType (line 133) | type deleteType
constant NoDelete (line 136) | NoDelete deleteType = iota
constant RenameDeleted (line 137) | RenameDeleted
constant HardDelete (line 138) | HardDelete
function NewExpiringDirJWTStore (line 150) | func NewExpiringDirJWTStore(dirPath string, shard bool, create bool, del...
function xorAssign (line 549) | func xorAssign(lVal *[sha256.Size]byte, rVal [sha256.Size]byte) {
type jwtItem (line 567) | type jwtItem struct
type expirationTracker (line 575) | type expirationTracker struct
method Len (line 587) | func (q *expirationTracker) Len() int { return len(q.heap) }
method Less (line 589) | func (q *expirationTracker) Less(i, j int) bool {
method Swap (line 594) | func (q *expirationTracker) Swap(i, j int) {
method Push (line 601) | func (q *expirationTracker) Push(x any) {
method Pop (line 609) | func (q *expirationTracker) Pop() any {
method updateTrack (line 621) | func (pq *expirationTracker) updateTrack(publicKey string) {
method unTrack (line 635) | func (pq *expirationTracker) unTrack(publicKey string) {
method track (line 643) | func (pq *expirationTracker) track(publicKey string, hash *[sha256.Siz...
method close (line 672) | func (pq *expirationTracker) close() {
FILE: server/dirstore_test.go
function init (line 38) | func init() {
function TestShardedDirStoreWriteAndReadonly (line 66) | func TestShardedDirStoreWriteAndReadonly(t *testing.T) {
function TestUnshardedDirStoreWriteAndReadonly (line 119) | func TestUnshardedDirStoreWriteAndReadonly(t *testing.T) {
function TestNoCreateRequiresDir (line 174) | func TestNoCreateRequiresDir(t *testing.T) {
function TestCreateMakesDir (line 180) | func TestCreateMakesDir(t *testing.T) {
function TestShardedDirStorePackMerge (line 198) | func TestShardedDirStorePackMerge(t *testing.T) {
function TestShardedToUnsharedDirStorePackMerge (line 273) | func TestShardedToUnsharedDirStorePackMerge(t *testing.T) {
function TestMergeOnlyOnNewer (line 332) | func TestMergeOnlyOnNewer(t *testing.T) {
function createTestAccount (line 378) | func createTestAccount(t *testing.T, dirStore *DirJWTStore, expSec int, ...
function assertStoreSize (line 393) | func assertStoreSize(t *testing.T, dirStore *DirJWTStore, length int) {
function TestExpiration (line 405) | func TestExpiration(t *testing.T) {
function TestLimit (line 442) | func TestLimit(t *testing.T) {
function TestLimitNoEvict (line 484) | func TestLimitNoEvict(t *testing.T) {
function TestLruLoad (line 536) | func TestLruLoad(t *testing.T) {
function TestLruVolume (line 568) | func TestLruVolume(t *testing.T) {
function TestLru (line 610) | func TestLru(t *testing.T) {
function TestReload (line 659) | func TestReload(t *testing.T) {
function TestExpirationUpdate (line 720) | func TestExpirationUpdate(t *testing.T) {
function TestTTL (line 777) | func TestTTL(t *testing.T) {
function TestRemove (line 831) | func TestRemove(t *testing.T) {
constant infDur (line 879) | infDur = time.Duration(math.MaxInt64)
function TestNotificationOnPack (line 881) | func TestNotificationOnPack(t *testing.T) {
function TestNotificationOnPackWalk (line 944) | func TestNotificationOnPackWalk(t *testing.T) {
FILE: server/disk_avail.go
function diskAvailable (line 23) | func diskAvailable(storeDir string) int64 {
FILE: server/disk_avail_netbsd.go
function diskAvailable (line 19) | func diskAvailable(storeDir string) int64 {
FILE: server/disk_avail_openbsd.go
function diskAvailable (line 23) | func diskAvailable(storeDir string) int64 {
FILE: server/disk_avail_solaris.go
function diskAvailable (line 23) | func diskAvailable(storeDir string) int64 {
FILE: server/disk_avail_wasm.go
function diskAvailable (line 18) | func diskAvailable(storeDir string) int64 {
FILE: server/disk_avail_windows.go
function diskAvailable (line 19) | func diskAvailable(storeDir string) int64 {
FILE: server/elastic/elastic.go
function Make (line 20) | func Make[T any](ptr *T) *Pointer[T] {
type Pointer (line 26) | type Pointer struct
method Set (line 31) | func (e *Pointer[T]) Set(ptr *T) {
method Strengthen (line 38) | func (e *Pointer[T]) Strengthen() {
method Weaken (line 45) | func (e *Pointer[T]) Weaken() {
method Value (line 52) | func (e *Pointer[T]) Value() *T {
FILE: server/errors.go
type mappingDestinationErr (line 251) | type mappingDestinationErr struct
method Error (line 256) | func (e *mappingDestinationErr) Error() string {
method Is (line 263) | func (e *mappingDestinationErr) Is(target error) bool {
type configErr (line 268) | type configErr struct
method Source (line 274) | func (e *configErr) Source() string {
method Error (line 279) | func (e *configErr) Error() string {
type unknownConfigFieldErr (line 287) | type unknownConfigFieldErr struct
method Error (line 293) | func (e *unknownConfigFieldErr) Error() string {
type configWarningErr (line 298) | type configWarningErr struct
method Error (line 304) | func (e *configWarningErr) Error() string {
type processConfigErr (line 309) | type processConfigErr struct
method Error (line 316) | func (e *processConfigErr) Error() string {
method Warnings (line 328) | func (e *processConfigErr) Warnings() []error {
method Errors (line 333) | func (e *processConfigErr) Errors() []error {
type errCtx (line 339) | type errCtx struct
method Unwrap (line 349) | func (e *errCtx) Unwrap() error {
method Context (line 357) | func (e *errCtx) Context() string {
function NewErrorCtx (line 344) | func NewErrorCtx(err error, format string, args ...any) error {
function UnpackIfErrorCtx (line 365) | func UnpackIfErrorCtx(err error) string {
function errorsUnwrap (line 377) | func errorsUnwrap(err error) error {
function ErrorIs (line 389) | func ErrorIs(err, target error) bool {
FILE: server/errors_gen.go
function panicIfErr (line 76) | func panicIfErr(err error) {
function goFmt (line 83) | func goFmt(file string) error {
function checkIncrements (line 93) | func checkIncrements(errs []server.ErrorsData) error {
function checkDupes (line 115) | func checkDupes(errs []server.ErrorsData) error {
function findTags (line 144) | func findTags(d string) []string {
function main (line 159) | func main() {
FILE: server/errors_test.go
function TestErrCtx (line 21) | func TestErrCtx(t *testing.T) {
function TestErrCtxWrapped (line 46) | func TestErrCtxWrapped(t *testing.T) {
FILE: server/events.go
constant accLookupReqTokens (line 42) | accLookupReqTokens = 6
constant accLookupReqSubj (line 43) | accLookupReqSubj = "$SYS.REQ.ACCOUNT.%s.CLAIMS.LOOKUP"
constant accPackReqSubj (line 44) | accPackReqSubj = "$SYS.REQ.CLAIMS.PACK"
constant accListReqSubj (line 45) | accListReqSubj = "$SYS.REQ.CLAIMS.LIST"
constant accClaimsReqSubj (line 46) | accClaimsReqSubj = "$SYS.REQ.CLAIMS.UPDATE"
constant accDeleteReqSubj (line 47) | accDeleteReqSubj = "$SYS.REQ.CLAIMS.DELETE"
constant connectEventSubj (line 49) | connectEventSubj = "$SYS.ACCOUNT.%s.CONNECT"
constant disconnectEventSubj (line 50) | disconnectEventSubj = "$SYS.ACCOUNT.%s.DISCONNECT"
constant accDirectReqSubj (line 51) | accDirectReqSubj = "$SYS.REQ.ACCOUNT.%s.%s"
constant accPingReqSubj (line 52) | accPingReqSubj = "$SYS.REQ.ACCOUNT.PING.%s"
constant accUpdateEventSubjOld (line 55) | accUpdateEventSubjOld = "$SYS.ACCOUNT.%s.CLAIMS.UPDATE"
constant accUpdateEventSubjNew (line 56) | accUpdateEventSubjNew = "$SYS.REQ.ACCOUNT.%s.CLAIMS.UPDATE"
constant connsRespSubj (line 57) | connsRespSubj = "$SYS._INBOX_.%s"
constant accConnsEventSubjNew (line 58) | accConnsEventSubjNew = "$SYS.ACCOUNT.%s.SERVER.CONNS"
constant accConnsEventSubjOld (line 59) | accConnsEventSubjOld = "$SYS.SERVER.ACCOUNT.%s.CONNS"
constant lameDuckEventSubj (line 60) | lameDuckEventSubj = "$SYS.SERVER.%s.LAMEDUCK"
constant shutdownEventSubj (line 61) | shutdownEventSubj = "$SYS.SERVER.%s.SHUTDOWN"
constant clientKickReqSubj (line 62) | clientKickReqSubj = "$SYS.REQ.SERVER.%s.KICK"
constant clientLDMReqSubj (line 63) | clientLDMReqSubj = "$SYS.REQ.SERVER.%s.LDM"
constant authErrorEventSubj (line 64) | authErrorEventSubj = "$SYS.SERVER.%s.CLIENT.AUTH.ERR"
constant authErrorAccountEventSubj (line 65) | authErrorAccountEventSubj = "$SYS.ACCOUNT.CLIENT.AUTH.ERR"
constant serverStatsSubj (line 66) | serverStatsSubj = "$SYS.SERVER.%s.STATSZ"
constant serverDirectReqSubj (line 67) | serverDirectReqSubj = "$SYS.REQ.SERVER.%s.%s"
constant serverPingReqSubj (line 68) | serverPingReqSubj = "$SYS.REQ.SERVER.PING.%s"
constant serverStatsPingReqSubj (line 69) | serverStatsPingReqSubj = "$SYS.REQ.SERVER.PING"
constant serverReloadReqSubj (line 70) | serverReloadReqSubj = "$SYS.REQ.SERVER.%s.RELOAD"
constant leafNodeConnectEventSubj (line 71) | leafNodeConnectEventSubj = "$SYS.ACCOUNT.%s.LEAFNODE.CONNECT"
constant remoteLatencyEventSubj (line 72) | remoteLatencyEventSubj = "$SYS.LATENCY.M2.%s"
constant inboxRespSubj (line 73) | inboxRespSubj = "$SYS._INBOX.%s.%s"
constant userDirectInfoSubj (line 76) | userDirectInfoSubj = "$SYS.REQ.USER.INFO"
constant userDirectReqSubj (line 77) | userDirectReqSubj = "$SYS.REQ.USER.%s.INFO"
constant accNumSubsReqSubj (line 81) | accNumSubsReqSubj = "$SYS.REQ.ACCOUNT.NSUBS"
constant accSubsSubj (line 84) | accSubsSubj = "$SYS.DEBUG.SUBSCRIBERS"
constant shutdownEventTokens (line 86) | shutdownEventTokens = 4
constant serverSubjectIndex (line 87) | serverSubjectIndex = 2
constant accUpdateTokensNew (line 88) | accUpdateTokensNew = 6
constant accUpdateTokensOld (line 89) | accUpdateTokensOld = 5
constant accUpdateAccIdxOld (line 90) | accUpdateAccIdxOld = 2
constant accReqTokens (line 92) | accReqTokens = 5
constant accReqAccIndex (line 93) | accReqAccIndex = 3
constant ocspPeerRejectEventSubj (line 95) | ocspPeerRejectEventSubj = "$SYS.SERVER.%s.OCSP.PEER.CONN.REJECT"
constant ocspPeerChainlinkInvalidEventSubj (line 96) | ocspPeerChainlinkInvalidEventSubj = "$SYS.SERVER.%s.OCSP.PEER.LINK.INVALID"
constant defaultStatszRateLimit (line 104) | defaultStatszRateLimit = 1 * time.Second
type sysMsgHandler (line 109) | type sysMsgHandler
type inSysMsg (line 112) | type inSysMsg struct
type internal (line 124) | type internal struct
type ServerStatsMsg (line 150) | type ServerStatsMsg struct
type ConnectEventMsg (line 156) | type ConnectEventMsg struct
constant ConnectEventMsgType (line 163) | ConnectEventMsgType = "io.nats.server.advisory.v1.client_connect"
type DisconnectEventMsg (line 167) | type DisconnectEventMsg struct
constant DisconnectEventMsgType (line 177) | DisconnectEventMsgType = "io.nats.server.advisory.v1.client_disconnect"
type OCSPPeerRejectEventMsg (line 182) | type OCSPPeerRejectEventMsg struct
constant OCSPPeerRejectEventMsgType (line 191) | OCSPPeerRejectEventMsgType = "io.nats.server.advisory.v1.ocsp_peer_reject"
type OCSPPeerChainlinkInvalidEventMsg (line 196) | type OCSPPeerChainlinkInvalidEventMsg struct
constant OCSPPeerChainlinkInvalidEventMsgType (line 205) | OCSPPeerChainlinkInvalidEventMsgType = "io.nats.server.advisory.v1.ocsp_...
type AccountNumConns (line 210) | type AccountNumConns struct
type AccountStat (line 217) | type AccountStat struct
constant AccountNumConnsMsgType (line 229) | AccountNumConnsMsgType = "io.nats.server.advisory.v1.account_connections"
type accNumConnsReq (line 233) | type accNumConnsReq struct
type ServerID (line 239) | type ServerID struct
type ServerCapability (line 246) | type ServerCapability
type ServerInfo (line 249) | type ServerInfo struct
method SetJetStreamEnabled (line 274) | func (si *ServerInfo) SetJetStreamEnabled() {
method JetStreamEnabled (line 281) | func (si *ServerInfo) JetStreamEnabled() bool {
method SetBinaryStreamSnapshot (line 287) | func (si *ServerInfo) SetBinaryStreamSnapshot() {
method BinaryStreamSnapshot (line 292) | func (si *ServerInfo) BinaryStreamSnapshot() bool {
method SetAccountNRG (line 297) | func (si *ServerInfo) SetAccountNRG() {
method AccountNRG (line 303) | func (si *ServerInfo) AccountNRG() bool {
constant JetStreamEnabled (line 268) | JetStreamEnabled ServerCapability = 1 << iota
constant BinaryStreamSnapshot (line 269) | BinaryStreamSnapshot
constant AccountNRG (line 270) | AccountNRG
type ClientInfo (line 308) | type ClientInfo struct
method forAssignmentSnap (line 335) | func (ci *ClientInfo) forAssignmentSnap() *ClientInfo {
method forProposal (line 344) | func (ci *ClientInfo) forProposal() *ClientInfo {
method forAdvisory (line 355) | func (ci *ClientInfo) forAdvisory() *ClientInfo {
type ServerStats (line 366) | type ServerStats struct
type RouteStat (line 391) | type RouteStat struct
type GatewayStat (line 400) | type GatewayStat struct
type MsgBytes (line 408) | type MsgBytes struct
type DataStats (line 414) | type DataStats struct
type pubMsg (line 422) | type pubMsg struct
method returnToPool (line 453) | func (pm *pubMsg) returnToPool() {
function newPubMsg (line 436) | func newPubMsg(c *client, sub, rply string, si *ServerInfo, hdr []byte,
type serverUpdate (line 462) | type serverUpdate struct
type TypedEvent (line 469) | type TypedEvent struct
method internalReceiveLoop (line 477) | func (s *Server) internalReceiveLoop(recvq *ipQueue[*inSysMsg]) {
method internalSendLoop (line 496) | func (s *Server) internalSendLoop(wg *sync.WaitGroup) {
method sendLDMShutdownEventLocked (line 675) | func (s *Server) sendLDMShutdownEventLocked() {
method sendShutdownEvent (line 685) | func (s *Server) sendShutdownEvent() {
method sendInternalAccountMsg (line 704) | func (s *Server) sendInternalAccountMsg(a *Account, subject string, msg ...
method sendInternalAccountMsgWithReply (line 709) | func (s *Server) sendInternalAccountMsgWithReply(a *Account, subject, re...
method sendInternalAccountSysMsg (line 733) | func (s *Server) sendInternalAccountSysMsg(a *Account, subj string, si *...
method sendInternalMsgLocked (line 751) | func (s *Server) sendInternalMsgLocked(subj, rply string, si *ServerInfo...
method sendInternalMsg (line 759) | func (s *Server) sendInternalMsg(subj, rply string, si *ServerInfo, msg ...
method sendInternalResponse (line 767) | func (s *Server) sendInternalResponse(subj string, response *ServerAPIRe...
method sendInternalMsg (line 778) | func (c *client) sendInternalMsg(subj, rply string, si *ServerInfo, msg ...
method eventsRunning (line 796) | func (s *Server) eventsRunning() bool {
method EventsEnabled (line 808) | func (s *Server) EventsEnabled() bool {
method eventsEnabled (line 816) | func (s *Server) eventsEnabled() bool {
method TrackedRemoteServers (line 822) | func (s *Server) TrackedRemoteServers() int {
method checkRemoteServers (line 833) | func (s *Server) checkRemoteServers() {
method updateServerUsage (line 849) | func (s *Server) updateServerUsage(v *ServerStats) {
function routeStat (line 860) | func routeStat(r *client) *RouteStat {
method sendStatsz (line 892) | func (s *Server) sendStatsz(subj string) {
method limitStatsz (line 1076) | func (s *Server) limitStatsz(subj string) bool {
method heartbeatStatsz (line 1106) | func (s *Server) heartbeatStatsz() {
method resetLastStatsz (line 1123) | func (s *Server) resetLastStatsz() {
method sendStatszUpdate (line 1127) | func (s *Server) sendStatszUpdate() {
method startStatszTimer (line 1132) | func (s *Server) startStatszTimer() {
method startRemoteServerSweepTimer (line 1141) | func (s *Server) startRemoteServerSweepTimer() {
constant sysHashLen (line 1146) | sysHashLen = 8
function getHash (line 1149) | func getHash(name string) string {
function getHashSize (line 1154) | func getHashSize(name string, size int) string {
method Node (line 1165) | func (s *Server) Node() string {
method initEventTracking (line 1180) | func (s *Server) initEventTracking() {
type UserInfo (line 1508) | type UserInfo struct
method userInfoReq (line 1518) | func (s *Server) userInfoReq(sub *subscription, c *client, _ *Account, s...
method registerSystemImportsForExisting (line 1555) | func (s *Server) registerSystemImportsForExisting() {
method addSystemAccountExports (line 1579) | func (s *Server) addSystemAccountExports(sacc *Account) {
method accountClaimUpdate (line 1631) | func (s *Server) accountClaimUpdate(sub *subscription, c *client, _ *Acc...
method processRemoteServerShutdown (line 1665) | func (s *Server) processRemoteServerShutdown(sid string) {
method sameDomain (line 1683) | func (s *Server) sameDomain(domain string) bool {
method remoteServerShutdown (line 1688) | func (s *Server) remoteServerShutdown(sub *subscription, c *client, _ *A...
method remoteServerUpdate (line 1727) | func (s *Server) remoteServerUpdate(sub *subscription, c *client, _ *Acc...
method updateRemoteServer (line 1786) | func (s *Server) updateRemoteServer(si *ServerInfo) {
method processNewServer (line 1804) | func (s *Server) processNewServer(si *ServerInfo) {
method updateNRGAccountStatus (line 1839) | func (s *Server) updateNRGAccountStatus() {
method ensureGWsInterestOnlyForLeafNodes (line 1861) | func (s *Server) ensureGWsInterestOnlyForLeafNodes() {
method shutdownEventing (line 1875) | func (s *Server) shutdownEventing() {
method connsRequest (line 1909) | func (s *Server) connsRequest(sub *subscription, c *client, _ *Account, ...
method leafNodeConnected (line 1948) | func (s *Server) leafNodeConnected(sub *subscription, _ *client, _ *Acco...
type EventFilterOptions (line 1969) | type EventFilterOptions struct
type StatszEventOptions (line 1979) | type StatszEventOptions struct
type AccInfoEventOptions (line 1985) | type AccInfoEventOptions struct
type ConnzEventOptions (line 1991) | type ConnzEventOptions struct
type RoutezEventOptions (line 1997) | type RoutezEventOptions struct
type SubszEventOptions (line 2003) | type SubszEventOptions struct
type VarzEventOptions (line 2009) | type VarzEventOptions struct
type GatewayzEventOptions (line 2015) | type GatewayzEventOptions struct
type LeafzEventOptions (line 2021) | type LeafzEventOptions struct
type AccountzEventOptions (line 2027) | type AccountzEventOptions struct
type AccountStatzEventOptions (line 2033) | type AccountStatzEventOptions struct
type JszEventOptions (line 2039) | type JszEventOptions struct
type HealthzEventOptions (line 2045) | type HealthzEventOptions struct
type ProfilezEventOptions (line 2051) | type ProfilezEventOptions struct
type ExpvarzEventOptions (line 2057) | type ExpvarzEventOptions struct
type IpqueueszEventOptions (line 2062) | type IpqueueszEventOptions struct
type RaftzEventOptions (line 2068) | type RaftzEventOptions struct
method filterRequest (line 2075) | func (s *Server) filterRequest(fOpts *EventFilterOptions) bool {
type compressionType (line 2105) | type compressionType
constant noCompression (line 2108) | noCompression = compressionType(iota)
constant gzipCompression (line 2109) | gzipCompression
constant snappyCompression (line 2110) | snappyCompression
constant unsupportedCompression (line 2111) | unsupportedCompression
type ServerAPIResponse (line 2115) | type ServerAPIResponse struct
type ServerAPIConnzResponse (line 2129) | type ServerAPIConnzResponse struct
type ServerAPIRoutezResponse (line 2136) | type ServerAPIRoutezResponse struct
type ServerAPIGatewayzResponse (line 2143) | type ServerAPIGatewayzResponse struct
type ServerAPIJszResponse (line 2150) | type ServerAPIJszResponse struct
type ServerAPIHealthzResponse (line 2157) | type ServerAPIHealthzResponse struct
type ServerAPIVarzResponse (line 2164) | type ServerAPIVarzResponse struct
type ServerAPISubszResponse (line 2171) | type ServerAPISubszResponse struct
type ServerAPILeafzResponse (line 2178) | type ServerAPILeafzResponse struct
type ServerAPIAccountzResponse (line 2185) | type ServerAPIAccountzResponse struct
type ServerAPIExpvarzResponse (line 2192) | type ServerAPIExpvarzResponse struct
type ServerAPIpqueueszResponse (line 2199) | type ServerAPIpqueueszResponse struct
type ServerAPIRaftzResponse (line 2206) | type ServerAPIRaftzResponse struct
method statszReq (line 2213) | func (s *Server) statszReq(sub *subscription, c *client, _ *Account, sub...
method idzReq (line 2242) | func (s *Server) idzReq(sub *subscription, c *client, _ *Account, subjec...
constant acceptEncodingHeader (line 2256) | acceptEncodingHeader = "Accept-Encoding"
constant contentEncodingHeader (line 2257) | contentEncodingHeader = "Content-Encoding"
function getAcceptEncoding (line 2261) | func getAcceptEncoding(hdr []byte) compressionType {
method zReq (line 2275) | func (s *Server) zReq(_ *client, reply string, hdr, msg []byte, fOpts *E...
method remoteConnsUpdate (line 2306) | func (s *Server) remoteConnsUpdate(sub *subscription, c *client, _ *Acco...
method registerSystemImports (line 2354) | func (s *Server) registerSystemImports(a *Account) {
method enableAccountTracking (line 2389) | func (s *Server) enableAccountTracking(a *Account) {
method sendLeafNodeConnect (line 2406) | func (s *Server) sendLeafNodeConnect(a *Account) {
method sendLeafNodeConnectMsg (line 2421) | func (s *Server) sendLeafNodeConnectMsg(accName string) {
method sendAccConnsUpdate (line 2430) | func (s *Server) sendAccConnsUpdate(a *Account, subj ...string) {
method statz (line 2469) | func (a *Account) statz() *AccountStat {
method accConnsUpdate (line 2529) | func (s *Server) accConnsUpdate(a *Account) {
method nextEventID (line 2539) | func (s *Server) nextEventID() string {
method accountConnectEvent (line 2545) | func (s *Server) accountConnectEvent(c *client) {
method accountDisconnectEvent (line 2592) | func (s *Server) accountDisconnectEvent(c *client, now time.Time, reason...
method sendAuthErrorEvent (line 2654) | func (s *Server) sendAuthErrorEvent(c *client, reason string) {
method sendAccountAuthErrorEvent (line 2713) | func (s *Server) sendAccountAuthErrorEvent(c *client, acc *Account, reas...
type msgHandler (line 2774) | type msgHandler
constant recvQMuxed (line 2777) | recvQMuxed = 1
constant recvQStatsz (line 2778) | recvQStatsz = 2
method noInlineCallback (line 2783) | func (s *Server) noInlineCallback(cb sysMsgHandler) msgHandler {
method noInlineCallbackStatsz (line 2789) | func (s *Server) noInlineCallbackStatsz(cb sysMsgHandler) msgHandler {
method noInlineCallbackRecvQSelect (line 2795) | func (s *Server) noInlineCallbackRecvQSelect(cb sysMsgHandler, recvQSele...
method sysSubscribe (line 2819) | func (s *Server) sysSubscribe(subject string, cb msgHandler) (*subscript...
method sysSubscribeQ (line 2824) | func (s *Server) sysSubscribeQ(subject, queue string, cb msgHandler) (*s...
method sysSubscribeInternal (line 2829) | func (s *Server) sysSubscribeInternal(subject string, cb msgHandler) (*s...
method systemSubscribe (line 2833) | func (s *Server) systemSubscribe(subject, queue string, internalOnly boo...
method sysUnsubscribe (line 2865) | func (s *Server) sysUnsubscribe(sub *subscription) {
function remoteLatencySubjectForResponse (line 2883) | func remoteLatencySubjectForResponse(subject []byte) string {
method remoteLatencyUpdate (line 2893) | func (s *Server) remoteLatencyUpdate(sub *subscription, _ *client, _ *Ac...
method inboxReply (line 2951) | func (s *Server) inboxReply(sub *subscription, c *client, acc *Account, ...
constant InboxPrefix (line 2969) | InboxPrefix = "$SYS._INBOX."
constant inboxPrefixLen (line 2970) | inboxPrefixLen = len(InboxPrefix)
constant respInboxPrefixLen (line 2971) | respInboxPrefixLen = inboxPrefixLen + sysHashLen + 1
constant replySuffixLen (line 2972) | replySuffixLen = 8
method newRespInbox (line 2976) | func (s *Server) newRespInbox() string {
type accNumSubsReq (line 2989) | type accNumSubsReq struct
function totalSubs (line 2996) | func totalSubs(rr *SublistResult, qg []byte) (nsubs int32) {
method debugSubscribers (line 3024) | func (s *Server) debugSubscribers(sub *subscription, c *client, _ *Accou...
method nsubsRequest (line 3152) | func (s *Server) nsubsRequest(sub *subscription, c *client, _ *Account, ...
method reloadConfig (line 3191) | func (s *Server) reloadConfig(sub *subscription, c *client, _ *Account, ...
type KickClientReq (line 3203) | type KickClientReq struct
type LDMClientReq (line 3207) | type LDMClientReq struct
method kickClient (line 3211) | func (s *Server) kickClient(_ *subscription, c *client, _ *Account, subj...
method ldmClient (line 3229) | func (s *Server) ldmClient(_ *subscription, c *client, _ *Account, subje...
function accForClient (line 3247) | func accForClient(c *client) string {
function issuerForClient (line 3255) | func issuerForClient(c *client) (issuerKey string) {
function clearTimer (line 3267) | func clearTimer(tp **time.Timer) {
method wrapChk (line 3276) | func (s *Server) wrapChk(f func()) func() {
method sendOCSPPeerRejectEvent (line 3290) | func (s *Server) sendOCSPPeerRejectEvent(kind string, peer *x509.Certifi...
method sendOCSPPeerChainlinkInvalidEvent (line 3323) | func (s *Server) sendOCSPPeerChainlinkInvalidEvent(peer *x509.Certificat...
FILE: server/events_test.go
function createAccount (line 41) | func createAccount(s *Server) (*Account, nkeys.KeyPair) {
function createUserCredsEx (line 55) | func createUserCredsEx(t *testing.T, nuc *jwt.UserClaims, akp nkeys.KeyP...
function createUserCreds (line 73) | func createUserCreds(t *testing.T, _ *Server, akp nkeys.KeyPair) nats.Op...
function runTrustedServer (line 77) | func runTrustedServer(t *testing.T) (*Server, *Options) {
function runTrustedCluster (line 88) | func runTrustedCluster(t *testing.T) (*Server, *Options, *Server, *Optio...
function runTrustedGateways (line 132) | func runTrustedGateways(t *testing.T) (*Server, *Options, *Server, *Opti...
function TestSystemAccount (line 176) | func TestSystemAccount(t *testing.T) {
function TestSystemAccountNewConnection (line 200) | func TestSystemAccountNewConnection(t *testing.T) {
function runTrustedLeafServer (line 383) | func runTrustedLeafServer(t *testing.T) (*Server, *Options) {
function genCredsFile (line 395) | func genCredsFile(t *testing.T, jwt string, seed []byte) string {
function runSolicitWithCredentials (line 414) | func runSolicitWithCredentials(t *testing.T, opts *Options, creds string...
function checkLeafNodeConnected (line 433) | func checkLeafNodeConnected(t testing.TB, s *Server) {
function checkLeafNodeConnectedCount (line 439) | func checkLeafNodeConnectedCount(t testing.TB, s *Server, lnCons int) {
function TestSystemAccountingWithLeafNodes (line 450) | func TestSystemAccountingWithLeafNodes(t *testing.T) {
function TestSystemAccountDisconnectBadLogin (line 572) | func TestSystemAccountDisconnectBadLogin(t *testing.T) {
function TestSysSubscribeRace (line 607) | func TestSysSubscribeRace(t *testing.T) {
function TestSystemAccountInternalSubscriptions (line 661) | func TestSystemAccountInternalSubscriptions(t *testing.T) {
function TestSystemAccountConnectionUpdatesStopAfterNoLocal (line 745) | func TestSystemAccountConnectionUpdatesStopAfterNoLocal(t *testing.T) {
function TestSystemAccountConnectionLimits (line 847) | func TestSystemAccountConnectionLimits(t *testing.T) {
function TestBadAccountUpdate (line 891) | func TestBadAccountUpdate(t *testing.T) {
function TestSystemAccountSystemConnectionLimitsHonored (line 913) | func TestSystemAccountSystemConnectionLimitsHonored(t *testing.T) {
fun
Copy disabled (too large)
Download .json
Condensed preview — 482 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (13,588K chars).
[
{
"path": ".coveralls.yml",
"chars": 25,
"preview": "service_name: travis-pro\n"
},
{
"path": ".github/CODEOWNERS",
"chars": 132,
"preview": "* @nats-io/server\n*.go @nats-io/server-dev\ndoc/ @nats-io/server-dev\ntest/ @nats-io/server-dev\nlocksordering.txt @nats-io"
},
{
"path": ".github/FUNDING.yml",
"chars": 84,
"preview": "# These are supported funding model platforms\n\n# NATS.io\ncommunity_bridge: nats-io\n\n"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 333,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: Discussion\n url: https://github.com/nats-io/nats-server/discussi"
},
{
"path": ".github/ISSUE_TEMPLATE/defect.yml",
"chars": 1695,
"preview": "---\nname: Defect\ndescription: Report a defect, such as a bug or regression.\nlabels:\n - defect\nbody:\n - type: textarea\n"
},
{
"path": ".github/ISSUE_TEMPLATE/proposal.yml",
"chars": 724,
"preview": "---\nname: Proposal\ndescription: Propose an enhancement or new feature.\nlabels:\n - proposal\nbody:\n - type: textarea\n "
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 358,
"preview": "<!-- Please make sure to read CONTRIBUTING.md, then delete this notice and replace it with your PR description. The belo"
},
{
"path": ".github/actions/nightly-release/action.yaml",
"chars": 1500,
"preview": "name: Nightly Docker Releaser\ndescription: Builds nightly docker images\n\ninputs:\n hub_username:\n description: Docker"
},
{
"path": ".github/dependabot.yml",
"chars": 206,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"gomod\"\n directory: \"/\"\n schedule:\n interval: \"weekly\"\n - package"
},
{
"path": ".github/workflows/claude.yml",
"chars": 1109,
"preview": "name: Claude Code\n\n# GITHUB_TOKEN is neutered — all GitHub API access uses the App token instead.\npermissions: {}\n\non:\n "
},
{
"path": ".github/workflows/cov.yaml",
"chars": 1606,
"preview": "name: NATS Server Code Coverage\non:\n workflow_dispatch: {}\n\n schedule:\n - cron: \"40 4 * * *\"\n\npermissions:\n conten"
},
{
"path": ".github/workflows/long-tests.yaml",
"chars": 831,
"preview": "name: NATS Server Long Tests\n\non:\n # Allow manual trigger (any branch)\n workflow_dispatch:\n # Run daily at 12:30 on d"
},
{
"path": ".github/workflows/mqtt-test.yaml",
"chars": 1621,
"preview": "name: MQTT External Tests\non: [pull_request]\n\npermissions:\n contents: read\n\njobs:\n test:\n env:\n GOPATH: /home/"
},
{
"path": ".github/workflows/nightly.yaml",
"chars": 1315,
"preview": "name: Docker Nightly\non:\n workflow_dispatch:\n inputs:\n target:\n description: \"Override source branch (op"
},
{
"path": ".github/workflows/release.yaml",
"chars": 1675,
"preview": "name: NATS Server Releases\non:\n push:\n tags:\n - v*\n\npermissions:\n contents: read\n\njobs:\n run:\n name: GitHu"
},
{
"path": ".github/workflows/stale-issues.yaml",
"chars": 507,
"preview": "name: Stale Issues\non:\n schedule:\n - cron: \"30 1 * * *\"\n\npermissions:\n issues: write\n pull-requests: write\n\njobs:\n"
},
{
"path": ".github/workflows/tests.yaml",
"chars": 11602,
"preview": "name: NATS Server Tests\n\non:\n push:\n pull_request:\n workflow_dispatch:\n\npermissions:\n contents: read\n\nenv:\n RACE: $"
},
{
"path": ".github/workflows/vuln.yaml",
"chars": 906,
"preview": "name: Vulnerability Scan\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n schedule:\n - cron: "
},
{
"path": ".gitignore",
"chars": 490,
"preview": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\ndist\n\n# Configurati"
},
{
"path": ".golangci.yml",
"chars": 1765,
"preview": "version: \"2\"\nrun:\n concurrency: 4\n modules-download-mode: readonly\n issues-exit-code: 1\n tests: true\noutput:\n forma"
},
{
"path": ".goreleaser.yml",
"chars": 2895,
"preview": "project_name: nats-server\nversion: 2\n\nrelease:\n github:\n owner: '{{ envOrDefault \"GITHUB_REPOSITORY_OWNER\" \"nats-io\""
},
{
"path": "AMBASSADORS.md",
"chars": 321,
"preview": "# Ambassadors\n\nThe NATS ambassador program recognizes community members that go above and beyond in their contributions "
},
{
"path": "CODE-OF-CONDUCT.md",
"chars": 138,
"preview": "## Community Code of Conduct\n\nNATS follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/cod"
},
{
"path": "CONTRIBUTING.md",
"chars": 3956,
"preview": "# Contributing\n\nThanks for your interest in contributing! This document contains `nats-io/nats-server` specific contribu"
},
{
"path": "DEPENDENCIES.md",
"chars": 799,
"preview": "# External Dependencies\n\nThis file lists the dependencies used in this repository.\n\n| Dependency | License |\n|-|-|\n| Go "
},
{
"path": "GOVERNANCE.md",
"chars": 172,
"preview": "# NATS Server Governance\n\nNATS Server is part of the NATS project and is subject to the [NATS Governance](https://github"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "MAINTAINERS.md",
"chars": 576,
"preview": "# Maintainers\n\nMaintainership is on a per project basis. Reference [NATS Governance Model](https://github.com/nats-io/na"
},
{
"path": "README.md",
"chars": 4576,
"preview": "<p align=\"center\">\n <img src=\"logos/nats-horizontal-color.png\" width=\"300\" alt=\"NATS Logo\">\n</p>\n\n[NATS](https://nats.i"
},
{
"path": "RELEASES.md",
"chars": 956,
"preview": "# Release Workflow\n\n- As of NATS 2.11, the server follows a 6-month release cycle. 2.11 was released in March 2025.\n- Ve"
},
{
"path": "TODO.md",
"chars": 2254,
"preview": "\n# General\n\n- [ ] Auth for queue groups?\n- [ ] Blacklist or ERR escalation to close connection for auth/permissions\n- [ "
},
{
"path": "conf/fuzz.go",
"chars": 728,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "conf/lex.go",
"chars": 33663,
"preview": "// Copyright 2013-2024 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "conf/lex_test.go",
"chars": 36616,
"preview": "package conf\n\nimport \"testing\"\n\n// Test to make sure we get what we expect.\nfunc expect(t *testing.T, lx *lexer, items ["
},
{
"path": "conf/parse.go",
"chars": 12885,
"preview": "// Copyright 2013-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "conf/parse_test.go",
"chars": 24179,
"preview": "package conf\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n"
},
{
"path": "doc/README.md",
"chars": 151,
"preview": "# Architecture Decision Records\n\nThe NATS ADR documents have moved to their [own repository](https://github.com/nats-io/"
},
{
"path": "docker/Dockerfile.nightly",
"chars": 1433,
"preview": "FROM --platform=$BUILDPLATFORM golang:alpine AS builder\n\nARG VERSION=\"nightly\"\nARG GIT_COMMIT\n\nARG TARGETOS\nARG TARGETAR"
},
{
"path": "go.mod",
"chars": 720,
"preview": "module github.com/nats-io/nats-server/v2\n\ngo 1.25.0\n\ntoolchain go1.25.8\n\nrequire (\n\tgithub.com/antithesishq/antithesis-s"
},
{
"path": "go.sum",
"chars": 2033,
"preview": "github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op h1:kpBdlEPbRvff0mDD1gk7o9BhI16b9p5yYAXRlidpqJE=\ngithub.co"
},
{
"path": "internal/antithesis/noop.go",
"chars": 973,
"preview": "// Copyright 2022-2024 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "internal/antithesis/test_assert.go",
"chars": 4087,
"preview": "// Copyright 2022-2024 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "internal/fastrand/LICENSE",
"chars": 1486,
"preview": "Copyright (c) 2011 The LevelDB-Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with"
},
{
"path": "internal/fastrand/fastrand.go",
"chars": 628,
"preview": "// Copyright 2020-2023 The LevelDB-Go, Pebble and NATS Authors. All rights reserved.\n// Use of this source code is gover"
},
{
"path": "internal/fastrand/fastrand_test.go",
"chars": 1206,
"preview": "// Copyright 2020-23 The LevelDB-Go, Pebble and NATS Authors. All rights reserved.\n// Use of this source code is governe"
},
{
"path": "internal/ldap/dn.go",
"chars": 8551,
"preview": "// Copyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)\n// Portions copyright (c) 2015-2016 go-ldap Authors\npackag"
},
{
"path": "internal/ldap/dn_test.go",
"chars": 6229,
"preview": "// Copyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)\n// Portions copyright (c) 2015-2016 go-ldap Authors\n// Sta"
},
{
"path": "internal/ocsp/ocsp.go",
"chars": 7391,
"preview": "// Copyright 2019-2024 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "internal/testhelper/logging.go",
"chars": 3218,
"preview": "// Copyright 2019-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "locksordering.txt",
"chars": 1930,
"preview": "Here is the list of some established lock ordering.\n\nIn this list, A -> B means that you can have A.Lock() then B.Lock()"
},
{
"path": "logger/log.go",
"chars": 9756,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "logger/log_test.go",
"chars": 8637,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "logger/syslog.go",
"chars": 3350,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "logger/syslog_test.go",
"chars": 5613,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "logger/syslog_windows.go",
"chars": 2978,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "logger/syslog_windows_test.go",
"chars": 3975,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "main.go",
"chars": 5259,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "scripts/cov.sh",
"chars": 2469,
"preview": "#!/bin/bash\n# Run from directory above via ./scripts/cov.sh\n\ncheck_file () {\n # If the content of the file is simply "
},
{
"path": "scripts/runTestsOnTravis.sh",
"chars": 6025,
"preview": "#!/bin/sh\n\nset -ex\n\nif [ \"$1\" = \"compile\" ]; then\n # First check that NATS builds.\n go build -v;\n\n # Now run th"
},
{
"path": "scripts/updateCopyrights.sh",
"chars": 1676,
"preview": "#!/bin/bash\n\n# Ensure script is run at the root of a git repository\ngit rev-parse --is-inside-work-tree &>/dev/null || {"
},
{
"path": "server/README-MQTT.md",
"chars": 29099,
"preview": "**MQTT Implementation Overview**\n\nRevision 1.1\n\nAuthors: Ivan Kozlovic, Lev Brouk\n\nNATS Server currently supports most o"
},
{
"path": "server/README.md",
"chars": 876,
"preview": "# Tests\n\nTests that run on Travis have been split into jobs that run in their own VM in parallel. This reduces the overa"
},
{
"path": "server/accounts.go",
"chars": 137736,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/accounts_test.go",
"chars": 122603,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/ats/ats.go",
"chars": 2411,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/ats/ats_test.go",
"chars": 2498,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/auth.go",
"chars": 51758,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/auth_callout.go",
"chars": 15842,
"preview": "// Copyright 2022-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/auth_callout_test.go",
"chars": 83583,
"preview": "// Copyright 2022-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/auth_test.go",
"chars": 20406,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/avl/norace_test.go",
"chars": 5515,
"preview": "// Copyright 2023-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/avl/seqset.go",
"chars": 14283,
"preview": "// Copyright 2023-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/avl/seqset_test.go",
"chars": 9002,
"preview": "// Copyright 2023 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/benchmark_publish_test.go",
"chars": 4320,
"preview": "// Copyright 2022 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/certidp/certidp.go",
"chars": 10224,
"preview": "// Copyright 2023-2024 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/certidp/certidp_test.go",
"chars": 1390,
"preview": "// Copyright 2023 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/certidp/messages.go",
"chars": 6862,
"preview": "// Copyright 2023 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/certidp/ocsp_responder.go",
"chars": 2488,
"preview": "// Copyright 2023-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/certidp/ocsp_responder_test.go",
"chars": 707,
"preview": "package certidp\n\nimport (\n\t\"encoding/base64\"\n\t\"net/url\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestEncodeOCSPRequest(t *testing.T"
},
{
"path": "server/certstore/certstore.go",
"chars": 2629,
"preview": "// Copyright 2022-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/certstore/certstore_other.go",
"chars": 1429,
"preview": "// Copyright 2022-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/certstore/certstore_windows.go",
"chars": 30601,
"preview": "// Copyright 2022-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/certstore/errors.go",
"chars": 4104,
"preview": "package certstore\n\nimport (\n\t\"errors\"\n)\n\nvar (\n\t// ErrBadCryptoStoreProvider represents inablity to establish link with "
},
{
"path": "server/certstore_windows_test.go",
"chars": 11347,
"preview": "// Copyright 2022-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/ciphersuites.go",
"chars": 2043,
"preview": "// Copyright 2016-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/client.go",
"chars": 196488,
"preview": "// Copyright 2012-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/client_proxyproto.go",
"chars": 13661,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/client_proxyproto_test.go",
"chars": 17592,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/client_test.go",
"chars": 105580,
"preview": "// Copyright 2012-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/closed_conns_test.go",
"chars": 7100,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/config_check_test.go",
"chars": 61382,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/configs/certs/cert.new.pem",
"chars": 1314,
"preview": "-----BEGIN CERTIFICATE-----\nMIIDnjCCAoagAwIBAgIJAM/HacKKaH7zMA0GCSqGSIb3DQEBCwUAMIGDMQswCQYD\nVQQGEwJVUzELMAkGA1UECAwCQ0E"
},
{
"path": "server/configs/certs/key.new.pem",
"chars": 1704,
"preview": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC8EgBVSviAIQFF\nVsAdLB4IsTE6sxmYgjgB2+AipP6"
},
{
"path": "server/configs/certs/key.pem",
"chars": 1704,
"preview": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDc8YaxliKNsa8M\nidwQsDXS0MI4z+ZP1UMW9U/Vt2q"
},
{
"path": "server/configs/certs/server.pem",
"chars": 1314,
"preview": "-----BEGIN CERTIFICATE-----\nMIIDnjCCAoagAwIBAgIJAOXpOWk41Pd7MA0GCSqGSIb3DQEBCwUAMIGDMQswCQYD\nVQQGEwJVUzELMAkGA1UECAwCQ0E"
},
{
"path": "server/configs/certs/tls/benchmark-ca-cert.pem",
"chars": 1399,
"preview": "-----BEGIN CERTIFICATE-----\nMIID2zCCAsOgAwIBAgIUZj0PngA93uUSShcRndTQju/J88YwDQYJKoZIhvcNAQEL\nBQAwfDETMBEGA1UEAwwKbmF0cy5"
},
{
"path": "server/configs/certs/tls/benchmark-ca-key.pem",
"chars": 1704,
"preview": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDZwLIkv4MTFTJm\n2jZ4UuYwFFKRAvEz2k5YH07xN5w"
},
{
"path": "server/configs/certs/tls/benchmark-server-cert-ed25519.pem",
"chars": 1139,
"preview": "-----BEGIN CERTIFICATE-----\nMIIDHTCCAgWgAwIBAgIUc31LCktokAIQGqLsSC2BlsLCTsYwDQYJKoZIhvcNAQEL\nBQAwfDETMBEGA1UEAwwKbmF0cy5"
},
{
"path": "server/configs/certs/tls/benchmark-server-cert-rsa-1024.pem",
"chars": 1302,
"preview": "-----BEGIN CERTIFICATE-----\nMIIDkzCCAnugAwIBAgIUc31LCktokAIQGqLsSC2BlsLCTsMwDQYJKoZIhvcNAQEL\nBQAwfDETMBEGA1UEAwwKbmF0cy5"
},
{
"path": "server/configs/certs/tls/benchmark-server-cert-rsa-2048.pem",
"chars": 1480,
"preview": "-----BEGIN CERTIFICATE-----\nMIIEFzCCAv+gAwIBAgIUc31LCktokAIQGqLsSC2BlsLCTsQwDQYJKoZIhvcNAQEL\nBQAwfDETMBEGA1UEAwwKbmF0cy5"
},
{
"path": "server/configs/certs/tls/benchmark-server-cert-rsa-4096.pem",
"chars": 1826,
"preview": "-----BEGIN CERTIFICATE-----\nMIIFFzCCA/+gAwIBAgIUc31LCktokAIQGqLsSC2BlsLCTsUwDQYJKoZIhvcNAQEL\nBQAwfDETMBEGA1UEAwwKbmF0cy5"
},
{
"path": "server/configs/certs/tls/benchmark-server-key-ed25519.pem",
"chars": 119,
"preview": "-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEIJRCtUNxUuutNs9j8OtcwFw1xkbs+zxjHhpAqVuqDNo5\n-----END PRIVATE KEY-----\n"
},
{
"path": "server/configs/certs/tls/benchmark-server-key-rsa-1024.pem",
"chars": 916,
"preview": "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALIcdpUeKcHeMGyJ\nxHiGnu6inPS7f46RSJwhRJBcNxa"
},
{
"path": "server/configs/certs/tls/benchmark-server-key-rsa-2048.pem",
"chars": 1704,
"preview": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDLHc75nq7xjVKK\n4e7ezNZsu8tatmlKkSJmSWX7CTn"
},
{
"path": "server/configs/certs/tls/benchmark-server-key-rsa-4096.pem",
"chars": 3272,
"preview": "-----BEGIN PRIVATE KEY-----\nMIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCP+vDRakKeLNRK\nzTo3FKyO5hvqxa1hCMt3o7pIKhD"
},
{
"path": "server/configs/one.creds",
"chars": 972,
"preview": "-----BEGIN NATS USER JWT-----\neyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJHRUNQVEpISE1TM01DTUtMVFBHWUdBTzQ"
},
{
"path": "server/const.go",
"chars": 8851,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/consumer.go",
"chars": 193337,
"preview": "// Copyright 2019-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/core_benchmarks_test.go",
"chars": 15871,
"preview": "// Copyright 2023-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/cron.go",
"chars": 9147,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/dirstore.go",
"chars": 19568,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/dirstore_test.go",
"chars": 25538,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/disk_avail.go",
"chars": 1159,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/disk_avail_netbsd.go",
"chars": 762,
"preview": "// Copyright 2022-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/disk_avail_openbsd.go",
"chars": 1106,
"preview": "// Copyright 2021-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/disk_avail_solaris.go",
"chars": 1120,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/disk_avail_wasm.go",
"chars": 704,
"preview": "// Copyright 2022-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/disk_avail_windows.go",
"chars": 769,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/elastic/elastic.go",
"chars": 1228,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/errors.go",
"chars": 17216,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/errors.json",
"chars": 49939,
"preview": "[\n {\n \"constant\": \"JSClusterPeerNotMemberErr\",\n \"code\": 400,\n \"error_code\": 10040,\n \"description\": \"peer no"
},
{
"path": "server/errors_gen.go",
"chars": 5353,
"preview": "//go:build ignore\n\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"os/exec\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\t"
},
{
"path": "server/errors_test.go",
"chars": 2332,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/events.go",
"chars": 102092,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/events_test.go",
"chars": 117621,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/filestore.go",
"chars": 356778,
"preview": "// Copyright 2019-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/filestore_test.go",
"chars": 393595,
"preview": "// Copyright 2019-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/gateway.go",
"chars": 103107,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/gateway_test.go",
"chars": 227578,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/gsl/gsl.go",
"chars": 10912,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/gsl/gsl_test.go",
"chars": 13028,
"preview": "// Copyright 2016-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/ipqueue.go",
"chars": 8035,
"preview": "// Copyright 2021-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/ipqueue_test.go",
"chars": 16059,
"preview": "// Copyright 2021-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream.go",
"chars": 84618,
"preview": "// Copyright 2019-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_api.go",
"chars": 162064,
"preview": "// Copyright 2020-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_batching.go",
"chars": 35725,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/jetstream_batching_test.go",
"chars": 135712,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/jetstream_benchmark_test.go",
"chars": 62407,
"preview": "// Copyright 2023-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_cluster.go",
"chars": 328022,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_cluster_1_test.go",
"chars": 329661,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_cluster_2_test.go",
"chars": 236610,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_cluster_3_test.go",
"chars": 231572,
"preview": "// Copyright 2022-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_cluster_4_test.go",
"chars": 222755,
"preview": "// Copyright 2022-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_cluster_long_test.go",
"chars": 30590,
"preview": "// Copyright 2022-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_consumer_test.go",
"chars": 326828,
"preview": "// Copyright 2022-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_errors.go",
"chars": 2112,
"preview": "package server\n\nimport (\n\t\"fmt\"\n)\n\ntype errOpts struct {\n\terr error\n}\n\n// ErrorOption configures a NATS Error helper\ntyp"
},
{
"path": "server/jetstream_errors_generated.go",
"chars": 137890,
"preview": "// Generated code, do not edit. See errors.json and run go generate to update\n\npackage server\n\nimport \"strings\"\n\nconst ("
},
{
"path": "server/jetstream_errors_test.go",
"chars": 2811,
"preview": "package server\n\nimport (\n\t\"errors\"\n\t\"testing\"\n)\n\nfunc TestIsNatsErr(t *testing.T) {\n\tif !IsNatsErr(ApiErrors[JSNotEnable"
},
{
"path": "server/jetstream_events.go",
"chars": 14022,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_helpers_test.go",
"chars": 59623,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_jwt_test.go",
"chars": 66713,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_leafnode_test.go",
"chars": 54617,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_meta_benchmark_test.go",
"chars": 8884,
"preview": "// Copyright 2024-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_sourcing_scaling_test.go",
"chars": 8298,
"preview": "// Copyright 2024 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/jetstream_super_cluster_test.go",
"chars": 148512,
"preview": "// Copyright 2020-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_test.go",
"chars": 660133,
"preview": "// Copyright 2019-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_tpm_test.go",
"chars": 5846,
"preview": "// Copyright 2024 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/jetstream_versioning.go",
"chars": 7744,
"preview": "// Copyright 2024-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jetstream_versioning_test.go",
"chars": 22727,
"preview": "// Copyright 2024-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jwt.go",
"chars": 7799,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/jwt_test.go",
"chars": 231886,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/leafnode.go",
"chars": 111477,
"preview": "// Copyright 2019-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/leafnode_proxy_test.go",
"chars": 24046,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/leafnode_test.go",
"chars": 305151,
"preview": "// Copyright 2019-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/log.go",
"chars": 8035,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/log_test.go",
"chars": 19073,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/memstore.go",
"chars": 71599,
"preview": "// Copyright 2019-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/memstore_test.go",
"chars": 45854,
"preview": "// Copyright 2019-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/monitor.go",
"chars": 143092,
"preview": "// Copyright 2013-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/monitor_sort_opts.go",
"chars": 4795,
"preview": "// Copyright 2013-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/monitor_test.go",
"chars": 198287,
"preview": "// Copyright 2013-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/mqtt.go",
"chars": 180493,
"preview": "// Copyright 2020-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/mqtt_ex_bench_test.go",
"chars": 8221,
"preview": "// Copyright 2024-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/mqtt_ex_test_test.go",
"chars": 8951,
"preview": "// Copyright 2024-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/mqtt_test.go",
"chars": 295029,
"preview": "// Copyright 2020-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/msgtrace.go",
"chars": 22351,
"preview": "// Copyright 2024-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/msgtrace_test.go",
"chars": 166802,
"preview": "// Copyright 2024-2026 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/nkey.go",
"chars": 1406,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/nkey_test.go",
"chars": 8350,
"preview": "// Copyright 2018-2024 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/norace_1_test.go",
"chars": 229981,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/norace_2_test.go",
"chars": 94846,
"preview": "// Copyright 2018-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/ocsp.go",
"chars": 27465,
"preview": "// Copyright 2021-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/ocsp_peer.go",
"chars": 14724,
"preview": "// Copyright 2023-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/ocsp_responsecache.go",
"chars": 16136,
"preview": "// Copyright 2023-2024 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/opts.go",
"chars": 200163,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/opts_test.go",
"chars": 121818,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/parser.go",
"chars": 26077,
"preview": "// Copyright 2012-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/parser_fuzz_test.go",
"chars": 2265,
"preview": "// Copyright 2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/parser_test.go",
"chars": 29635,
"preview": "// Copyright 2012-2024 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/ping_test.go",
"chars": 1733,
"preview": "// Copyright 2015-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/proto.go",
"chars": 5688,
"preview": "// Copyright 2024 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/pse/freebsd.txt",
"chars": 984,
"preview": "/*\n * Compile and run this as a C program to get the kinfo_proc offsets\n * for your architecture.\n * While FreeBSD works"
},
{
"path": "server/pse/pse_darwin.go",
"chars": 2702,
"preview": "// Copyright 2015-2021 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/pse/pse_dragonfly.go",
"chars": 1116,
"preview": "// Copyright 2015-2023 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/pse/pse_freebsd_cgo.go",
"chars": 1728,
"preview": "// Copyright 2015-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/pse/pse_freebsd_sysctl.go",
"chars": 4523,
"preview": "// Copyright 2015-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/pse/pse_linux.go",
"chars": 2671,
"preview": "// Copyright 2015-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/pse/pse_netbsd.go",
"chars": 1111,
"preview": "// Copyright 2022 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "server/pse/pse_openbsd.go",
"chars": 1115,
"preview": "// Copyright 2015-2018 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
},
{
"path": "server/pse/pse_rumprun.go",
"chars": 762,
"preview": "// Copyright 2015-2025 The NATS Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
}
]
// ... and 282 more files (download for full content)
About this extraction
This page contains the full source code of the nats-io/nats-server GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 482 files (11.8 MB), approximately 3.1M tokens, and a symbol index with 11136 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.