Compare commits
3 Commits
29966dc838
...
d541e1e759
Author | SHA1 | Date | |
---|---|---|---|
d541e1e759 | |||
67cb801f54 | |||
b453ec3d92 |
50
README.md
50
README.md
@ -8,18 +8,64 @@ There are three main goals:
|
|||||||
2. Provide a native-feeling Zig client API.
|
2. Provide a native-feeling Zig client API.
|
||||||
3. Support cross-compilation to the platforms that Zig supports.
|
3. Support cross-compilation to the platforms that Zig supports.
|
||||||
|
|
||||||
Right now, in service of goal 3, the underlying C library is built without certain features (notably, without TLS support and without streaming support) because those features require wrangling some complex transitive dependencies (OpenSSL and Protocol Buffers, respectively). Solving this limitation is somewhere on the roadmap, but it's not high priority.
|
Right now, in service of goal 3, the underlying C library is built without certain features (notably, without streaming support) due to those features requiring managing some transitive dependencies (for streaming, the `protobuf-c` library). Solving this limitation is somewhere on the roadmap, but it's not high priority. `nats.c` is compiled against a copy of LibreSSL that has been wrapped with the zig build system. This appears to work, but it notably is not specifically OpenSSL, so there may be corner cases around encrypted connections.
|
||||||
|
|
||||||
# Zig Version Support
|
# Zig Version Support
|
||||||
|
|
||||||
Since the language is still under active development, any written Zig code is a moving target. The plan is to support Zig `0.11.*` exclusively until the NATS library API has good coverage and is stabilized. At that point, if there are major breaking changes, a maintenance branch will be created, and master will probably move to track Zig master.
|
Since the language is still under active development, any written Zig code is a moving target. The plan is to support Zig `0.11.*` exclusively until the NATS library API has good coverage and is stabilized. At that point, if there are major breaking changes, a maintenance branch will be created, and master will probably move to track Zig master.
|
||||||
|
|
||||||
|
# Using
|
||||||
|
|
||||||
|
NATS.zig is ready-to-use with the Zig package manager. With Zig 0.11.x, this means you will need to create a `build.zig.zon` and modify your `build.zig` to use the dependency.
|
||||||
|
|
||||||
|
### Example `build.zig.zon`
|
||||||
|
|
||||||
|
```zig
|
||||||
|
.{
|
||||||
|
.name = "my cool project",
|
||||||
|
.version = "0.1.0",
|
||||||
|
.dependencies = .{
|
||||||
|
.nats = .{
|
||||||
|
.url = "https://github.com/epicyclic-dev/nats.zig/archive/<git commit hash>.tar.gz",
|
||||||
|
// on first run, `zig build` will prompt you to add the missing hash.
|
||||||
|
// .hash = "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example `build.zig`
|
||||||
|
|
||||||
|
```zig
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
const my_program = b.addExecutable(.{
|
||||||
|
.name="cool-project",
|
||||||
|
.root_source_file = .{.path = "my_cool_project.zig"},
|
||||||
|
});
|
||||||
|
|
||||||
|
my_program.addModule(
|
||||||
|
"nats",
|
||||||
|
b.dependency("nats", .{}).module("nats"),
|
||||||
|
);
|
||||||
|
|
||||||
|
b.installArtifact(my_program);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# Building
|
# Building
|
||||||
|
|
||||||
Currently, a demonstration executable can be built in the standard fashion, i.e. by running `zig build`.
|
Some basic example executables can be built using `zig build examples`. These examples expect you to be running a copy of `nats-server` listening for unencrypted connections on `localhost:4222` (the default NATS port).
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
|
||||||
|
Unit tests can be run using `zig build test`. The unit tests expect an executable named `nats-server` to be in your PATH in order to run properly.
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
|
Unless noted otherwise (check file headers), all source code is licensed under the Apache License, Version 2.0 (which is also the `nats.c` license).
|
||||||
|
|
||||||
```
|
```
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
// This file is licensed under the CC0 1.0 license.
|
||||||
|
// See: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const nats = @import("nats");
|
const nats = @import("nats");
|
||||||
|
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
// This file is licensed under the CC0 1.0 license.
|
||||||
|
// See: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const nats = @import("nats");
|
const nats = @import("nats");
|
||||||
|
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
// This file is licensed under the CC0 1.0 license.
|
||||||
|
// See: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const nats = @import("nats");
|
const nats = @import("nats");
|
||||||
|
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
// Copyright 2023 torque@epicyclic.dev
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub const nats_c = @cImport({
|
pub const nats_c = @cImport({
|
||||||
@ -46,7 +60,7 @@ pub const AddressPort = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Connection = opaque {
|
pub const Connection = opaque {
|
||||||
pub fn create(options: *ConnectionOptions) Error!*Connection {
|
pub fn connect(options: *ConnectionOptions) Error!*Connection {
|
||||||
var self: *Connection = undefined;
|
var self: *Connection = undefined;
|
||||||
const status = Status.fromInt(nats_c.natsConnection_Connect(@ptrCast(&self), @ptrCast(options)));
|
const status = Status.fromInt(nats_c.natsConnection_Connect(@ptrCast(&self), @ptrCast(options)));
|
||||||
return status.toError() orelse self;
|
return status.toError() orelse self;
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
// Copyright 2023 torque@epicyclic.dev
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub const nats_c = @cImport({
|
pub const nats_c = @cImport({
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
// Copyright 2023 torque@epicyclic.dev
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub const nats_c = @cImport({
|
pub const nats_c = @cImport({
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
// Copyright 2023 torque@epicyclic.dev
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const nats_c = @cImport({
|
const nats_c = @cImport({
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
// Copyright 2023 torque@epicyclic.dev
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub const nats_c = @cImport({
|
pub const nats_c = @cImport({
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
// Copyright 2023 torque@epicyclic.dev
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub const nats_c = @cImport({
|
pub const nats_c = @cImport({
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
|
// This file is licensed under the CC0 1.0 license.
|
||||||
|
// See: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const nats = @import("nats");
|
const nats = @import("nats");
|
||||||
|
|
||||||
const util = @import("./util.zig");
|
const util = @import("./util.zig");
|
||||||
|
|
||||||
|
const rsa_key = @embedFile("./data/client-rsa.key");
|
||||||
|
const rsa_cert = @embedFile("./data/client-rsa.cert");
|
||||||
|
const ecc_key = @embedFile("./data/client-ecc.key");
|
||||||
|
const ecc_cert = @embedFile("./data/client-ecc.cert");
|
||||||
|
|
||||||
test "nats.Connection.connectTo" {
|
test "nats.Connection.connectTo" {
|
||||||
{
|
{
|
||||||
var server = try util.TestServer.launch(.{});
|
var server = try util.TestServer.launch(.{});
|
||||||
@ -43,11 +51,6 @@ test "nats.Connection.connectTo" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tokenHandler(userdata: *u32) [:0]const u8 {
|
|
||||||
_ = userdata;
|
|
||||||
return "token";
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reconnectDelayHandler(userdata: *u32, connection: *nats.Connection, attempts: c_int) i64 {
|
fn reconnectDelayHandler(userdata: *u32, connection: *nats.Connection, attempts: c_int) i64 {
|
||||||
_ = userdata;
|
_ = userdata;
|
||||||
_ = connection;
|
_ = connection;
|
||||||
@ -100,19 +103,10 @@ test "nats.ConnectionOptions" {
|
|||||||
try options.setServers(&servers);
|
try options.setServers(&servers);
|
||||||
try options.setCredentials("user", "password");
|
try options.setCredentials("user", "password");
|
||||||
try options.setToken("test_token");
|
try options.setToken("test_token");
|
||||||
// requires a functioning token handler, which I will not write right now. Also
|
|
||||||
// cannot be called if a token has already been set
|
|
||||||
// try options.setTokenHandler(u32, tokenHandler, &userdata);
|
|
||||||
try options.setNoRandomize(false);
|
try options.setNoRandomize(false);
|
||||||
try options.setTimeout(1000);
|
try options.setTimeout(1000);
|
||||||
try options.setName("name");
|
try options.setName("name");
|
||||||
|
|
||||||
// the following all require a build with openssl
|
|
||||||
// try options.setSecure(false);
|
|
||||||
// try options.setCiphers("-ALL:HIGH");
|
|
||||||
// try options.setCipherSuites("TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256");
|
|
||||||
// try options.setExpectedHostname("host.name");
|
|
||||||
// try options.skipServerVerification(true);
|
|
||||||
try options.setVerbose(true);
|
try options.setVerbose(true);
|
||||||
try options.setPedantic(true);
|
try options.setPedantic(true);
|
||||||
try options.setPingInterval(1000);
|
try options.setPingInterval(1000);
|
||||||
@ -144,3 +138,67 @@ test "nats.ConnectionOptions" {
|
|||||||
try options.setCustomInboxPrefix("_FOOBOX");
|
try options.setCustomInboxPrefix("_FOOBOX");
|
||||||
try options.setMessageBufferPadding(123);
|
try options.setMessageBufferPadding(123);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tokenHandler(userdata: *u32) [:0]const u8 {
|
||||||
|
_ = userdata;
|
||||||
|
return "token";
|
||||||
|
}
|
||||||
|
|
||||||
|
test "nats.ConnectionOptions (crypto edition)" {
|
||||||
|
try nats.init(nats.default_spin_count);
|
||||||
|
defer nats.deinit();
|
||||||
|
|
||||||
|
const options = try nats.ConnectionOptions.create();
|
||||||
|
defer options.destroy();
|
||||||
|
var userdata: u32 = 0;
|
||||||
|
|
||||||
|
try options.setTokenHandler(u32, tokenHandler, &userdata);
|
||||||
|
try options.setSecure(false);
|
||||||
|
try options.setCertificatesChain(rsa_cert, rsa_key);
|
||||||
|
try options.setCiphers("-ALL:HIGH");
|
||||||
|
try options.setCipherSuites("TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256");
|
||||||
|
try options.setExpectedHostname("test.nats.zig");
|
||||||
|
try options.skipServerVerification(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "nats.ConnectionOptions (crypto connect)" {
|
||||||
|
{
|
||||||
|
var server = try util.TestServer.launch(.{ .tls = .rsa });
|
||||||
|
defer server.stop();
|
||||||
|
|
||||||
|
try nats.init(nats.default_spin_count);
|
||||||
|
defer nats.deinit();
|
||||||
|
|
||||||
|
const options = try nats.ConnectionOptions.create();
|
||||||
|
defer options.destroy();
|
||||||
|
|
||||||
|
try options.setSecure(true);
|
||||||
|
try options.skipServerVerification(true);
|
||||||
|
try options.setCertificatesChain(rsa_cert, rsa_key);
|
||||||
|
|
||||||
|
const connection = try nats.Connection.connect(options);
|
||||||
|
defer connection.destroy();
|
||||||
|
|
||||||
|
try connection.publish("foo", "bar");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var server = try util.TestServer.launch(.{ .tls = .ecc });
|
||||||
|
defer server.stop();
|
||||||
|
|
||||||
|
try nats.init(nats.default_spin_count);
|
||||||
|
defer nats.deinit();
|
||||||
|
|
||||||
|
const options = try nats.ConnectionOptions.create();
|
||||||
|
defer options.destroy();
|
||||||
|
|
||||||
|
try options.setSecure(true);
|
||||||
|
try options.skipServerVerification(true);
|
||||||
|
try options.setCertificatesChain(ecc_cert, ecc_key);
|
||||||
|
|
||||||
|
const connection = try nats.Connection.connect(options);
|
||||||
|
defer connection.destroy();
|
||||||
|
|
||||||
|
try connection.publish("foo", "bar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
16
tests/data/client-ecc.cert
Normal file
16
tests/data/client-ecc.cert
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIClTCCAhygAwIBAgIUNUxHIA2G0sEDgjWcx1svHk9wK1AwCgYIKoZIzj0EAwIw
|
||||||
|
gYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcMCENp
|
||||||
|
dHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFueVNl
|
||||||
|
Y3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5uYXRzLnppZzAgFw0yMzA5MDIyMjEz
|
||||||
|
MzJaGA8yMTIzMDgwOTIyMTMzMlowgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlT
|
||||||
|
dGF0ZU5hbWUxETAPBgNVBAcMCENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFt
|
||||||
|
ZTEbMBkGA1UECwwSQ29tcGFueVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5u
|
||||||
|
YXRzLnppZzB2MBAGByqGSM49AgEGBSuBBAAiA2IABPcAhGdzooeoL0SY1qJmY3SY
|
||||||
|
cyngBaon8ICyaQLRvOKEIhym25jB90xj4J2IDy3pg/5564G43NOOBZ/T4ClTv3XF
|
||||||
|
+2E71w+31HVGVKW4l+natAQt72oXn+HcjSnwrplYz6NTMFEwHQYDVR0OBBYEFFkN
|
||||||
|
/08ID2jBHkYMUzm7o8S8Ch86MB8GA1UdIwQYMBaAFFkN/08ID2jBHkYMUzm7o8S8
|
||||||
|
Ch86MA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDZwAwZAIwWauKBQMCf6XT
|
||||||
|
K1y2TvNZpqehk+MsQ8aDcNoUJ+iALJM7Y89XpibdZ4hvGPsQK/cgAjAg8SXHVWS5
|
||||||
|
yeFNtZdnRowEuQhtk5rRaj983wMSLbMXbz9Oxm0MY7edcS4MWP7l7nI=
|
||||||
|
-----END CERTIFICATE-----
|
6
tests/data/client-ecc.key
Normal file
6
tests/data/client-ecc.key
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDfkvPMjrVTAU06KSLK
|
||||||
|
vxKDF3+vdWDQUxQBIJ3F1qrSMJNzfuguXiYv8DMTbNvCNB+hZANiAAT3AIRnc6KH
|
||||||
|
qC9EmNaiZmN0mHMp4AWqJ/CAsmkC0bzihCIcptuYwfdMY+CdiA8t6YP+eeuBuNzT
|
||||||
|
jgWf0+ApU791xfthO9cPt9R1RlSluJfp2rQELe9qF5/h3I0p8K6ZWM8=
|
||||||
|
-----END PRIVATE KEY-----
|
34
tests/data/client-rsa.cert
Normal file
34
tests/data/client-rsa.cert
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIF5TCCA82gAwIBAgIUSiVHqM6yI2CBF8ZuakGuaXdAd0EwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcM
|
||||||
|
CENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFu
|
||||||
|
eVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5uYXRzLnppZzAgFw0yMzA5MDIy
|
||||||
|
MjE0MDZaGA8yMTIzMDgwOTIyMTQwNlowgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQI
|
||||||
|
DAlTdGF0ZU5hbWUxETAPBgNVBAcMCENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55
|
||||||
|
TmFtZTEbMBkGA1UECwwSQ29tcGFueVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0
|
||||||
|
cy5uYXRzLnppZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOF2MLuH
|
||||||
|
xvEUbc2PXQKhTL7flDvl/KWGxikE4HBQ96vQ3bHAzVuLezTI9D0qLTOvY1SVBy0C
|
||||||
|
En4e5ZklufTHciOg/a1B76IC2EFPEnhY0oO7pLfLzA43MU7biNvb1BGPW/MEihOZ
|
||||||
|
2ZmGnK1CiwynFKTkRJdafzK8OrQV9nmz+WNX0UqbDH6Gjp36V6VMcz+gHi01hqK+
|
||||||
|
v1lbAuUATGNEoZSVpGSoJx4+Ogyob9f4irsJX7GpO0dsKHUwd51pAm1pkpOH1rIU
|
||||||
|
CM+biSYaLt5fxFkSUJc9wqa+odE997hu5Ch6EEkdwg/4vYnigBMZxwFB3EVinXI0
|
||||||
|
5ywrYMwO8ozCrKmIDVG/FhNlzspooKVkZFKl8/T/1n8rDElsLc8No7clD0xFQxU8
|
||||||
|
3qyw05yaYm3khDMWTaD/B2w3AOoifZ9oWr6Ra2NN57yQx4sQdDy8s0WY4rVkv/nX
|
||||||
|
9VsBSeJwmmCfnnpse1Tq4Wfo7Jjz1Akl4n0GAQxkxR6gAkCfnkJrdkMKaOPQe+ep
|
||||||
|
Fs+5g2VrIeWQgzs5L4rte1qtMokK963IvqDSnsbPM6m9tcMQb8r+A0YbEOAK6D0D
|
||||||
|
nnKcguSKNkPP8hwaqJ9XNDXSN65I+DsgX0ngfHCh/grkSPJI2oEmx4DeaA8hgRzh
|
||||||
|
zbGpazOcVa4ahyUCxZKZi9c/+Aw3gir0fpQbAgMBAAGjUzBRMB0GA1UdDgQWBBRI
|
||||||
|
3sPebMsmYX0ourw+0SA8BqcXwTAfBgNVHSMEGDAWgBRI3sPebMsmYX0ourw+0SA8
|
||||||
|
BqcXwTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCkGzTMZdGT
|
||||||
|
dUQBbAqTzHvoc1Vy5OxadgJ4UGly9s7GpYg8brsevFmHyGHl+J9dBsnhmmNGxs1t
|
||||||
|
rU5lvnMWLOyvg7iLyx/4rkNAR03wyRgx1jK+4xIxMBj7YDB0WK6AtL3OUiqvTW4h
|
||||||
|
INoEIylyrIIOf7oHS9UkzDdZ3ZghH+EADjE6ksM/PuCRK0oTz9z7LUSMlcI5UCeb
|
||||||
|
P/V6N2QHzz2n+/BvTo/bpjHrwyUZ+eZbUC7rCfZX7Pi/pTGS2bps16lO2Us6tzIn
|
||||||
|
9If5h+MHHGOZXQtOZPYDFi3nLo/E+bBzt6Lvrt0Vm5DjXKzplrq+UMPbsEtGue7v
|
||||||
|
xSfcbPsXf44n+kZSFtFTjZ4zqpP05/H3R5eTayRUhVLkJlxDZbPiFjOSEupUmZq+
|
||||||
|
cpmf6Mq9OJJimyJBRaC0Lex4mCDUarXYLXXyNaIAQ2O+EmaNxZ2B86gHy6R3gaHr
|
||||||
|
w66pDXq0IXznJyr50aKu7WYJHOE5HOaBgptU7lXz35+5yId7WKWorXfGIYBWCc3g
|
||||||
|
LRDr0pgyLk1YVxz2tphR8hEJ7rJb+gMR3t5UzDElsUIqKJo/6Aziq4dRlrj5x62s
|
||||||
|
Vmm7JJqMSyh6UDJowwFicS3KTZbKZnxRHdyy8Km6gRvi26pdNWW5+/57ETLG3cn5
|
||||||
|
+MDARAttyn8SEhbPolxttebRKDAIFnxYkQ==
|
||||||
|
-----END CERTIFICATE-----
|
52
tests/data/client-rsa.key
Normal file
52
tests/data/client-rsa.key
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
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
|
||||||
|
qnLykaAJSPCsd4jY4P3EtZLNbee3fQ==
|
||||||
|
-----END PRIVATE KEY-----
|
16
tests/data/server-ecc.cert
Normal file
16
tests/data/server-ecc.cert
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICljCCAhygAwIBAgIUcjxQ8y9DFk5UChiI2CTG4fKNuzswCgYIKoZIzj0EAwIw
|
||||||
|
gYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcMCENp
|
||||||
|
dHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFueVNl
|
||||||
|
Y3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5uYXRzLnppZzAgFw0yMzA5MDIyMjEy
|
||||||
|
NDJaGA8yMTIzMDgwOTIyMTI0MlowgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlT
|
||||||
|
dGF0ZU5hbWUxETAPBgNVBAcMCENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFt
|
||||||
|
ZTEbMBkGA1UECwwSQ29tcGFueVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5u
|
||||||
|
YXRzLnppZzB2MBAGByqGSM49AgEGBSuBBAAiA2IABL1QQVL1CUI+g8EAFtW4OYRk
|
||||||
|
bsa4GpLMojjWYGZ5azB6zFJsjqr626hwl8B+yUOLV8O8COZtSHhh9TOwMK9my+mF
|
||||||
|
jSlRLkBhViJtiQS/i+lOAHLSZhyYGi0LMwR/84s9zqNTMFEwHQYDVR0OBBYEFDep
|
||||||
|
AJQvuHNpqaxaBt5Md4mAcMcBMB8GA1UdIwQYMBaAFDepAJQvuHNpqaxaBt5Md4mA
|
||||||
|
cMcBMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDaAAwZQIwWiMIHiOwfO0+
|
||||||
|
CcjrMZmSVqhBiDY8bcJgpPFCp+GFfPiTwse1eUQhYE0K2onU1mYTAjEA7atUdQxL
|
||||||
|
8SjkuTRdvNoRJ2EOVMHMeaYMU5HPAxHhIPDWBaHmHOHgOx5hUw/chRjf
|
||||||
|
-----END CERTIFICATE-----
|
6
tests/data/server-ecc.key
Normal file
6
tests/data/server-ecc.key
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAdXFWFvY4ujDsDxw2e
|
||||||
|
Vga7jpgVBKAg7mEA/AYL+yjLanR52DJ6XM8iU4qbPEaMH66hZANiAAS9UEFS9QlC
|
||||||
|
PoPBABbVuDmEZG7GuBqSzKI41mBmeWswesxSbI6q+tuocJfAfslDi1fDvAjmbUh4
|
||||||
|
YfUzsDCvZsvphY0pUS5AYVYibYkEv4vpTgBy0mYcmBotCzMEf/OLPc4=
|
||||||
|
-----END PRIVATE KEY-----
|
34
tests/data/server-rsa.cert
Normal file
34
tests/data/server-rsa.cert
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIF5TCCA82gAwIBAgIUUIWzfooDSLVR8sW3AiBJuqDHZMYwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcM
|
||||||
|
CENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFu
|
||||||
|
eVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5uYXRzLnppZzAgFw0yMzA5MDIy
|
||||||
|
MjA5MTdaGA8yMTIzMDgwOTIyMDkxN1owgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQI
|
||||||
|
DAlTdGF0ZU5hbWUxETAPBgNVBAcMCENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55
|
||||||
|
TmFtZTEbMBkGA1UECwwSQ29tcGFueVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0
|
||||||
|
cy5uYXRzLnppZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOolz+6A
|
||||||
|
j1S3fJl8VSglQBaOplTsukup0Li7pDluS+Sgj5G5Vvl1Ki8jPVTWz9HcYl/7jgFz
|
||||||
|
iE7AG7qymH1+q/smzxl59MyiKkBPSvynRQ/iY35uyyCFSxgqNSFqnahzHmd1BpNX
|
||||||
|
9WJX2iRs+UyaWjhtj7T2cbIr2UZQtCUqF/ae0jeR+hb6beQCMoGzFG3Zn9uupazg
|
||||||
|
u49WdNmOSE/qf6DAmftnmdX7pc7u6jclMAk8WOvjL9LoxK8Nu+ZGusklJohjbUsG
|
||||||
|
DNdktsaqZQphlXbVCa6gV6cITup2oFmHQvMcncZ2xtYs/4Ul45UxGGEWGWQLQtaJ
|
||||||
|
KSS5B5YAkXTCga8k/cS+NRyy/NxQmuR3FeQUYYfMpiNhXweZ7zEWjosU9jjEiS6w
|
||||||
|
UhlTCQYH6p9/jZmByE8DySNQtcexV1IBVzOYsg7MS/AwHq9ym9iqT9tx+S9Vub/f
|
||||||
|
ysbgQU9GkKeic64iYVC+gG/Y2W8XS9LSzSKCJuvf8EUD18g3dmmRxzltwq7oH14W
|
||||||
|
f0KjyhwdzeJUhoEvPgaEgWvlvff9uSP0utX/KmOJPJckjoQrk9RN/GDxR01U2SPf
|
||||||
|
1pVclir3IEWSPOCNSil8Et/ut1MI7JGlDhsysZA3zoqIPAu+QYVUEytdSf+n3UHf
|
||||||
|
ZvT7VdDQlNyq2XYaP9kBEx4P7oGfto/HHOHtAgMBAAGjUzBRMB0GA1UdDgQWBBQV
|
||||||
|
GBaOUXiHmG3KT2uiwgOR7xBDSDAfBgNVHSMEGDAWgBQVGBaOUXiHmG3KT2uiwgOR
|
||||||
|
7xBDSDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCZhqnD3uVi
|
||||||
|
3q2plOHUBnlkYcCCoC0W7AHPSJ1pcb/wa1CgSkrXHNhBmaWfWEbs+JJ+eMHxStFr
|
||||||
|
kdJWNbVEnmS27ruMNE6S5XCj/1zdqncZnCr3gLRdmvb3S5yZHGphgEdNrAvPKIyi
|
||||||
|
XtfmROVh3y2/ZENRZfdJ984xU/yaHmfTy8ULiSCe0Jz9dxHvTgUCrZ5RVEIwmAkL
|
||||||
|
gcs1Hrw/5TDs/DagsNliH2Atn6cYzhAostBN9wDkra6xUkRqscE8R7D2/XJni+W3
|
||||||
|
toL+DTTFIww0pNlh2BWG5DMqeLdYPODhuxWWw5JhdKWx3cisPhiJ9RDKaSy532wC
|
||||||
|
i/tjKQAnNWQRvGFGfJDMIEcPL3s1JhQM/lhSanlloMsxHmGpOJOEI6IN0clYpPaX
|
||||||
|
7COo+qvGueQPRLDq/7vDRM3i7sQHBHeC71VdEN4TgyJQvQcGMFjGPPQ868VvJhYG
|
||||||
|
2CbUWhBaADWlWjZ5d5tMI+WT8J/y6D6cSOymXcgbHV8DpUCB9vImmTKvgiL9TLi1
|
||||||
|
PxZCP9nLUOCmCSnbz4vhupvxM38KesuvAfOUPKTEixjXBfD9iiEKVnMUKVv31TLO
|
||||||
|
5sfeYf6Zn8oDFCInUgdHgQRs/UXOAOTWYsOQQhS6xfZXJHom/Mcy0Q2TxsiI2dmw
|
||||||
|
ah/FB4DsF0XDCuDqGJWyywTbzQnh55uBBQ==
|
||||||
|
-----END CERTIFICATE-----
|
52
tests/data/server-rsa.key
Normal file
52
tests/data/server-rsa.key
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
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
|
||||||
|
u2Iow+n+vuh3lPHBmdmCxfYo50P+HA==
|
||||||
|
-----END PRIVATE KEY-----
|
@ -1,3 +1,6 @@
|
|||||||
|
// This file is licensed under the CC0 1.0 license.
|
||||||
|
// See: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
||||||
|
|
||||||
test {
|
test {
|
||||||
_ = @import("./nats.zig");
|
_ = @import("./nats.zig");
|
||||||
_ = @import("./connection.zig");
|
_ = @import("./connection.zig");
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
// This file is licensed under the CC0 1.0 license.
|
||||||
|
// See: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const nats = @import("nats");
|
const nats = @import("nats");
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
// This file is licensed under the CC0 1.0 license.
|
||||||
|
// See: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const nats = @import("nats");
|
const nats = @import("nats");
|
||||||
@ -67,7 +70,7 @@ test "misc" {
|
|||||||
// and switch.
|
// and switch.
|
||||||
const signed = nats.sign("12345678", "12345678") catch {
|
const signed = nats.sign("12345678", "12345678") catch {
|
||||||
const err = nats.getLastError();
|
const err = nats.getLastError();
|
||||||
std.debug.print("signing failed: {s}\n", .{err.desc});
|
std.debug.print("as expected, signing failed: {s}\n", .{err.desc});
|
||||||
|
|
||||||
var stackmem = [_]u8{0} ** 512;
|
var stackmem = [_]u8{0} ** 512;
|
||||||
var stackbuf: []u8 = &stackmem;
|
var stackbuf: []u8 = &stackmem;
|
||||||
|
@ -1,11 +1,26 @@
|
|||||||
|
// This file is licensed under the CC0 1.0 license.
|
||||||
|
// See: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
const KeyCert = struct { key: [:0]const u8, cert: [:0]const u8 };
|
||||||
|
const server_rsa: KeyCert = .{
|
||||||
|
.key = @embedFile("./data/server-rsa.key"),
|
||||||
|
.cert = @embedFile("./data/server-rsa.cert"),
|
||||||
|
};
|
||||||
|
|
||||||
|
const server_ecc: KeyCert = .{
|
||||||
|
.key = @embedFile("./data/server-ecc.key"),
|
||||||
|
.cert = @embedFile("./data/server-ecc.cert"),
|
||||||
|
};
|
||||||
|
|
||||||
const TestLaunchError = error{
|
const TestLaunchError = error{
|
||||||
NoLaunchStringFound,
|
NoLaunchStringFound,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const TestServer = struct {
|
pub const TestServer = struct {
|
||||||
process: std.ChildProcess,
|
process: std.ChildProcess,
|
||||||
|
key_dir: ?std.testing.TmpDir,
|
||||||
|
|
||||||
pub const LaunchOptions = struct {
|
pub const LaunchOptions = struct {
|
||||||
executable: []const u8 = "nats-server",
|
executable: []const u8 = "nats-server",
|
||||||
@ -15,38 +30,71 @@ pub const TestServer = struct {
|
|||||||
token: []const u8,
|
token: []const u8,
|
||||||
password: struct { user: []const u8, pass: []const u8 },
|
password: struct { user: []const u8, pass: []const u8 },
|
||||||
} = .none,
|
} = .none,
|
||||||
|
tls: enum {
|
||||||
|
none,
|
||||||
|
rsa,
|
||||||
|
ecc,
|
||||||
|
} = .none,
|
||||||
allocator: std.mem.Allocator = std.testing.allocator,
|
allocator: std.mem.Allocator = std.testing.allocator,
|
||||||
|
|
||||||
fn argLen(self: LaunchOptions) usize {
|
|
||||||
// executable, -a, 127.0.0.1, -p, 4222
|
|
||||||
const base_len: usize = 5;
|
|
||||||
return base_len + switch (self.auth) {
|
|
||||||
.none => @as(usize, 0),
|
|
||||||
.token => @as(usize, 2),
|
|
||||||
.password => @as(usize, 4),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn launch(options: LaunchOptions) !TestServer {
|
pub fn launch(options: LaunchOptions) !TestServer {
|
||||||
// const allocator = std.testing.allocator;
|
|
||||||
var portbuf = [_]u8{0} ** 5;
|
var portbuf = [_]u8{0} ** 5;
|
||||||
const strport = try std.fmt.bufPrint(&portbuf, "{d}", .{options.port});
|
const strport = try std.fmt.bufPrint(&portbuf, "{d}", .{options.port});
|
||||||
|
|
||||||
const argsbuf: [9][]const u8 = blk: {
|
var key_dir: ?std.testing.TmpDir = null;
|
||||||
const executable: [1][]const u8 = .{options.executable};
|
var key_path: ?[]const u8 = null;
|
||||||
const listen: [2][]const u8 = .{ "-a", "127.0.0.1" };
|
var cert_path: ?[]const u8 = null;
|
||||||
const port: [2][]const u8 = .{ "-p", strport };
|
// ChildProcess copies these, so we can free them before the process has
|
||||||
const auth: [4][]const u8 = switch (options.auth) {
|
// closed.
|
||||||
.none => .{""} ** 4,
|
defer {
|
||||||
.token => |tok| .{ "--auth", tok, "", "" },
|
if (key_path) |kp| options.allocator.free(kp);
|
||||||
.password => |auth| .{ "--user", auth.user, "--pass", auth.pass },
|
if (cert_path) |cp| options.allocator.free(cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
const args: [][]const u8 = blk: {
|
||||||
|
const executable: []const []const u8 = &.{options.executable};
|
||||||
|
const listen: []const []const u8 = &.{ "-a", "127.0.0.1" };
|
||||||
|
const port: []const []const u8 = &.{ "-p", strport };
|
||||||
|
const auth: []const []const u8 = switch (options.auth) {
|
||||||
|
.none => &[_][]const u8{},
|
||||||
|
.token => |tok| &[_][]const u8{ "--auth", tok },
|
||||||
|
.password => |auth| &[_][]const u8{ "--user", auth.user, "--pass", auth.pass },
|
||||||
|
};
|
||||||
|
const tls: []const []const u8 = switch (options.tls) {
|
||||||
|
.none => &[_][]const u8{},
|
||||||
|
.rsa, .ecc => |keytype| keyb: {
|
||||||
|
const pair = switch (keytype) {
|
||||||
|
.rsa => server_rsa,
|
||||||
|
.ecc => server_ecc,
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
|
||||||
|
const out_dir = std.testing.tmpDir(.{});
|
||||||
|
try out_dir.dir.writeFile("server.key", pair.key);
|
||||||
|
try out_dir.dir.writeFile("server.cert", pair.cert);
|
||||||
|
// since testing.tmpDir will actually bury itself in zig-cache/tmp,
|
||||||
|
// there's not an easy way to extract files from within the temp
|
||||||
|
// directory except through using realPath, as far as I can tell
|
||||||
|
// (or reproducing the path naming logic, but that seems fragile).
|
||||||
|
const out_key = try out_dir.dir.realpathAlloc(options.allocator, "server.key");
|
||||||
|
const out_cert = try out_dir.dir.realpathAlloc(options.allocator, "server.cert");
|
||||||
|
|
||||||
|
key_dir = out_dir;
|
||||||
|
key_path = out_key;
|
||||||
|
cert_path = out_cert;
|
||||||
|
break :keyb &[_][]const u8{ "--tls", "--tlscert", out_cert, "--tlskey", out_key };
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
break :blk executable ++ listen ++ port ++ auth;
|
break :blk try std.mem.concat(
|
||||||
|
options.allocator,
|
||||||
|
[]const u8,
|
||||||
|
&.{ executable, listen, port, auth, tls },
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const args = argsbuf[0..options.argLen()];
|
defer options.allocator.free(args);
|
||||||
|
|
||||||
var child = std.ChildProcess.init(args, options.allocator);
|
var child = std.ChildProcess.init(args, options.allocator);
|
||||||
child.stdin_behavior = .Ignore;
|
child.stdin_behavior = .Ignore;
|
||||||
@ -59,7 +107,7 @@ pub const TestServer = struct {
|
|||||||
|
|
||||||
while (try poller.poll()) {
|
while (try poller.poll()) {
|
||||||
if (std.mem.indexOf(u8, poller.fifo(.stderr).buf, "[INF] Server is ready")) |_| {
|
if (std.mem.indexOf(u8, poller.fifo(.stderr).buf, "[INF] Server is ready")) |_| {
|
||||||
return .{ .process = child };
|
return .{ .process = child, .key_dir = key_dir };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +117,7 @@ pub const TestServer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop(self: *TestServer) void {
|
pub fn stop(self: *TestServer) void {
|
||||||
|
if (self.key_dir) |*key_dir| key_dir.cleanup();
|
||||||
_ = self.process.kill() catch return;
|
_ = self.process.kill() catch return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user