mirror of
https://github.com/ziglang/zig.git
synced 2025-12-10 08:13:07 +00:00
* Delete `std.net.TmpWinAddr`. I don't think that was ever meant to be a real thing. * Delete `std.net.OsAddress`. This abstraction was not helpful. * Rename `std.net.Address` to `std.net.IpAddress`. It is now an extern union of IPv4 and IPv6 addresses. * Move `std.net.parseIp4` and `std.net.parseIp6` to the `std.net.IpAddress` namespace. They now return `IpAddress` instead of `u32` and `std.net.Ip6Addr`, which is deleted. * Add `std.net.IpAddress.parse` which accepts a port and parses either an IPv4 or IPv6 address. * Add `std.net.IpAddress.parseExpectingFamily` which additionally accepts a `family` parameter. * `std.net.IpAddress.initIp4` and `std.net.IpAddress.initIp6` are improved to directly take the address fields instead of a weird in-between type. * `std.net.IpAddress.port` is renamed to `std.net.IpAddress.getPort`. * Added `std.net.IpAddress.setPort`. * `os.sockaddr` struct on all targets is improved to match the corresponding system struct. Previously I had made it a union of sockaddr_in, sockaddr_in6, and sockaddr_un. The new abstraction for this is now `std.net.IpAddress`. * `os.sockaddr` and related bits are added for Windows. * `os.sockaddr` and related bits now have the `zero` fields default to zero initialization, and `len` fields default to the correct size. This is enough to abstract the differences across targets, and so no more switch on the target OS is needed in `std.net.IpAddress`. * Add the missing `os.sockaddr_un` on FreeBSD and NetBSD. * `std.net.IpAddress.initPosix` now takes a pointer to `os.sockaddr`.
92 lines
3.1 KiB
Zig
92 lines
3.1 KiB
Zig
const std = @import("../std.zig");
|
|
const net = std.net;
|
|
const mem = std.mem;
|
|
const testing = std.testing;
|
|
|
|
test "parse and render IPv6 addresses" {
|
|
const addr = net.IpAddress.parseIp6("FF01:0:0:0:0:0:0:FB", 80);
|
|
var buf: [100]u8 = undefined;
|
|
const printed = try std.fmt.bufPrint(&buf, "{}", addr);
|
|
std.testing.expect(mem.eql(u8, "[ff01::fb]:80", printed));
|
|
}
|
|
|
|
test "parse and render IPv4 addresses" {
|
|
var buffer: [18]u8 = undefined;
|
|
for ([_][]const u8{
|
|
"0.0.0.0",
|
|
"255.255.255.255",
|
|
"1.2.3.4",
|
|
"123.255.0.91",
|
|
"127.0.0.1",
|
|
}) |ip| {
|
|
var addr = net.IpAddress.parseIp4(ip, 0);
|
|
var newIp = std.fmt.bufPrint(buffer[0..], "{}", addr) catch unreachable;
|
|
std.testing.expect(std.mem.eql(u8, ip, newIp[0 .. newIp.len - 2]));
|
|
}
|
|
|
|
testing.expectError(error.Overflow, net.IpAddress.parseIp4("256.0.0.1", 0));
|
|
testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp4("x.0.0.1", 0));
|
|
testing.expectError(error.InvalidEnd, net.IpAddress.parseIp4("127.0.0.1.1", 0));
|
|
testing.expectError(error.Incomplete, net.IpAddress.parseIp4("127.0.0.", 0));
|
|
testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp4("100..0.1", 0));
|
|
}
|
|
|
|
test "resolve DNS" {
|
|
if (std.builtin.os == .windows) {
|
|
// DNS resolution not implemented on Windows yet.
|
|
return error.SkipZigTest;
|
|
}
|
|
var buf: [1000 * 10]u8 = undefined;
|
|
const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
|
|
|
|
const address_list = net.getAddressList(a, "example.com", 80) catch |err| switch (err) {
|
|
// The tests are required to work even when there is no Internet connection,
|
|
// so some of these errors we must accept and skip the test.
|
|
error.UnknownHostName => return error.SkipZigTest,
|
|
error.TemporaryNameServerFailure => return error.SkipZigTest,
|
|
else => return err,
|
|
};
|
|
address_list.deinit();
|
|
}
|
|
|
|
test "listen on a port, send bytes, receive bytes" {
|
|
if (std.builtin.os != .linux) {
|
|
// TODO build abstractions for other operating systems
|
|
return error.SkipZigTest;
|
|
}
|
|
if (std.io.mode != .evented) {
|
|
// TODO add ability to run tests in non-blocking I/O mode
|
|
return error.SkipZigTest;
|
|
}
|
|
|
|
// TODO doing this at comptime crashed the compiler
|
|
const localhost = net.IpAddress.parse("127.0.0.1", 0);
|
|
|
|
var server = net.TcpServer.init(net.TcpServer.Options{});
|
|
defer server.deinit();
|
|
try server.listen(localhost);
|
|
|
|
var server_frame = async testServer(&server);
|
|
var client_frame = async testClient(server.listen_address);
|
|
|
|
try await server_frame;
|
|
try await client_frame;
|
|
}
|
|
|
|
fn testClient(addr: net.IpAddress) anyerror!void {
|
|
const socket_file = try net.tcpConnectToAddress(addr);
|
|
defer socket_file.close();
|
|
|
|
var buf: [100]u8 = undefined;
|
|
const len = try socket_file.read(&buf);
|
|
const msg = buf[0..len];
|
|
testing.expect(mem.eql(u8, msg, "hello from server\n"));
|
|
}
|
|
|
|
fn testServer(server: *net.TcpServer) anyerror!void {
|
|
var client_file = try server.accept();
|
|
|
|
const stream = &client_file.outStream().stream;
|
|
try stream.print("hello from server\n");
|
|
}
|