Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor TLS, add TLS server #19308

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions lib/compiler/fmt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,9 @@ fn fmtPathFile(
return;

if (check_mode) {
const stdout = std.io.getStdOut().writer();
try stdout.print("{s}\n", .{file_path});
const stdout = std.io.getStdOut();
try stdout.writeAll(file_path);
try stdout.writeAll("\n");
fmt.any_error = true;
} else {
var af = try dir.atomicFile(sub_path, .{ .mode = stat.mode });
Expand Down
5 changes: 5 additions & 0 deletions lib/std/Uri.zig
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,11 @@ test "basic" {
try testing.expectEqual(@as(?u16, null), parsed.port);
}

test "subdomain" {
const parsed = try parse("http://a.b.example.com");
try testing.expectEqualStrings("a.b.example.com", parsed.host orelse return error.UnexpectedNull);
}

test "with port" {
const parsed = try parse("http://example:1337/");
try testing.expectEqualStrings("http", parsed.scheme);
Expand Down
45 changes: 29 additions & 16 deletions lib/std/array_list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
@compileError("The Writer interface is only defined for ArrayList(u8) " ++
"but the given type is ArrayList(" ++ @typeName(T) ++ ")")
else
std.io.Writer(*Self, Allocator.Error, appendWrite);
std.io.Writer(*Self, Allocator.Error, appendWritev);

/// Initializes a Writer which will append to the list.
pub fn writer(self: *Self) Writer {
Expand All @@ -354,9 +354,13 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
/// Same as `append` except it returns the number of bytes written, which is always the same
/// as `m.len`. The purpose of this function existing is to match `std.io.Writer` API.
/// Invalidates element pointers if additional memory is needed.
fn appendWrite(self: *Self, m: []const u8) Allocator.Error!usize {
try self.appendSlice(m);
return m.len;
fn appendWritev(self: *Self, iov: []const std.os.iovec_const) Allocator.Error!usize {
var written: usize = 0;
for (iov) |v| {
try self.appendSlice(v.iov_base[0..v.iov_len]);
written += v.iov_len;
}
return written;
}

/// Append a value to the list `n` times.
Expand Down Expand Up @@ -930,7 +934,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
@compileError("The Writer interface is only defined for ArrayList(u8) " ++
"but the given type is ArrayList(" ++ @typeName(T) ++ ")")
else
std.io.Writer(WriterContext, Allocator.Error, appendWrite);
std.io.Writer(WriterContext, Allocator.Error, appendWritev);

/// Initializes a Writer which will append to the list.
pub fn writer(self: *Self, allocator: Allocator) Writer {
Expand All @@ -941,12 +945,16 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
/// which is always the same as `m.len`. The purpose of this function
/// existing is to match `std.io.Writer` API.
/// Invalidates element pointers if additional memory is needed.
fn appendWrite(context: WriterContext, m: []const u8) Allocator.Error!usize {
try context.self.appendSlice(context.allocator, m);
return m.len;
fn appendWritev(context: WriterContext, iov: []const std.os.iovec_const) Allocator.Error!usize {
var written: usize = 0;
for (iov) |v| {
try context.self.appendSlice(context.allocator, v.iov_base[0..v.iov_len]);
written += v.iov_len;
}
return written;
}

pub const FixedWriter = std.io.Writer(*Self, Allocator.Error, appendWriteFixed);
pub const FixedWriter = std.io.Writer(*Self, Allocator.Error, appendWritevFixed);

/// Initializes a Writer which will append to the list but will return
/// `error.OutOfMemory` rather than increasing capacity.
Expand All @@ -955,13 +963,18 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
}

/// The purpose of this function existing is to match `std.io.Writer` API.
fn appendWriteFixed(self: *Self, m: []const u8) error{OutOfMemory}!usize {
const available_capacity = self.capacity - self.items.len;
if (m.len > available_capacity)
return error.OutOfMemory;

self.appendSliceAssumeCapacity(m);
return m.len;
fn appendWritevFixed(self: *Self, iov: []const std.os.iovec_const) error{OutOfMemory}!usize {
var written: usize = 0;
for (iov) |v| {
const m = v.iov_base[0..v.iov_len];
const available_capacity = self.capacity - self.items.len;
if (m.len > available_capacity)
return error.OutOfMemory;

self.appendSliceAssumeCapacity(m);
written += m.len;
}
return written;
}

/// Append a value to the list `n` times.
Expand Down
13 changes: 9 additions & 4 deletions lib/std/bounded_array.zig
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ pub fn BoundedArrayAligned(
@compileError("The Writer interface is only defined for BoundedArray(u8, ...) " ++
"but the given type is BoundedArray(" ++ @typeName(T) ++ ", ...)")
else
std.io.Writer(*Self, error{Overflow}, appendWrite);
std.io.Writer(*Self, error{Overflow}, appendWritev);

/// Initializes a writer which will write into the array.
pub fn writer(self: *Self) Writer {
Expand All @@ -280,9 +280,14 @@ pub fn BoundedArrayAligned(

/// Same as `appendSlice` except it returns the number of bytes written, which is always the same
/// as `m.len`. The purpose of this function existing is to match `std.io.Writer` API.
fn appendWrite(self: *Self, m: []const u8) error{Overflow}!usize {
try self.appendSlice(m);
return m.len;
fn appendWritev(self: *Self, iov: []const std.os.iovec_const) error{Overflow}!usize {
var written: usize = 0;
for (iov) |v| {
const m = v.iov_base[0..v.iov_len];
try self.appendSlice(m);
written += m.len;
}
return written;
}
};
}
Expand Down
32 changes: 22 additions & 10 deletions lib/std/compress.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,18 @@ pub fn HashedReader(
hasher: HasherType,

pub const Error = ReaderType.Error;
pub const Reader = std.io.Reader(*@This(), Error, read);
pub const Reader = std.io.Reader(*@This(), Error, readv);

pub fn read(self: *@This(), buf: []u8) Error!usize {
const amt = try self.child_reader.read(buf);
self.hasher.update(buf[0..amt]);
return amt;
pub fn readv(self: *@This(), iov: []const std.os.iovec) Error!usize {
const n_read = try self.child_reader.readv(iov);
var hashed_amt: usize = 0;
for (iov) |v| {
const to_hash = @min(n_read - hashed_amt, v.iov_len);
if (to_hash == 0) break;
self.hasher.update(v.iov_base[0..to_hash]);
hashed_amt += to_hash;
}
return n_read;
}

pub fn reader(self: *@This()) Reader {
Expand All @@ -49,12 +55,18 @@ pub fn HashedWriter(
hasher: HasherType,

pub const Error = WriterType.Error;
pub const Writer = std.io.Writer(*@This(), Error, write);
pub const Writer = std.io.Writer(*@This(), Error, writev);

pub fn write(self: *@This(), buf: []const u8) Error!usize {
const amt = try self.child_writer.write(buf);
self.hasher.update(buf[0..amt]);
return amt;
pub fn writev(self: *@This(), iov: []const std.os.iovec_const) Error!usize {
const n_written = try self.child_writer.writev(iov);
var hashed_amt: usize = 0;
for (iov) |v| {
const to_hash = @min(n_written - hashed_amt, v.iov_len);
if (to_hash == 0) break;
self.hasher.update(v.iov_base[0..to_hash]);
hashed_amt += to_hash;
}
return n_written;
}

pub fn writer(self: *@This()) Writer {
Expand Down
20 changes: 13 additions & 7 deletions lib/std/compress/flate/deflate.zig
Original file line number Diff line number Diff line change
Expand Up @@ -354,16 +354,20 @@ fn Deflate(comptime container: Container, comptime WriterType: type, comptime Bl
}

// Writer interface

pub const Writer = io.Writer(*Self, Error, write);
pub const Writer = io.Writer(*Self, Error, writev);
pub const Error = BlockWriterType.Error;

/// Write `input` of uncompressed data.
/// See compress.
pub fn write(self: *Self, input: []const u8) !usize {
var fbs = io.fixedBufferStream(input);
try self.compress(fbs.reader());
return input.len;
pub fn writev(self: *Self, iov: []const std.os.iovec_const) !usize {
var written: usize = 0;
for (iov) |v| {
const input = v.iov_base[0..v.iov_len];
var fbs = io.fixedBufferStream(input);
try self.compress(fbs.reader());
written += input.len;
}
return written;
}

pub fn writer(self: *Self) Writer {
Expand Down Expand Up @@ -558,7 +562,7 @@ test "tokenization" {
const cww = cw.writer();
var df = try Deflate(container, @TypeOf(cww), TestTokenWriter).init(cww, .{});

_ = try df.write(c.data);
_ = try df.writer().write(c.data);
try df.flush();

// df.token_writer.show();
Expand All @@ -579,6 +583,8 @@ const TestTokenWriter = struct {
pos: usize = 0,
actual: [128]Token = undefined,

pub const Error = error{};

pub fn init(_: anytype) Self {
return .{};
}
Expand Down
17 changes: 10 additions & 7 deletions lib/std/compress/flate/inflate.zig
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ pub fn Inflate(comptime container: Container, comptime LookaheadType: type, comp
/// Returns decompressed data from internal sliding window buffer.
/// Returned buffer can be any length between 0 and `limit` bytes. 0
/// returned bytes means end of stream reached. With limit=0 returns as
/// much data it can. It newer will be more than 65536 bytes, which is
/// much data it can. It never will be more than 65536 bytes, which is
/// size of internal buffer.
pub fn get(self: *Self, limit: usize) Error![]const u8 {
while (true) {
Expand All @@ -340,16 +340,19 @@ pub fn Inflate(comptime container: Container, comptime LookaheadType: type, comp
}

// Reader interface

pub const Reader = std.io.Reader(*Self, Error, read);
pub const Reader = std.io.Reader(*Self, Error, readv);

/// Returns the number of bytes read. It may be less than buffer.len.
/// If the number of bytes read is 0, it means end of stream.
/// End of stream is not an error condition.
pub fn read(self: *Self, buffer: []u8) Error!usize {
const out = try self.get(buffer.len);
@memcpy(buffer[0..out.len], out);
return out.len;
pub fn readv(self: *Self, iov: []const std.os.iovec) Error!usize {
var read: usize = 0;
for (iov) |v| {
const out = try self.get(v.iov_len);
@memcpy(v.iov_base[0..out.len], out);
read += out.len;
}
return read;
}

pub fn reader(self: *Self) Reader {
Expand Down
35 changes: 20 additions & 15 deletions lib/std/compress/lzma.zig
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn Decompress(comptime ReaderType: type) type {
Allocator.Error ||
error{ CorruptInput, EndOfStream, Overflow };

pub const Reader = std.io.Reader(*Self, Error, read);
pub const Reader = std.io.Reader(*Self, Error, readv);

allocator: Allocator,
in_reader: ReaderType,
Expand Down Expand Up @@ -63,23 +63,28 @@ pub fn Decompress(comptime ReaderType: type) type {
self.* = undefined;
}

pub fn read(self: *Self, output: []u8) Error!usize {
pub fn readv(self: *Self, iov: []const std.os.iovec) Error!usize {
const writer = self.to_read.writer(self.allocator);
while (self.to_read.items.len < output.len) {
switch (try self.state.process(self.allocator, self.in_reader, writer, &self.buffer, &self.decoder)) {
.continue_ => {},
.finished => {
try self.buffer.finish(writer);
break;
},
var n_read: usize = 0;
for (iov) |v| {
const output = v.iov_base[0..v.iov_len];
while (self.to_read.items.len < output.len) {
switch (try self.state.process(self.allocator, self.in_reader, writer, &self.buffer, &self.decoder)) {
.continue_ => {},
.finished => {
try self.buffer.finish(writer);
break;
},
}
}
const input = self.to_read.items;
const n = @min(input.len, output.len);
@memcpy(output[0..n], input[0..n]);
@memcpy(input[0 .. input.len - n], input[n..]);
self.to_read.shrinkRetainingCapacity(input.len - n);
n_read += n;
}
const input = self.to_read.items;
const n = @min(input.len, output.len);
@memcpy(output[0..n], input[0..n]);
@memcpy(input[0 .. input.len - n], input[n..]);
self.to_read.shrinkRetainingCapacity(input.len - n);
return n;
return n_read;
}
};
}
Expand Down
6 changes: 4 additions & 2 deletions lib/std/compress/xz.zig
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub fn Decompress(comptime ReaderType: type) type {
const Self = @This();

pub const Error = ReaderType.Error || block.Decoder(ReaderType).Error;
pub const Reader = std.io.Reader(*Self, Error, read);
pub const Reader = std.io.Reader(*Self, Error, readv);

allocator: Allocator,
block_decoder: block.Decoder(ReaderType),
Expand Down Expand Up @@ -71,7 +71,9 @@ pub fn Decompress(comptime ReaderType: type) type {
return .{ .context = self };
}

pub fn read(self: *Self, buffer: []u8) Error!usize {
pub fn readv(self: *Self, iov: []const std.os.iovec) Error!usize {
const first = iov[0];
const buffer = first.iov_base[0..first.iov_len];
if (buffer.len == 0)
return 0;

Expand Down
6 changes: 4 additions & 2 deletions lib/std/compress/zstandard.zig
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub fn Decompressor(comptime ReaderType: type) type {
OutOfMemory,
};

pub const Reader = std.io.Reader(*Self, Error, read);
pub const Reader = std.io.Reader(*Self, Error, readv);

pub fn init(source: ReaderType, options: DecompressorOptions) Self {
return .{
Expand Down Expand Up @@ -105,7 +105,9 @@ pub fn Decompressor(comptime ReaderType: type) type {
return .{ .context = self };
}

pub fn read(self: *Self, buffer: []u8) Error!usize {
pub fn readv(self: *Self, iov: []const std.os.iovec) Error!usize {
const first = iov[0];
const buffer = first.iov_base[0..first.iov_len];
if (buffer.len == 0) return 0;

var size: usize = 0;
Expand Down
7 changes: 5 additions & 2 deletions lib/std/compress/zstandard/readers.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub const ReversedByteReader = struct {
remaining_bytes: usize,
bytes: []const u8,

const Reader = std.io.Reader(*ReversedByteReader, error{}, readFn);
const Reader = std.io.Reader(*ReversedByteReader, error{}, readvFn);

pub fn init(bytes: []const u8) ReversedByteReader {
return .{
Expand All @@ -17,7 +17,10 @@ pub const ReversedByteReader = struct {
return .{ .context = self };
}

fn readFn(ctx: *ReversedByteReader, buffer: []u8) !usize {
fn readvFn(ctx: *ReversedByteReader, iov: []const std.os.iovec) !usize {
const first = iov[0];
const buffer = first.iov_base[0..first.iov_len];
std.debug.assert(buffer.len > 0);
if (ctx.remaining_bytes == 0) return 0;
const byte_index = ctx.remaining_bytes - 1;
buffer[0] = ctx.bytes[byte_index];
Expand Down
6 changes: 3 additions & 3 deletions lib/std/crypto/25519/ed25519.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ pub const Ed25519 = struct {
/// Length (in bytes) of optional random bytes, for non-deterministic signatures.
pub const noise_length = 32;

const CompressedScalar = Curve.scalar.CompressedScalar;
const Scalar = Curve.scalar.Scalar;
pub const CompressedScalar = Curve.scalar.CompressedScalar;
pub const Scalar = Curve.scalar.Scalar;

/// An Ed25519 secret key.
pub const SecretKey = struct {
Expand Down Expand Up @@ -73,7 +73,7 @@ pub const Ed25519 = struct {
nonce: CompressedScalar,
r_bytes: [Curve.encoded_length]u8,

fn init(scalar: CompressedScalar, nonce: CompressedScalar, public_key: PublicKey) (IdentityElementError || KeyMismatchError || NonCanonicalError || WeakPublicKeyError)!Signer {
pub fn init(scalar: CompressedScalar, nonce: CompressedScalar, public_key: PublicKey) (IdentityElementError || WeakPublicKeyError)!Signer {
const r = try Curve.basePoint.mul(nonce);
const r_bytes = r.toBytes();

Expand Down
Loading