aws-sdk-for-zig/src/main.zig

413 lines
19 KiB
Zig
Raw Permalink Normal View History

2021-04-27 18:24:01 +00:00
const std = @import("std");
const aws = @import("aws.zig");
const json = @import("json.zig");
2021-04-27 18:24:01 +00:00
var verbose: u8 = 0;
2021-04-27 18:24:01 +00:00
pub fn log(
comptime level: std.log.Level,
comptime scope: @TypeOf(.EnumLiteral),
comptime format: []const u8,
args: anytype,
) void {
// Ignore aws_signing messages
2023-08-04 17:07:58 +00:00
if (verbose < 3 and scope == .aws_signing and @intFromEnum(level) >= @intFromEnum(std.log.Level.debug))
return;
2022-02-16 22:14:54 +00:00
// Ignore aws_credentials messages
2023-08-04 17:07:58 +00:00
if (verbose < 3 and scope == .aws_credentials and @intFromEnum(level) >= @intFromEnum(std.log.Level.debug))
2022-02-16 22:14:54 +00:00
return;
// Ignore xml_shaper messages
2023-08-04 17:07:58 +00:00
if (verbose < 3 and scope == .xml_shaper and @intFromEnum(level) >= @intFromEnum(std.log.Level.debug))
2022-02-16 22:14:54 +00:00
return;
// Ignore date messages
2023-08-04 17:07:58 +00:00
if (verbose < 3 and scope == .date and @intFromEnum(level) >= @intFromEnum(std.log.Level.debug))
2022-02-16 22:14:54 +00:00
return;
2021-04-27 18:24:01 +00:00
// Ignore awshttp messages
2023-08-04 17:07:58 +00:00
if (verbose < 2 and scope == .awshttp and @intFromEnum(level) >= @intFromEnum(std.log.Level.debug))
return;
2023-08-04 17:07:58 +00:00
if (verbose < 1 and scope == .aws and @intFromEnum(level) >= @intFromEnum(std.log.Level.debug))
2021-04-27 18:24:01 +00:00
return;
const scope_prefix = "(" ++ @tagName(scope) ++ "): ";
const prefix = "[" ++ @tagName(level) ++ "] " ++ scope_prefix;
// Print the message to stderr, silently ignoring any errors
2021-12-23 16:51:48 +00:00
std.debug.getStderrMutex().lock();
defer std.debug.getStderrMutex().unlock();
2021-04-27 18:24:01 +00:00
const stderr = std.io.getStdErr().writer();
nosuspend stderr.print(prefix ++ format ++ "\n", args) catch return;
}
upgrade to nominated zig 2024.3.0-mach (0.12.0-dev.3180+83e578a18) There were significant changes to the way HTTP operates since 0.11, effecting client operations, but more substantially, the server implementation, which effected the test harness. std.http.Headers was removed, including the getFirstValue function, which needed to be replicated. On the plus side, a std.http.Header struct was added, identical to our own structure, so I have removed out own header in favor of stdlib. On the Http client side, I have switched to use the fetch API. Proxy support is built in, but we are using (mostly) our own implementation for now, with the remaining conversion left as a TODO item. Raw URIs are now supported, so the workaround for issue 17015 has been removed. Large payloads should also be fixed, but this has not been tested. The standard library now adds the content-length header (unconditionally), which is a decision of dubious nature. I have removed the addition of content-length, which also means it is not present during signing. This should be allowed. Dependency loop on fieldTransformer was fixed. This should have been a problem on zig 0.11, but was not. This effected the API for the json parsing, but we were not using that. At the call site, these did not need to be specified as references. With the http server no longer doing all the allocations it once was, the test harness now has a lot more allocations to perform. To alleviate the bookeeping, this was moved to an Arena allocator. The client, which is really what is under test, continues to use the allocator passed.
2024-04-02 16:13:45 +00:00
pub const std_options = std.Options{
.logFn = log,
};
const Tests = enum {
query_no_input,
query_with_input,
ec2_query_no_input,
2022-05-25 18:38:34 +00:00
ec2_query_with_input,
2021-08-12 21:24:24 +00:00
json_1_0_query_with_input,
json_1_0_query_no_input,
2021-08-13 00:51:47 +00:00
json_1_1_query_with_input,
json_1_1_query_no_input,
rest_json_1_query_no_input,
rest_json_1_query_with_input,
rest_json_1_work_with_lambda,
2022-05-25 22:27:13 +00:00
rest_xml_no_input,
2022-05-29 03:14:42 +00:00
rest_xml_anything_but_s3,
2022-06-06 01:34:39 +00:00
rest_xml_work_with_s3,
};
pub fn main() anyerror!void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
2021-12-23 16:51:48 +00:00
const allocator = gpa.allocator();
var tests = std.ArrayList(Tests).init(allocator);
defer tests.deinit();
2023-08-15 15:50:22 +00:00
var args = try std.process.argsWithAllocator(allocator);
defer args.deinit();
2023-08-29 14:26:11 +00:00
const stdout_raw = std.io.getStdOut().writer();
var bw = std.io.bufferedWriter(stdout_raw);
defer bw.flush() catch unreachable;
const stdout = bw.writer();
var arg0: ?[]const u8 = null;
upgrade to nominated zig 2024.3.0-mach (0.12.0-dev.3180+83e578a18) There were significant changes to the way HTTP operates since 0.11, effecting client operations, but more substantially, the server implementation, which effected the test harness. std.http.Headers was removed, including the getFirstValue function, which needed to be replicated. On the plus side, a std.http.Header struct was added, identical to our own structure, so I have removed out own header in favor of stdlib. On the Http client side, I have switched to use the fetch API. Proxy support is built in, but we are using (mostly) our own implementation for now, with the remaining conversion left as a TODO item. Raw URIs are now supported, so the workaround for issue 17015 has been removed. Large payloads should also be fixed, but this has not been tested. The standard library now adds the content-length header (unconditionally), which is a decision of dubious nature. I have removed the addition of content-length, which also means it is not present during signing. This should be allowed. Dependency loop on fieldTransformer was fixed. This should have been a problem on zig 0.11, but was not. This effected the API for the json parsing, but we were not using that. At the call site, these did not need to be specified as references. With the http server no longer doing all the allocations it once was, the test harness now has a lot more allocations to perform. To alleviate the bookeeping, this was moved to an Arena allocator. The client, which is really what is under test, continues to use the allocator passed.
2024-04-02 16:13:45 +00:00
var proxy: ?std.http.Client.Proxy = null;
while (args.next()) |arg| {
2023-08-29 14:26:11 +00:00
if (arg0 == null) arg0 = arg;
if (std.mem.eql(u8, "-h", arg) or std.mem.eql(u8, "--help", arg)) {
try stdout.print(
2023-08-29 18:24:34 +00:00
\\usage: {?s} [-h|--help] [-v][-v][-v] [-x|--proxy <proxy url>] [tests...]
2023-08-29 14:26:11 +00:00
\\
\\Where tests are one of the following:
\\
, .{arg0});
inline for (std.meta.fields(Tests)) |enumfield| {
try stdout.print("* {s}\n", .{enumfield.name});
}
return;
}
2023-08-29 18:24:34 +00:00
if (std.mem.eql(u8, "-x", arg) or std.mem.eql(u8, "--proxy", arg)) {
proxy = try proxyFromString(args.next().?); // parse stuff
continue;
}
2023-08-29 22:21:15 +00:00
if (std.mem.startsWith(u8, arg, "-v")) {
for (arg[1..]) |c| {
if (c != 'v') return error.InvalidArgument;
verbose += 1;
}
continue;
}
inline for (@typeInfo(Tests).Enum.fields) |f| {
if (std.mem.eql(u8, f.name, arg)) {
try tests.append(@field(Tests, f.name));
break;
}
}
}
if (tests.items.len == 0) {
inline for (@typeInfo(Tests).Enum.fields) |f|
try tests.append(@field(Tests, f.name));
}
2021-04-27 18:24:01 +00:00
std.log.info("Start\n", .{});
2023-08-29 18:24:34 +00:00
const client_options = aws.ClientOptions{ .proxy = proxy };
var client = aws.Client.init(allocator, client_options);
2021-04-27 18:24:01 +00:00
const options = aws.Options{
.region = "us-west-2",
.client = client,
2021-04-27 18:24:01 +00:00
};
defer client.deinit();
// As of 2023-08-28, only ECS from this list supports TLS v1.3
// AWS commitment is to enable all services by 2023-12-31
2022-05-29 03:14:42 +00:00
const services = aws.Services(.{ .sts, .ec2, .dynamo_db, .ecs, .lambda, .sqs, .s3, .cloudfront }){};
2021-04-27 18:24:01 +00:00
for (tests.items) |t| {
std.log.info("===== Start Test: {s} =====", .{@tagName(t)});
switch (t) {
.query_no_input => {
const call = try aws.Request(services.sts.get_caller_identity).call(.{}, options);
// const call = try client.call(services.sts.get_caller_identity.Request{}, options);
defer call.deinit();
2023-08-29 18:29:50 +00:00
std.log.info("arn: {s}", .{call.response.arn.?});
std.log.info("id: {s}", .{call.response.user_id.?});
std.log.info("account: {s}", .{call.response.account.?});
std.log.info("requestId: {s}", .{call.response_metadata.request_id});
},
.query_with_input => {
const call = try client.call(services.sqs.list_queues.Request{
.queue_name_prefix = "s",
}, options);
defer call.deinit();
2023-08-29 18:29:50 +00:00
std.log.info("request id: {s}", .{call.response_metadata.request_id});
std.log.info("account has queues with prefix 's': {}", .{call.response.queue_urls != null});
2021-08-12 21:24:24 +00:00
},
.json_1_0_query_with_input => {
const call = try client.call(services.dynamo_db.list_tables.Request{
2021-08-12 21:24:24 +00:00
.limit = 1,
}, options);
defer call.deinit();
2023-08-29 18:29:50 +00:00
std.log.info("request id: {s}", .{call.response_metadata.request_id});
std.log.info("account has tables: {}", .{call.response.table_names.?.len > 0});
2021-08-12 21:24:24 +00:00
},
.json_1_0_query_no_input => {
const call = try client.call(services.dynamo_db.describe_limits.Request{}, options);
defer call.deinit();
std.log.info("account read capacity limit: {?d}", .{call.response.account_max_read_capacity_units});
},
2021-08-13 00:51:47 +00:00
.json_1_1_query_with_input => {
const call = try client.call(services.ecs.list_clusters.Request{
2021-08-13 00:51:47 +00:00
.max_results = 1,
}, options);
defer call.deinit();
2023-08-29 18:29:50 +00:00
std.log.info("request id: {s}", .{call.response_metadata.request_id});
std.log.info("account has clusters: {}", .{call.response.cluster_arns.?.len > 0});
2021-08-13 00:51:47 +00:00
},
.json_1_1_query_no_input => {
const call = try client.call(services.ecs.list_clusters.Request{}, options);
defer call.deinit();
2023-08-29 18:29:50 +00:00
std.log.info("request id: {s}", .{call.response_metadata.request_id});
std.log.info("account has clusters: {}", .{call.response.cluster_arns.?.len > 0});
},
.rest_json_1_query_with_input => {
const call = try client.call(services.lambda.list_functions.Request{
.max_items = 1,
}, options);
defer call.deinit();
2023-08-29 18:29:50 +00:00
std.log.info("request id: {s}", .{call.response_metadata.request_id});
std.log.info("account has functions: {}", .{call.response.functions.?.len > 0});
},
.rest_json_1_query_no_input => {
const call = try client.call(services.lambda.list_functions.Request{}, options);
defer call.deinit();
2023-08-29 18:29:50 +00:00
std.log.info("request id: {s}", .{call.response_metadata.request_id});
std.log.info("account has functions: {}", .{call.response.functions.?.len > 0});
},
.rest_json_1_work_with_lambda => {
const call = try client.call(services.lambda.list_functions.Request{}, options);
defer call.deinit();
std.log.info("list request id: {s}", .{call.response_metadata.request_id});
2023-08-30 20:49:29 +00:00
if (call.response.functions) |fns| {
if (fns.len > 0) {
const func = fns[0];
const arn = func.function_arn.?;
// This is a bit ugly. Maybe a helper function in the library would help?
var tags = try std.ArrayList(@typeInfo(try typeForField(services.lambda.tag_resource.Request, "tags")).Pointer.child).initCapacity(allocator, 1);
defer tags.deinit();
tags.appendAssumeCapacity(.{ .key = "Foo", .value = "Bar" });
const req = services.lambda.tag_resource.Request{ .resource = arn, .tags = tags.items };
const addtag = try aws.Request(services.lambda.tag_resource).call(req, options);
// TODO: This is failing due to double-encoding (see zig issue 17015)
defer addtag.deinit();
// const addtag = try client.call(services.lambda.tag_resource.Request{ .resource = arn, .tags = &.{.{ .key = "Foo", .value = "Bar" }} }, options);
std.log.info("add tag request id: {s}", .{addtag.response_metadata.request_id});
var keys = [_][]const u8{"Foo"}; // Would love to have a way to express this without burning a var here
const deletetag = try aws.Request(services.lambda.untag_resource).call(.{ .tag_keys = keys[0..], .resource = arn }, options);
defer deletetag.deinit();
std.log.info("delete tag request id: {s}", .{deletetag.response_metadata.request_id});
} else {
std.log.err("no functions to work with", .{});
}
} else {
std.log.err("no functions to work with", .{});
}
2021-08-13 00:51:47 +00:00
},
.ec2_query_no_input => {
2023-08-28 20:10:16 +00:00
// Describe regions is a simpler request and easier to debug
const result = try client.call(services.ec2.describe_regions.Request{}, options);
defer result.deinit();
2023-08-29 18:29:50 +00:00
std.log.info("request id: {s}", .{result.response_metadata.request_id});
std.log.info("region count: {d}", .{result.response.regions.?.len});
2022-05-25 18:38:34 +00:00
},
.ec2_query_with_input => {
2022-02-11 17:17:27 +00:00
// Describe instances is more interesting
const result = try client.call(services.ec2.describe_instances.Request{ .max_results = 6 }, options);
defer result.deinit();
std.log.info("reservation count: {d}", .{result.response.reservations.?.len});
var items: usize = 0;
for (result.response.reservations.?) |reservation| {
items += reservation.instances.?.len;
}
std.log.info("items count: {d}", .{items});
var next = result.response.next_token;
while (next) |next_token| {
std.log.info("more results available: fetching again", .{});
const more = try aws.Request(services.ec2.describe_instances)
.call(.{ .next_token = next_token, .max_results = 6 }, options);
defer more.deinit();
// we could have exactly 6, which means we have a next token(?!) but not
// any actual additional data
if (more.response.reservations == null) break;
std.log.info("reservation count: {d}", .{more.response.reservations.?.len});
var batch_items: usize = 0;
for (more.response.reservations.?) |reservation| {
batch_items += reservation.instances.?.len;
}
std.log.info("items count: {d}", .{batch_items});
items += batch_items;
std.log.info("total items count: {d}", .{items});
next = more.response.next_token;
}
},
2023-08-28 20:30:39 +00:00
// ^^ under test. vv still in progress
2022-05-25 22:27:13 +00:00
.rest_xml_no_input => {
const result = try client.call(services.s3.list_buckets.Request{}, options);
defer result.deinit();
2023-08-29 18:29:50 +00:00
std.log.info("request id: {s}", .{result.response_metadata.request_id});
2022-05-25 22:27:13 +00:00
std.log.info("bucket count: {d}", .{result.response.buckets.?.len});
},
2022-05-29 03:14:42 +00:00
.rest_xml_anything_but_s3 => {
const result = try client.call(services.cloudfront.list_key_groups.Request{}, options);
defer result.deinit();
2023-08-29 18:29:50 +00:00
std.log.info("request id: {s}", .{result.response_metadata.request_id});
2022-05-29 03:14:42 +00:00
const list = result.response.key_group_list.?;
std.log.info("key group list max: {?d}", .{list.max_items});
2022-05-29 03:14:42 +00:00
std.log.info("key group quantity: {d}", .{list.quantity});
},
2022-06-06 01:34:39 +00:00
.rest_xml_work_with_s3 => {
2022-06-29 16:24:16 +00:00
const key = "i/am/a/teapot/foo";
// // const key = "foo";
//
2022-06-06 01:34:39 +00:00
const bucket = blk: {
const result = try client.call(services.s3.list_buckets.Request{}, options);
defer result.deinit();
const bucket = result.response.buckets.?[result.response.buckets.?.len - 1];
2023-08-29 18:29:50 +00:00
std.log.info("ListBuckets request id: {s}", .{result.response_metadata.request_id});
std.log.info("bucket name: {s}", .{bucket.name.?});
2022-06-06 01:34:39 +00:00
break :blk try allocator.dupe(u8, bucket.name.?);
};
defer allocator.free(bucket);
const location = blk: {
const result = try aws.Request(services.s3.get_bucket_location).call(.{
.bucket = bucket,
}, options);
defer result.deinit();
const location = result.response.location_constraint.?;
2023-08-29 18:29:50 +00:00
std.log.info("GetBucketLocation request id: {s}", .{result.response_metadata.request_id});
std.log.info("location: {s}", .{location});
2022-06-06 01:34:39 +00:00
break :blk try allocator.dupe(u8, location);
};
defer allocator.free(location);
2022-06-06 01:34:39 +00:00
const s3opts = aws.Options{
.region = location,
.client = client,
};
2023-08-28 00:36:26 +00:00
{
const result = try aws.Request(services.s3.put_object).call(.{
.bucket = bucket,
.key = key,
.content_type = "text/plain",
.body = "bar",
.storage_class = "STANDARD",
}, s3opts);
std.log.info("PutObject Request id: {s}", .{result.response_metadata.request_id});
std.log.info("PutObject etag: {s}", .{result.response.e_tag.?});
2023-08-28 00:36:26 +00:00
defer result.deinit();
}
{
// Note that boto appears to redirect by default, but java
// does not. We will not
const result = try aws.Request(services.s3.get_object).call(.{
.bucket = bucket,
.key = key,
}, s3opts);
std.log.info("GetObject Request id: {s}", .{result.response_metadata.request_id});
std.log.info("GetObject Body: {s}", .{result.response.body.?});
std.log.info("GetObject etag: {s}", .{result.response.e_tag.?});
2023-08-28 00:36:26 +00:00
std.log.info("GetObject last modified (seconds since epoch): {d}", .{result.response.last_modified.?});
defer result.deinit();
}
{
const result = try aws.Request(services.s3.delete_object).call(.{
.bucket = bucket,
.key = key,
}, s3opts);
std.log.info("DeleteObject Request id: {s}", .{result.response_metadata.request_id});
2023-08-28 00:36:26 +00:00
defer result.deinit();
}
2022-06-06 01:34:39 +00:00
{
const result = try aws.Request(services.s3.list_objects).call(.{
.bucket = bucket,
}, s3opts);
std.log.info("ListObject Request id: {s}", .{result.response_metadata.request_id});
2022-06-06 01:34:39 +00:00
std.log.info("Object count: {d}", .{result.response.contents.?.len});
defer result.deinit();
}
},
}
std.log.info("===== End Test: {s} =====\n", .{@tagName(t)});
2021-04-27 18:24:01 +00:00
}
// if (test_twice) {
// std.time.sleep(1000 * std.time.ns_per_ms);
// std.log.info("second request", .{});
//
// var client2 = aws.Aws.init(allocator);
// defer client2.deinit();
// const resp2 = try client2.call(services.sts.get_caller_identity.Request{}, options); // catch here and try alloc?
// defer resp2.deinit();
// }
2021-04-27 18:24:01 +00:00
std.log.info("===== Tests complete =====", .{});
2021-04-27 18:24:01 +00:00
}
2023-08-29 18:24:34 +00:00
upgrade to nominated zig 2024.3.0-mach (0.12.0-dev.3180+83e578a18) There were significant changes to the way HTTP operates since 0.11, effecting client operations, but more substantially, the server implementation, which effected the test harness. std.http.Headers was removed, including the getFirstValue function, which needed to be replicated. On the plus side, a std.http.Header struct was added, identical to our own structure, so I have removed out own header in favor of stdlib. On the Http client side, I have switched to use the fetch API. Proxy support is built in, but we are using (mostly) our own implementation for now, with the remaining conversion left as a TODO item. Raw URIs are now supported, so the workaround for issue 17015 has been removed. Large payloads should also be fixed, but this has not been tested. The standard library now adds the content-length header (unconditionally), which is a decision of dubious nature. I have removed the addition of content-length, which also means it is not present during signing. This should be allowed. Dependency loop on fieldTransformer was fixed. This should have been a problem on zig 0.11, but was not. This effected the API for the json parsing, but we were not using that. At the call site, these did not need to be specified as references. With the http server no longer doing all the allocations it once was, the test harness now has a lot more allocations to perform. To alleviate the bookeeping, this was moved to an Arena allocator. The client, which is really what is under test, continues to use the allocator passed.
2024-04-02 16:13:45 +00:00
fn proxyFromString(string: []const u8) !std.http.Client.Proxy {
var rc = std.http.Client.Proxy{
2023-08-29 18:24:34 +00:00
.protocol = undefined,
.host = undefined,
upgrade to nominated zig 2024.3.0-mach (0.12.0-dev.3180+83e578a18) There were significant changes to the way HTTP operates since 0.11, effecting client operations, but more substantially, the server implementation, which effected the test harness. std.http.Headers was removed, including the getFirstValue function, which needed to be replicated. On the plus side, a std.http.Header struct was added, identical to our own structure, so I have removed out own header in favor of stdlib. On the Http client side, I have switched to use the fetch API. Proxy support is built in, but we are using (mostly) our own implementation for now, with the remaining conversion left as a TODO item. Raw URIs are now supported, so the workaround for issue 17015 has been removed. Large payloads should also be fixed, but this has not been tested. The standard library now adds the content-length header (unconditionally), which is a decision of dubious nature. I have removed the addition of content-length, which also means it is not present during signing. This should be allowed. Dependency loop on fieldTransformer was fixed. This should have been a problem on zig 0.11, but was not. This effected the API for the json parsing, but we were not using that. At the call site, these did not need to be specified as references. With the http server no longer doing all the allocations it once was, the test harness now has a lot more allocations to perform. To alleviate the bookeeping, this was moved to an Arena allocator. The client, which is really what is under test, continues to use the allocator passed.
2024-04-02 16:13:45 +00:00
.authorization = null,
.port = undefined,
.supports_connect = true, // TODO: Is this a good default?
2023-08-29 18:24:34 +00:00
};
var remaining: []const u8 = string;
if (std.mem.startsWith(u8, string, "http://")) {
remaining = remaining["http://".len..];
rc.protocol = .plain;
upgrade to nominated zig 2024.3.0-mach (0.12.0-dev.3180+83e578a18) There were significant changes to the way HTTP operates since 0.11, effecting client operations, but more substantially, the server implementation, which effected the test harness. std.http.Headers was removed, including the getFirstValue function, which needed to be replicated. On the plus side, a std.http.Header struct was added, identical to our own structure, so I have removed out own header in favor of stdlib. On the Http client side, I have switched to use the fetch API. Proxy support is built in, but we are using (mostly) our own implementation for now, with the remaining conversion left as a TODO item. Raw URIs are now supported, so the workaround for issue 17015 has been removed. Large payloads should also be fixed, but this has not been tested. The standard library now adds the content-length header (unconditionally), which is a decision of dubious nature. I have removed the addition of content-length, which also means it is not present during signing. This should be allowed. Dependency loop on fieldTransformer was fixed. This should have been a problem on zig 0.11, but was not. This effected the API for the json parsing, but we were not using that. At the call site, these did not need to be specified as references. With the http server no longer doing all the allocations it once was, the test harness now has a lot more allocations to perform. To alleviate the bookeeping, this was moved to an Arena allocator. The client, which is really what is under test, continues to use the allocator passed.
2024-04-02 16:13:45 +00:00
rc.port = 80;
2023-08-29 18:24:34 +00:00
} else if (std.mem.startsWith(u8, string, "https://")) {
remaining = remaining["https://".len..];
upgrade to nominated zig 2024.3.0-mach (0.12.0-dev.3180+83e578a18) There were significant changes to the way HTTP operates since 0.11, effecting client operations, but more substantially, the server implementation, which effected the test harness. std.http.Headers was removed, including the getFirstValue function, which needed to be replicated. On the plus side, a std.http.Header struct was added, identical to our own structure, so I have removed out own header in favor of stdlib. On the Http client side, I have switched to use the fetch API. Proxy support is built in, but we are using (mostly) our own implementation for now, with the remaining conversion left as a TODO item. Raw URIs are now supported, so the workaround for issue 17015 has been removed. Large payloads should also be fixed, but this has not been tested. The standard library now adds the content-length header (unconditionally), which is a decision of dubious nature. I have removed the addition of content-length, which also means it is not present during signing. This should be allowed. Dependency loop on fieldTransformer was fixed. This should have been a problem on zig 0.11, but was not. This effected the API for the json parsing, but we were not using that. At the call site, these did not need to be specified as references. With the http server no longer doing all the allocations it once was, the test harness now has a lot more allocations to perform. To alleviate the bookeeping, this was moved to an Arena allocator. The client, which is really what is under test, continues to use the allocator passed.
2024-04-02 16:13:45 +00:00
rc.port = 443;
2023-08-29 18:24:34 +00:00
rc.protocol = .tls;
} else return error.InvalidScheme;
var split_iterator = std.mem.split(u8, remaining, ":");
rc.host = std.mem.trimRight(u8, split_iterator.first(), "/");
if (split_iterator.next()) |port|
rc.port = try std.fmt.parseInt(u16, port, 10);
return rc;
}
fn typeForField(comptime T: type, comptime field_name: []const u8) !type {
const ti = @typeInfo(T);
switch (ti) {
.Struct => {
inline for (ti.Struct.fields) |field| {
if (std.mem.eql(u8, field.name, field_name))
return field.type;
}
},
else => return error.TypeIsNotAStruct, // should not hit this
}
return error.FieldNotFound;
}
// TODO: Move into json.zig
pub fn jsonFun() !void {
// Standard behavior
const payload =
\\{"GetCallerIdentityResponse":{"GetCallerIdentityResult":{"Account":"0123456789","Arn":"arn:aws:iam::0123456789:user/test","UserId":"MYUSERID"},"ResponseMetadata":{"RequestId":"3b80a99b-7df8-4bcb-96ee-b2759878a5f2"}}}
;
const Ret3 = struct {
getCallerIdentityResponse: struct { getCallerIdentityResult: struct { account: []u8, arn: []u8, user_id: []u8 }, responseMetadata: struct { requestId: []u8 } },
};
var stream3 = json.TokenStream.init(payload);
const res3 = json.parse(Ret3, &stream3, .{
.allocator = std.heap.c_allocator,
.allow_camel_case_conversion = true, // new option
.allow_snake_case_conversion = true, // new option
.allow_unknown_fields = true, // new option
}) catch unreachable;
std.log.info("{}", .{res3});
std.log.info("{any}", .{res3.getCallerIdentityResponse.getCallerIdentityResult.user_id});
}