complete src/main.zig zig 0.12.0 upgrade
Some checks failed
AWS-Zig Build / build (push) Has been cancelled

This commit is contained in:
Emil Lerch 2024-05-15 14:21:01 -07:00
parent 3a1208d6a9
commit ce115ff485
Signed by: lobo
GPG Key ID: A7B62D657EF764F8

View File

@ -9,8 +9,8 @@ const Account = @import("Account.zig");
const log = std.log.scoped(.dynamodb); const log = std.log.scoped(.dynamodb);
pub const std_options = struct { pub const std_options = .{
pub const log_scope_levels = &[_]std.log.ScopeLevel{.{ .scope = .aws_signing, .level = .info }}; .log_scope_levels = &.{.{ .scope = .aws_signing, .level = .info }},
}; };
pub fn main() !u8 { pub fn main() !u8 {
@ -32,12 +32,16 @@ pub fn handler(allocator: std.mem.Allocator, event_data: []const u8, context: un
var fis = std.io.fixedBufferStream(event_data); var fis = std.io.fixedBufferStream(event_data);
try authenticateUser(allocator, context, context.request.target, context.request.headers, fis.reader()); try authenticateUser(allocator, context, context.request.target, context.request.headers, fis.reader());
try setContentType(&context.headers, "application/x-amz-json-1.0", false); try setContentType(allocator, &context.headers, "application/x-amz-json-1.0", false);
// https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html#API_CreateTable_Examples // https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html#API_CreateTable_Examples
// Operation is in X-Amz-Target // Operation is in X-Amz-Target
// event_data is json // event_data is json
// X-Amz-Target: DynamoDB_20120810.CreateTable // X-Amz-Target: DynamoDB_20120810.CreateTable
const target_value_or_null = context.request.headers.getFirstValue("X-Amz-Target"); const target_value_or_null = blk: {
for (context.request.headers) |h|
if (std.ascii.eqlIgnoreCase(h.name, "X-Amz-Target")) break :blk h.value;
break :blk null;
};
const target_value = if (target_value_or_null) |t| t else { const target_value = if (target_value_or_null) |t| t else {
context.status = .bad_request; context.status = .bad_request;
context.reason = "Missing X-Amz-Target header"; context.reason = "Missing X-Amz-Target header";
@ -76,12 +80,24 @@ pub fn handler(allocator: std.mem.Allocator, event_data: []const u8, context: un
context.status = .bad_request; context.status = .bad_request;
return error.OperationUnsupported; return error.OperationUnsupported;
} }
fn setContentType(headers: *std.http.Headers, content_type: []const u8, overwrite: bool) !void { fn setContentType(allocator: std.mem.Allocator, headers: *[]const std.http.Header, content_type: []const u8, overwrite: bool) !void {
if (headers.contains("content-type")) { for (headers.*, 0..) |h, i| {
if (!overwrite) return; if (std.ascii.eqlIgnoreCase(h.name, "content-type")) {
_ = headers.delete("content-type"); if (overwrite) {
const new_headers = try allocator.dupe(std.http.Header, headers.*);
errdefer allocator.free(new_headers);
new_headers[i] = .{ .name = "Content-Type", .value = content_type };
headers.* = new_headers;
}
return;
}
} }
try headers.append("Content-Type", content_type); // need to add to the array
const new_headers = try allocator.alloc(std.http.Header, headers.len + 1);
errdefer allocator.free(new_headers);
@memcpy(new_headers[0..headers.len], headers.*);
new_headers[new_headers.len - 1] = .{ .name = "Content-Type", .value = content_type };
headers.* = new_headers;
} }
fn executeOperation( fn executeOperation(
request: *AuthenticatedRequest, request: *AuthenticatedRequest,
@ -98,8 +114,9 @@ fn executeOperation(
return err; return err;
}; };
} }
fn authenticateUser(allocator: std.mem.Allocator, context: universal_lambda_interface.Context, target: []const u8, headers: std.http.Headers, body_reader: anytype) !void { fn authenticateUser(allocator: std.mem.Allocator, context: universal_lambda_interface.Context, target: []const u8, headers: []const std.http.Header, body_reader: anytype) !void {
const request = signing.UnverifiedRequest{ const request = signing.UnverifiedRequest{
.allocator = allocator,
.method = std.http.Method.POST, .method = std.http.Method.POST,
.target = target, .target = target,
.headers = headers, .headers = headers,
@ -215,7 +232,7 @@ fn fillRootCreds(allocator: std.mem.Allocator) !void {
} }
const NullAllocator = struct { const NullAllocator = struct {
const thing = 0; const thing: u8 = 0;
const vtable = std.mem.Allocator.VTable{ const vtable = std.mem.Allocator.VTable{
.alloc = alloc, .alloc = alloc,
.resize = resize, .resize = resize,
@ -268,8 +285,12 @@ fn accountForAccessKey(allocator: std.mem.Allocator, access_key: []const u8) !u4
/// Function assumes an authenticated request, so signing.verify must be called /// Function assumes an authenticated request, so signing.verify must be called
/// and returned true before calling this function. If authentication header /// and returned true before calling this function. If authentication header
/// is not found, environment variable will be used /// is not found, environment variable will be used
fn accountId(allocator: std.mem.Allocator, headers: std.http.Headers) !u40 { fn accountId(allocator: std.mem.Allocator, headers: []const std.http.Header) !u40 {
const auth_header = headers.getFirstValue("Authorization"); const auth_header = blk: {
for (headers) |h|
if (std.ascii.eqlIgnoreCase(h.name, "Authorization")) break :blk h.value;
break :blk null;
};
if (auth_header) |h| { if (auth_header) |h| {
// AWS4-HMAC-SHA256 Credential=ACCESS/20230908/us-west-2/s3/aws4_request, SignedHeaders=accept;content-length;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class, Signature=fcc43ce73a34c9bd1ddf17e8a435f46a859812822f944f9eeb2aabcd64b03523 // AWS4-HMAC-SHA256 Credential=ACCESS/20230908/us-west-2/s3/aws4_request, SignedHeaders=accept;content-length;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class, Signature=fcc43ce73a34c9bd1ddf17e8a435f46a859812822f944f9eeb2aabcd64b03523
const start = std.mem.indexOf(u8, h, "Credential=").? + "Credential=".len; const start = std.mem.indexOf(u8, h, "Credential=").? + "Credential=".len;