updates for PR 25592 (std.Io interface) and 25706 (remove Oracle Solaris)
Some checks failed
aws-zig nightly build / build-zig-nightly (push) Failing after 26s
Some checks failed
aws-zig nightly build / build-zig-nightly (push) Failing after 26s
This commit is contained in:
parent
ef74739b9b
commit
3f5d9d9542
10 changed files with 113 additions and 61 deletions
|
|
@ -22,10 +22,6 @@
|
|||
.url = "https://github.com/aws/aws-sdk-go-v2/archive/refs/tags/release-2025-05-05.tar.gz",
|
||||
.hash = "N-V-__8AAKWdeiawujEcrfukQbb8lLAiQIRT0uG5gCcm4b7W",
|
||||
},
|
||||
.zeit = .{
|
||||
.url = "git+https://github.com/rockorager/zeit?ref=zig-0.15#ed2ca60db118414bda2b12df2039e33bad3b0b88",
|
||||
.hash = "zeit-0.6.0-5I6bk0J9AgCVa0nnyL0lNY9Xa9F68hHq-ZarhuXNV-Jb",
|
||||
},
|
||||
.date = .{
|
||||
.path = "lib/date",
|
||||
},
|
||||
|
|
@ -36,5 +32,9 @@
|
|||
.url = "git+https://github.com/travisstaloch/case.git#f8003fe5f93b65f673d10d41323e347225e8cb87",
|
||||
.hash = "case-0.0.1-chGYqx_EAADaGJjmoln5M1iMBDTrMdd8to5wdEVpfXm4",
|
||||
},
|
||||
.zeit = .{
|
||||
.url = "git+https://github.com/elerch/zeit#8190461dc1f892f6370fa9d5cd76690aac0e1c71",
|
||||
.hash = "zeit-0.6.0-5I6bk99-AgDNMIDuw2Zcoe_9QYIpzwZJqeqMpU54egTd",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ pub fn main() anyerror!void {
|
|||
defer arena.deinit();
|
||||
const allocator = arena.allocator();
|
||||
|
||||
var threaded: std.Io.Threaded = .init(allocator);
|
||||
defer threaded.deinit();
|
||||
const io = threaded.io();
|
||||
|
||||
const args = try std.process.argsAlloc(allocator);
|
||||
defer std.process.argsFree(allocator, args);
|
||||
var stdout_writer = std.fs.File.stdout().writer(&.{});
|
||||
|
|
@ -79,7 +83,7 @@ pub fn main() anyerror!void {
|
|||
skip_next = true;
|
||||
continue;
|
||||
}
|
||||
try processFile(arg, output_dir, &manifest);
|
||||
try processFile(io, arg, output_dir, &manifest);
|
||||
files_processed += 1;
|
||||
}
|
||||
if (files_processed == 0) {
|
||||
|
|
@ -93,12 +97,12 @@ pub fn main() anyerror!void {
|
|||
defer cwd.setAsCwd() catch unreachable;
|
||||
|
||||
try m.setAsCwd();
|
||||
try processDirectories(m, output_dir, &root_progress_node);
|
||||
try processDirectories(io, m, output_dir, &root_progress_node);
|
||||
}
|
||||
}
|
||||
|
||||
if (args.len == 0)
|
||||
_ = try generateServices(allocator, ";", std.fs.File.stdin(), stdout);
|
||||
_ = try generateServices(allocator, io, ";", std.fs.File.stdin(), stdout);
|
||||
|
||||
if (verbose) {
|
||||
const output_path = try output_dir.realpathAlloc(allocator, ".");
|
||||
|
|
@ -110,7 +114,7 @@ const OutputManifest = struct {
|
|||
model_dir_hash_digest: [Hasher.hex_multihash_len]u8,
|
||||
output_dir_hash_digest: [Hasher.hex_multihash_len]u8,
|
||||
};
|
||||
fn processDirectories(models_dir: std.fs.Dir, output_dir: std.fs.Dir, parent_progress: *const std.Progress.Node) !void {
|
||||
fn processDirectories(io: std.Io, models_dir: std.fs.Dir, output_dir: std.fs.Dir, parent_progress: *const std.Progress.Node) !void {
|
||||
// Let's get ready to hash!!
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
defer arena.deinit();
|
||||
|
|
@ -154,7 +158,7 @@ fn processDirectories(models_dir: std.fs.Dir, output_dir: std.fs.Dir, parent_pro
|
|||
|
||||
while (try mi.next()) |e| {
|
||||
if ((e.kind == .file or e.kind == .sym_link) and std.mem.endsWith(u8, e.name, ".json")) {
|
||||
try processFile(e.name, output_dir, &manifest.interface);
|
||||
try processFile(io, e.name, output_dir, &manifest.interface);
|
||||
generating_models_progress.completeOne();
|
||||
}
|
||||
}
|
||||
|
|
@ -210,7 +214,7 @@ fn calculateDigests(models_dir: std.fs.Dir, output_dir: std.fs.Dir, thread_pool:
|
|||
},
|
||||
};
|
||||
}
|
||||
fn processFile(file_name: []const u8, output_dir: std.fs.Dir, manifest: *std.Io.Writer) !void {
|
||||
fn processFile(io: std.Io, file_name: []const u8, output_dir: std.fs.Dir, manifest: *std.Io.Writer) !void {
|
||||
// It's probably best to create our own allocator here so we can deint at the end and
|
||||
// toss all allocations related to the services in this file
|
||||
// I can't guarantee we're not leaking something, and at the end of the
|
||||
|
|
@ -237,6 +241,7 @@ fn processFile(file_name: []const u8, output_dir: std.fs.Dir, manifest: *std.Io.
|
|||
|
||||
const service_names = generateServicesForFilePath(
|
||||
allocator,
|
||||
io,
|
||||
";",
|
||||
file_name,
|
||||
writer,
|
||||
|
|
@ -288,13 +293,14 @@ fn zigFmt(allocator: std.mem.Allocator, buffer: [:0]const u8) ![]const u8 {
|
|||
|
||||
fn generateServicesForFilePath(
|
||||
allocator: std.mem.Allocator,
|
||||
io: std.Io,
|
||||
comptime terminator: []const u8,
|
||||
path: []const u8,
|
||||
writer: *std.Io.Writer,
|
||||
) ![][]const u8 {
|
||||
const file = try std.fs.cwd().openFile(path, .{});
|
||||
defer file.close();
|
||||
return try generateServices(allocator, terminator, file, writer);
|
||||
return try generateServices(allocator, io, terminator, file, writer);
|
||||
}
|
||||
|
||||
fn addReference(id: []const u8, map: *std.StringHashMap(u64)) !void {
|
||||
|
|
@ -396,12 +402,13 @@ fn countReferences(
|
|||
|
||||
fn generateServices(
|
||||
allocator: std.mem.Allocator,
|
||||
io: std.Io,
|
||||
comptime _: []const u8,
|
||||
file: std.fs.File,
|
||||
writer: *std.Io.Writer,
|
||||
) ![][]const u8 {
|
||||
var fbuf: [1024]u8 = undefined;
|
||||
var freader = file.reader(&fbuf);
|
||||
var freader = file.reader(io, &fbuf);
|
||||
var reader = &freader.interface;
|
||||
const json = try reader.allocRemaining(allocator, .limited(1024 * 1024 * 1024));
|
||||
defer allocator.free(json);
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
.minimum_zig_version = "0.14.0",
|
||||
.dependencies = .{
|
||||
.zeit = .{
|
||||
.url = "git+https://github.com/rockorager/zeit?ref=zig-0.15#ed2ca60db118414bda2b12df2039e33bad3b0b88",
|
||||
.hash = "zeit-0.6.0-5I6bk0J9AgCVa0nnyL0lNY9Xa9F68hHq-ZarhuXNV-Jb",
|
||||
.url = "git+https://github.com/elerch/zeit#8190461dc1f892f6370fa9d5cd76690aac0e1c71",
|
||||
.hash = "zeit-0.6.0-5I6bk99-AgDNMIDuw2Zcoe_9QYIpzwZJqeqMpU54egTd",
|
||||
},
|
||||
.json = .{
|
||||
.path = "../json",
|
||||
|
|
|
|||
|
|
@ -83,8 +83,10 @@ fn printDateTime(dt: DateTime) void {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn printNowUtc() void {
|
||||
printDateTime(timestampToDateTime(std.time.timestamp()));
|
||||
pub fn printNowUtc(io: std.Io) void {
|
||||
const now = std.Io.Clock.Timestamp.now(io, .awake) catch return;
|
||||
const timestamp = @as(i64, @intCast(@divFloor(now.raw.nanoseconds, std.time.ns_per_s)));
|
||||
printDateTime(timestampToDateTime(timestamp));
|
||||
}
|
||||
|
||||
test "Convert timestamp to datetime" {
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ pub const Services = servicemodel.Services;
|
|||
|
||||
pub const ClientOptions = struct {
|
||||
proxy: ?std.http.Client.Proxy = null,
|
||||
io: std.Io,
|
||||
};
|
||||
pub const Client = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
|
|
@ -123,7 +124,7 @@ pub const Client = struct {
|
|||
pub fn init(allocator: std.mem.Allocator, options: ClientOptions) Self {
|
||||
return Self{
|
||||
.allocator = allocator,
|
||||
.aws_http = awshttp.AwsHttp.init(allocator, options.proxy),
|
||||
.aws_http = awshttp.AwsHttp.init(allocator, options.io, options.proxy),
|
||||
};
|
||||
}
|
||||
pub fn deinit(self: *Client) void {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ pub const Options = struct {
|
|||
|
||||
pub var static_credentials: ?auth.Credentials = null;
|
||||
|
||||
pub fn getCredentials(allocator: std.mem.Allocator, options: Options) !auth.Credentials {
|
||||
pub fn getCredentials(allocator: std.mem.Allocator, io: std.Io, options: Options) !auth.Credentials {
|
||||
if (static_credentials) |c| return c;
|
||||
if (try getEnvironmentCredentials(allocator)) |cred| {
|
||||
log.debug("Found credentials in environment. Access key: {s}", .{cred.access_key});
|
||||
|
|
@ -87,11 +87,11 @@ pub fn getCredentials(allocator: std.mem.Allocator, options: Options) !auth.Cred
|
|||
// GetWebIdentity is not currently implemented. The rest are tested and gtg
|
||||
// Note: Lambda just sets environment variables
|
||||
if (try getWebIdentityToken(allocator)) |cred| return cred;
|
||||
if (try getProfileCredentials(allocator, options.profile)) |cred| return cred;
|
||||
if (try getProfileCredentials(allocator, io, options.profile)) |cred| return cred;
|
||||
|
||||
if (try getContainerCredentials(allocator)) |cred| return cred;
|
||||
if (try getContainerCredentials(allocator, io)) |cred| return cred;
|
||||
// I don't think we need v1 at all?
|
||||
if (try getImdsv2Credentials(allocator)) |cred| return cred;
|
||||
if (try getImdsv2Credentials(allocator, io)) |cred| return cred;
|
||||
return error.CredentialsNotFound;
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ fn getWebIdentityToken(allocator: std.mem.Allocator) !?auth.Credentials {
|
|||
// TODO: implement
|
||||
return null;
|
||||
}
|
||||
fn getContainerCredentials(allocator: std.mem.Allocator) !?auth.Credentials {
|
||||
fn getContainerCredentials(allocator: std.mem.Allocator, io: std.Io) !?auth.Credentials {
|
||||
// A note on testing: The best way I have found to test this process is
|
||||
// the following. Setup an ECS Fargate cluster and create a task definition
|
||||
// with the command ["/bin/bash","-c","while true; do sleep 10; done"].
|
||||
|
|
@ -171,7 +171,7 @@ fn getContainerCredentials(allocator: std.mem.Allocator) !?auth.Credentials {
|
|||
const container_uri = try std.fmt.allocPrint(allocator, "http://169.254.170.2{s}", .{container_relative_uri});
|
||||
defer allocator.free(container_uri);
|
||||
|
||||
var cl = std.http.Client{ .allocator = allocator };
|
||||
var cl = std.http.Client{ .allocator = allocator, .io = io };
|
||||
defer cl.deinit(); // I don't belive connection pooling would help much here as it's non-ssl and local
|
||||
var aw: std.Io.Writer.Allocating = .init(allocator);
|
||||
defer aw.deinit();
|
||||
|
|
@ -218,10 +218,10 @@ fn getContainerCredentials(allocator: std.mem.Allocator) !?auth.Credentials {
|
|||
);
|
||||
}
|
||||
|
||||
fn getImdsv2Credentials(allocator: std.mem.Allocator) !?auth.Credentials {
|
||||
fn getImdsv2Credentials(allocator: std.mem.Allocator, io: std.Io) !?auth.Credentials {
|
||||
var token: ?[]u8 = null;
|
||||
defer if (token) |t| allocator.free(t);
|
||||
var cl = std.http.Client{ .allocator = allocator };
|
||||
var cl = std.http.Client{ .allocator = allocator, .io = io };
|
||||
defer cl.deinit(); // I don't belive connection pooling would help much here as it's non-ssl and local
|
||||
// Get token
|
||||
{
|
||||
|
|
@ -383,7 +383,7 @@ fn getImdsCredentials(allocator: std.mem.Allocator, client: *std.http.Client, ro
|
|||
|
||||
}
|
||||
|
||||
fn getProfileCredentials(allocator: std.mem.Allocator, options: Profile) !?auth.Credentials {
|
||||
fn getProfileCredentials(allocator: std.mem.Allocator, io: std.Io, options: Profile) !?auth.Credentials {
|
||||
var default_path: ?[]const u8 = null;
|
||||
defer if (default_path) |p| allocator.free(p);
|
||||
|
||||
|
|
@ -416,13 +416,13 @@ fn getProfileCredentials(allocator: std.mem.Allocator, options: Profile) !?auth.
|
|||
defer if (credentials_file) |f| f.close();
|
||||
// It's much more likely that we'll find credentials in the credentials file
|
||||
// so we'll try that first
|
||||
const creds_file_creds = try credsForFile(allocator, credentials_file, profile);
|
||||
const creds_file_creds = try credsForFile(allocator, io, credentials_file, profile);
|
||||
var conf_file_creds = PartialCredentials{};
|
||||
if (creds_file_creds.access_key == null or creds_file_creds.secret_key == null) {
|
||||
log.debug("Checking config file: {s}", .{config_file_path.evaluated_path});
|
||||
const config_file = std.fs.openFileAbsolute(creds_file_path.evaluated_path, .{}) catch null;
|
||||
defer if (config_file) |f| f.close();
|
||||
conf_file_creds = try credsForFile(allocator, config_file, profile);
|
||||
conf_file_creds = try credsForFile(allocator, io, config_file, profile);
|
||||
}
|
||||
const access_key = keyFrom(allocator, creds_file_creds.access_key, conf_file_creds.access_key);
|
||||
const secret_key = keyFrom(allocator, creds_file_creds.secret_key, conf_file_creds.secret_key);
|
||||
|
|
@ -461,10 +461,10 @@ const PartialCredentials = struct {
|
|||
access_key: ?[]const u8 = null,
|
||||
secret_key: ?[]const u8 = null,
|
||||
};
|
||||
fn credsForFile(allocator: std.mem.Allocator, file: ?std.fs.File, profile: []const u8) !PartialCredentials {
|
||||
fn credsForFile(allocator: std.mem.Allocator, io: std.Io, file: ?std.fs.File, profile: []const u8) !PartialCredentials {
|
||||
if (file == null) return PartialCredentials{};
|
||||
var fbuf: [1024]u8 = undefined;
|
||||
var freader = file.?.reader(&fbuf);
|
||||
var freader = file.?.reader(io, &fbuf);
|
||||
var reader = &freader.interface;
|
||||
const text = try reader.allocRemaining(allocator, .unlimited);
|
||||
defer allocator.free(text);
|
||||
|
|
@ -629,7 +629,7 @@ fn getHomeDir(allocator: std.mem.Allocator) ![]const u8 {
|
|||
else => return error.HomeDirUnavailable,
|
||||
};
|
||||
},
|
||||
.macos, .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => {
|
||||
.macos, .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .illumos => {
|
||||
const home_dir = std.posix.getenv("HOME") orelse {
|
||||
// TODO look in /etc/passwd
|
||||
return error.HomeDirUnavailable;
|
||||
|
|
|
|||
|
|
@ -144,13 +144,15 @@ const EndPoint = struct {
|
|||
pub const AwsHttp = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
proxy: ?std.http.Client.Proxy,
|
||||
io: std.Io,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator, proxy: ?std.http.Client.Proxy) Self {
|
||||
pub fn init(allocator: std.mem.Allocator, io: std.Io, proxy: ?std.http.Client.Proxy) Self {
|
||||
return Self{
|
||||
.allocator = allocator,
|
||||
.proxy = proxy,
|
||||
.io = io,
|
||||
// .credentialsProvider = // creds provider could be useful
|
||||
};
|
||||
}
|
||||
|
|
@ -186,7 +188,7 @@ pub const AwsHttp = struct {
|
|||
defer endpoint.deinit();
|
||||
log.debug("Calling endpoint {s}", .{endpoint.uri});
|
||||
// TODO: Should we allow customization here?
|
||||
const creds = try credentials.getCredentials(self.allocator, .{});
|
||||
const creds = try credentials.getCredentials(self.allocator, self.io, .{});
|
||||
defer creds.deinit();
|
||||
const signing_config: signing.Config = .{
|
||||
.region = getRegion(service, options.region),
|
||||
|
|
@ -241,7 +243,7 @@ pub const AwsHttp = struct {
|
|||
defer if (len) |l| self.allocator.free(l);
|
||||
request_cp.headers = request_headers.items;
|
||||
|
||||
if (signing_config) |opts| request_cp = try signing.signRequest(self.allocator, request_cp, opts);
|
||||
if (signing_config) |opts| request_cp = try signing.signRequest(self.allocator, self.io, request_cp, opts);
|
||||
defer {
|
||||
if (signing_config) |opts| {
|
||||
signing.freeSignedRequest(self.allocator, &request_cp, opts);
|
||||
|
|
@ -261,7 +263,7 @@ pub const AwsHttp = struct {
|
|||
defer self.allocator.free(url);
|
||||
log.debug("Request url: {s}", .{url});
|
||||
// TODO: Fix this proxy stuff. This is all a kludge just to compile, but std.http.Client has it all built in now
|
||||
var cl = std.http.Client{ .allocator = self.allocator, .https_proxy = if (self.proxy) |*p| @constCast(p) else null };
|
||||
var cl = std.http.Client{ .allocator = self.allocator, .io = self.io, .https_proxy = if (self.proxy) |*p| @constCast(p) else null };
|
||||
defer cl.deinit(); // TODO: Connection pooling
|
||||
const method = std.meta.stringToEnum(std.http.Method, request_cp.method).?;
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ pub const SigningError = error{
|
|||
XAmzExpiresHeaderInRequest,
|
||||
/// Used if the request headers already includes x-amz-region-set
|
||||
XAmzRegionSetHeaderInRequest,
|
||||
} || error{OutOfMemory};
|
||||
} || error{OutOfMemory} || std.Io.Clock.Error;
|
||||
|
||||
const forbidden_headers = .{
|
||||
.{ .name = "x-amz-content-sha256", .err = SigningError.XAmzContentSha256HeaderInRequest },
|
||||
|
|
@ -185,7 +185,7 @@ const skipped_headers = .{
|
|||
/// Signs a request. Only header signing is currently supported. Note that
|
||||
/// This adds two headers to the request, which will need to be freed by the
|
||||
/// caller. Use freeSignedRequest with the same parameters to free
|
||||
pub fn signRequest(allocator: std.mem.Allocator, request: base.Request, config: Config) SigningError!base.Request {
|
||||
pub fn signRequest(allocator: std.mem.Allocator, io: std.Io, request: base.Request, config: Config) SigningError!base.Request {
|
||||
try validateConfig(config);
|
||||
for (request.headers) |h| {
|
||||
inline for (forbidden_headers) |f| {
|
||||
|
|
@ -195,7 +195,10 @@ pub fn signRequest(allocator: std.mem.Allocator, request: base.Request, config:
|
|||
}
|
||||
var rc = request;
|
||||
|
||||
const signing_time = config.signing_time orelse std.time.timestamp();
|
||||
const signing_time = config.signing_time orelse blk: {
|
||||
const now = try std.Io.Clock.Timestamp.now(io, .awake);
|
||||
break :blk @as(i64, @intCast(@divFloor(now.raw.nanoseconds, std.time.ns_per_s)));
|
||||
};
|
||||
|
||||
const signed_date = date.timestampToDateTime(signing_time);
|
||||
|
||||
|
|
@ -352,10 +355,10 @@ pub fn freeSignedRequest(allocator: std.mem.Allocator, request: *base.Request, c
|
|||
|
||||
pub const credentialsFn = *const fn ([]const u8) ?Credentials;
|
||||
|
||||
pub fn verifyServerRequest(allocator: std.mem.Allocator, request: *std.http.Server.Request, request_body_reader: *std.Io.Reader, credentials_fn: credentialsFn) !bool {
|
||||
pub fn verifyServerRequest(allocator: std.mem.Allocator, io: std.Io, request: *std.http.Server.Request, request_body_reader: *std.Io.Reader, credentials_fn: credentialsFn) !bool {
|
||||
var unverified_request = try UnverifiedRequest.init(allocator, request);
|
||||
defer unverified_request.deinit();
|
||||
return verify(allocator, unverified_request, request_body_reader, credentials_fn);
|
||||
return verify(allocator, io, unverified_request, request_body_reader, credentials_fn);
|
||||
}
|
||||
|
||||
pub const UnverifiedRequest = struct {
|
||||
|
|
@ -393,7 +396,7 @@ pub const UnverifiedRequest = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub fn verify(allocator: std.mem.Allocator, request: UnverifiedRequest, request_body_reader: *std.Io.Reader, credentials_fn: credentialsFn) !bool {
|
||||
pub fn verify(allocator: std.mem.Allocator, io: std.Io, request: UnverifiedRequest, request_body_reader: *std.Io.Reader, credentials_fn: credentialsFn) !bool {
|
||||
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||
defer arena.deinit();
|
||||
const aa = arena.allocator();
|
||||
|
|
@ -425,6 +428,7 @@ pub fn verify(allocator: std.mem.Allocator, request: UnverifiedRequest, request_
|
|||
if (signature == null) return error.AuthorizationHeaderMissingSignature;
|
||||
return verifyParsedAuthorization(
|
||||
aa,
|
||||
io,
|
||||
request,
|
||||
credential.?,
|
||||
signed_headers.?,
|
||||
|
|
@ -436,6 +440,7 @@ pub fn verify(allocator: std.mem.Allocator, request: UnverifiedRequest, request_
|
|||
|
||||
fn verifyParsedAuthorization(
|
||||
allocator: std.mem.Allocator,
|
||||
io: std.Io,
|
||||
request: UnverifiedRequest,
|
||||
credential: []const u8,
|
||||
signed_headers: []const u8,
|
||||
|
|
@ -502,7 +507,7 @@ fn verifyParsedAuthorization(
|
|||
signed_request.query = request.target[signed_request.path.len..]; // TODO: should this be +1? query here would include '?'
|
||||
signed_request.body = try request_body_reader.allocRemaining(allocator, .unlimited);
|
||||
defer allocator.free(signed_request.body);
|
||||
signed_request = try signRequest(allocator, signed_request, config);
|
||||
signed_request = try signRequest(allocator, io, signed_request, config);
|
||||
defer freeSignedRequest(allocator, &signed_request, config);
|
||||
return verifySignedRequest(signed_request, signature);
|
||||
}
|
||||
|
|
@ -1100,6 +1105,9 @@ test "can sign" {
|
|||
// [debug] (awshttp): Content-Length: 43
|
||||
|
||||
const allocator = std.testing.allocator;
|
||||
var threaded: std.Io.Threaded = .init(allocator);
|
||||
defer threaded.deinit();
|
||||
const io = threaded.io();
|
||||
var headers = try std.ArrayList(std.http.Header).initCapacity(allocator, 5);
|
||||
defer headers.deinit(allocator);
|
||||
try headers.append(allocator, .{ .name = "Content-Type", .value = "application/x-www-form-urlencoded; charset=utf-8" });
|
||||
|
|
@ -1131,7 +1139,7 @@ test "can sign" {
|
|||
.signing_time = 1440938160, // 20150830T123600Z
|
||||
};
|
||||
// TODO: There is an x-amz-content-sha256. Investigate
|
||||
var signed_req = try signRequest(allocator, req, config);
|
||||
var signed_req = try signRequest(allocator, io, req, config);
|
||||
|
||||
defer freeSignedRequest(allocator, &signed_req, config);
|
||||
try std.testing.expectEqualStrings("X-Amz-Date", signed_req.headers[signed_req.headers.len - 3].name);
|
||||
|
|
@ -1151,6 +1159,9 @@ test "can sign" {
|
|||
var test_credential: ?Credentials = null;
|
||||
test "can verify server request" {
|
||||
const allocator = std.testing.allocator;
|
||||
var threaded: std.Io.Threaded = .init(allocator);
|
||||
defer threaded.deinit();
|
||||
const io = threaded.io();
|
||||
|
||||
const access_key = try allocator.dupe(u8, "ACCESS");
|
||||
const secret_key = try allocator.dupe(u8, "SECRET");
|
||||
|
|
@ -1191,7 +1202,7 @@ test "can verify server request" {
|
|||
// const old_level = std.testing.log_level;
|
||||
// std.testing.log_level = .debug;
|
||||
// defer std.testing.log_level = old_level;
|
||||
try std.testing.expect(try verifyServerRequest(allocator, &request, &body_reader, struct {
|
||||
try std.testing.expect(try verifyServerRequest(allocator, io, &request, &body_reader, struct {
|
||||
cred: Credentials,
|
||||
|
||||
const Self = @This();
|
||||
|
|
@ -1203,6 +1214,9 @@ test "can verify server request" {
|
|||
}
|
||||
test "can verify server request without x-amz-content-sha256" {
|
||||
const allocator = std.testing.allocator;
|
||||
var threaded: std.Io.Threaded = .init(allocator);
|
||||
defer threaded.deinit();
|
||||
const io = threaded.io();
|
||||
|
||||
const access_key = try allocator.dupe(u8, "ACCESS");
|
||||
const secret_key = try allocator.dupe(u8, "SECRET");
|
||||
|
|
@ -1293,7 +1307,7 @@ test "can verify server request without x-amz-content-sha256" {
|
|||
}
|
||||
|
||||
{ // verification
|
||||
try std.testing.expect(try verifyServerRequest(allocator, &request, &body_reader, struct {
|
||||
try std.testing.expect(try verifyServerRequest(allocator, io, &request, &body_reader, struct {
|
||||
cred: Credentials,
|
||||
|
||||
const Self = @This();
|
||||
|
|
|
|||
|
|
@ -254,6 +254,8 @@ const TestOptions = struct {
|
|||
};
|
||||
const TestSetup = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
threaded: std.Io.Threaded,
|
||||
io: std.Io,
|
||||
options: TestOptions,
|
||||
creds: aws_auth.Credentials,
|
||||
client: aws.Client,
|
||||
|
|
@ -306,6 +308,7 @@ const TestSetup = struct {
|
|||
allocator.free(self.trace);
|
||||
allocator.free(self.request_uri);
|
||||
allocator.destroy(self.request.reader.in);
|
||||
allocator.destroy(self.request.client);
|
||||
allocator.destroy(self.request);
|
||||
}
|
||||
};
|
||||
|
|
@ -346,9 +349,19 @@ const TestSetup = struct {
|
|||
const reader = try self.allocator.create(std.Io.Reader);
|
||||
errdefer self.allocator.destroy(reader);
|
||||
reader.* = .fixed(self.options.server_response);
|
||||
// Create a minimal mock client that only provides io for deinit
|
||||
// By creating it with the allocator, we leave critical fields like
|
||||
// connection_pool as undefined, which will fail spectacularly if
|
||||
// a real request were to be attempted
|
||||
const mock_client = try self.allocator.create(std.http.Client);
|
||||
errdefer self.allocator.destroy(mock_client);
|
||||
mock_client.* = .{
|
||||
.allocator = self.allocator,
|
||||
.io = self.io,
|
||||
};
|
||||
req.* = .{
|
||||
.uri = uri,
|
||||
.client = undefined,
|
||||
.client = mock_client,
|
||||
.connection = options.connection,
|
||||
.reader = .{
|
||||
.in = reader,
|
||||
|
|
@ -433,7 +446,9 @@ const TestSetup = struct {
|
|||
return self.request_actuals.?.request.reader.in;
|
||||
}
|
||||
fn init(options: TestOptions) !*Self {
|
||||
const client = aws.Client.init(options.allocator, .{});
|
||||
var threaded: std.Io.Threaded = .init(options.allocator);
|
||||
const io = threaded.io();
|
||||
const client = aws.Client.init(options.allocator, .{ .io = io });
|
||||
const call_options = try options.allocator.create(aws.Options);
|
||||
const self = try options.allocator.create(Self);
|
||||
call_options.* = .{
|
||||
|
|
@ -453,6 +468,8 @@ const TestSetup = struct {
|
|||
self.* = .{
|
||||
.options = options,
|
||||
.allocator = options.allocator,
|
||||
.threaded = threaded,
|
||||
.io = io,
|
||||
.creds = aws_auth.Credentials.init(
|
||||
options.allocator,
|
||||
try options.allocator.dupe(u8, "ACCESS"),
|
||||
|
|
@ -476,6 +493,7 @@ const TestSetup = struct {
|
|||
}
|
||||
self.allocator.destroy(self.call_options);
|
||||
self.call_options = undefined;
|
||||
self.threaded.deinit();
|
||||
self.allocator.destroy(self);
|
||||
aws_creds.static_credentials = null;
|
||||
}
|
||||
|
|
@ -1308,6 +1326,7 @@ test "jsonStringify nullable object" {
|
|||
test "works against a live server" {
|
||||
const Server = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
io: std.Io,
|
||||
ready: std.Thread.Semaphore = .{},
|
||||
requests_received: usize = 0,
|
||||
thread: ?std.Thread = null,
|
||||
|
|
@ -1339,7 +1358,7 @@ test "works against a live server" {
|
|||
pub fn stop(self: *Server) !void {
|
||||
if (self.thread == null) return; // thread not started, nothing to do
|
||||
// post stop message
|
||||
var client = std.http.Client{ .allocator = self.allocator };
|
||||
var client = std.http.Client{ .allocator = self.allocator, .io = self.io };
|
||||
_ = try client.fetch(.{ // we ignore return because that should just shut down
|
||||
.method = .POST,
|
||||
.payload = "quit",
|
||||
|
|
@ -1350,10 +1369,10 @@ test "works against a live server" {
|
|||
}
|
||||
|
||||
fn threadMain(self: *Server) !void {
|
||||
const address = try std.net.Address.parseIp("127.0.0.1", 0);
|
||||
var server = try address.listen(.{});
|
||||
defer server.deinit();
|
||||
const server_port = server.listen_address.in.getPort();
|
||||
const address = try std.Io.net.IpAddress.parseLiteral("127.0.0.1:0");
|
||||
var server = try address.listen(self.io, .{});
|
||||
defer server.deinit(self.io);
|
||||
const server_port = server.socket.address.getPort();
|
||||
self.listening_uri = try std.fmt.allocPrint(self.allocator, "http://127.0.0.1:{d}", .{server_port});
|
||||
defer {
|
||||
self.allocator.free(self.listening_uri);
|
||||
|
|
@ -1361,13 +1380,13 @@ test "works against a live server" {
|
|||
}
|
||||
self.ready.post();
|
||||
while (true) {
|
||||
var connection = try server.accept();
|
||||
defer connection.stream.close();
|
||||
var connection = try server.accept(self.io);
|
||||
defer connection.close(self.io);
|
||||
var recv_buffer: [4000]u8 = undefined;
|
||||
var send_buffer: [4000]u8 = undefined;
|
||||
var conn_reader = connection.stream.reader(&recv_buffer);
|
||||
var conn_writer = connection.stream.writer(&send_buffer);
|
||||
var http_server = std.http.Server.init(conn_reader.interface(), &conn_writer.interface);
|
||||
var conn_reader = connection.reader(self.io, &recv_buffer);
|
||||
var conn_writer = connection.writer(self.io, &send_buffer);
|
||||
var http_server = std.http.Server.init(&conn_reader.interface, &conn_writer.interface);
|
||||
while (http_server.reader.state == .ready) {
|
||||
var req = try http_server.receiveHead();
|
||||
if (req.head.content_length) |l| {
|
||||
|
|
@ -1392,7 +1411,10 @@ test "works against a live server" {
|
|||
}
|
||||
};
|
||||
const allocator = std.testing.allocator;
|
||||
var server = Server{ .allocator = allocator };
|
||||
var threaded: std.Io.Threaded = .init(allocator);
|
||||
defer threaded.deinit();
|
||||
const io = threaded.io();
|
||||
var server = Server{ .allocator = allocator, .io = io };
|
||||
try server.start();
|
||||
var stopped = false;
|
||||
defer if (!stopped) server.stop() catch log.err("error stopping server", .{});
|
||||
|
|
@ -1412,7 +1434,7 @@ test "works against a live server" {
|
|||
// }
|
||||
|
||||
const sts = (Services(.{.sts}){}).sts;
|
||||
const client = aws.Client.init(std.testing.allocator, .{});
|
||||
const client = aws.Client.init(std.testing.allocator, .{ .io = io });
|
||||
const creds = aws_auth.Credentials.init(
|
||||
allocator,
|
||||
try allocator.dupe(u8, "ACCESS"),
|
||||
|
|
|
|||
|
|
@ -111,7 +111,10 @@ pub fn main() anyerror!void {
|
|||
}
|
||||
|
||||
std.log.info("Start\n", .{});
|
||||
const client_options = aws.ClientOptions{ .proxy = proxy };
|
||||
var threaded: std.Io.Threaded = .init(allocator);
|
||||
defer threaded.deinit();
|
||||
const io = threaded.io();
|
||||
const client_options = aws.ClientOptions{ .proxy = proxy, .io = io };
|
||||
var client = aws.Client.init(allocator, client_options);
|
||||
const options = aws.Options{
|
||||
.region = "us-west-2",
|
||||
|
|
@ -373,7 +376,8 @@ fn proxyFromString(string: []const u8) !std.http.Client.Proxy {
|
|||
rc.protocol = .tls;
|
||||
} else return error.InvalidScheme;
|
||||
var split_iterator = std.mem.splitScalar(u8, remaining, ':');
|
||||
rc.host = std.mem.trimRight(u8, split_iterator.first(), "/");
|
||||
const host_str = std.mem.trimRight(u8, split_iterator.first(), "/");
|
||||
rc.host = try std.Io.net.HostName.init(host_str);
|
||||
if (split_iterator.next()) |port|
|
||||
rc.port = try std.fmt.parseInt(u16, port, 10);
|
||||
return rc;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue