return new request instead of mutating in place
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Emil Lerch 2022-01-19 19:12:50 -08:00
parent b928a5ec21
commit 3e9fab6ca5
Signed by: lobo
GPG Key ID: A7B62D657EF764F8
2 changed files with 21 additions and 25 deletions

View File

@ -128,13 +128,12 @@ pub const AwsHttp = struct {
const len = try addHeaders(self.allocator, &request_headers, endpoint.host, request_cp.body, request_cp.content_type, request_cp.headers);
defer if (len) |l| self.allocator.free(l);
request_cp.headers = request_headers.items;
// defer self.allocator.free(request_cp.headers);
log.debug("All Request Headers (before signing. Count: {d}):", .{request_cp.headers.len});
for (request_cp.headers) |h|
log.debug("\t{s}: {s}", .{ h.name, h.value });
// Signing will alter request headers
if (signing_config) |opts| try signing.signRequest(self.allocator, &request_cp, opts);
if (signing_config) |opts| request_cp = try signing.signRequest(self.allocator, request_cp, opts);
log.debug("All Request Headers (after signing):", .{});
for (request_cp.headers) |h|
log.debug("\t{s}: {s}", .{ h.name, h.value });

View File

@ -127,7 +127,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!void {
pub fn signRequest(allocator: std.mem.Allocator, request: base.Request, config: Config) SigningError!base.Request {
try validateConfig(config);
for (request.headers) |h| {
inline for (forbidden_headers) |f| {
@ -135,6 +135,7 @@ pub fn signRequest(allocator: std.mem.Allocator, request: *base.Request, config:
return f.err;
}
}
var rc = request;
const signing_time = config.signing_time orelse std.time.timestamp();
@ -152,28 +153,22 @@ pub fn signRequest(allocator: std.mem.Allocator, request: *base.Request, config:
signed_date.second,
},
);
errdefer freeSignedRequest(allocator, request, config);
errdefer freeSignedRequest(allocator, &rc, config);
const newheaders = try allocator.alloc(base.Header, request.headers.len + 2);
const newheaders = try allocator.alloc(base.Header, rc.headers.len + 2);
errdefer allocator.free(newheaders);
const oldheaders = request.headers;
errdefer {
freeSignedRequest(allocator, request, config);
request.headers = oldheaders;
}
const oldheaders = rc.headers;
errdefer freeSignedRequest(allocator, &rc, config);
std.mem.copy(base.Header, newheaders, oldheaders);
newheaders[newheaders.len - 2] = base.Header{
.name = "X-Amz-Date",
.value = signing_iso8601,
};
std.log.debug("oldheaders len: {d}, newheaders len: {d}, request.headers len: {d}", .{ oldheaders.len, newheaders.len, request.headers.len });
// for (newheaders) |h, i|
// std.log.debug("{d}: {d}/{d}", .{ i, h.name.len, h.value.len });
request.headers = newheaders[0 .. newheaders.len - 1];
for (request.headers) |h|
rc.headers = newheaders[0 .. newheaders.len - 1];
for (rc.headers) |h|
std.log.debug("{d}/{d}", .{ h.name.len, h.value.len });
log.debug("Signing with access key: {s}", .{config.credentials.access_key});
const canonical_request = try createCanonicalRequest(allocator, request.*, config);
const canonical_request = try createCanonicalRequest(allocator, rc, config);
defer {
allocator.free(canonical_request.arr);
allocator.free(canonical_request.hash);
@ -237,8 +232,8 @@ pub fn signRequest(allocator: std.mem.Allocator, request: *base.Request, config:
},
),
};
request.headers = newheaders;
//return SigningError.NotImplemented;
rc.headers = newheaders;
return rc;
}
/// Frees allocated resources for the request, including the headers array
@ -830,14 +825,16 @@ test "can sign" {
};
// TODO: There is an x-amz-content-sha256. Investigate
//
try signRequest(allocator, &req, config);
var signed_req = try signRequest(allocator, req, config);
defer freeSignedRequest(allocator, &req, config);
try std.testing.expectEqualStrings("X-Amz-Date", req.headers[req.headers.len - 2].name);
try std.testing.expectEqualStrings("20150830T123600Z", req.headers[req.headers.len - 2].value);
defer freeSignedRequest(allocator, &signed_req, config);
try std.testing.expectEqualStrings("X-Amz-Date", signed_req.headers[signed_req.headers.len - 2].name);
try std.testing.expectEqualStrings("20150830T123600Z", signed_req.headers[signed_req.headers.len - 2].value);
const expected_auth = "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date, Signature=1a72ec8f64bd914b0e42e42607c7fbce7fb2c7465f63e3092b3b0d39fa77a6fe";
// c_aws_auth tests don't seem to have valid data. Live endpoint is
// accepting what we're doing
const expected_auth = "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date, Signature=2b9566917226a17022b710430a367d343cbff33af7ee50b0ff8f44d75a4a46d8";
try std.testing.expectEqualStrings("Authorization", req.headers[req.headers.len - 1].name);
try std.testing.expectEqualStrings(expected_auth, req.headers[req.headers.len - 1].value);
try std.testing.expectEqualStrings("Authorization", signed_req.headers[signed_req.headers.len - 1].name);
try std.testing.expectEqualStrings(expected_auth, signed_req.headers[signed_req.headers.len - 1].value);
}