@@ -709,8 +709,10 @@ pub fn Request(comptime request_action: anytype) type {
709709
710710 // Extract the first json key
711711 const key = firstJsonKey (data );
712- const found_normal_json_response = std .mem .eql (u8 , key , action .action_name ++ "Response" ) or
713- std .mem .eql (u8 , key , action .action_name ++ "Result" );
712+ const found_normal_json_response =
713+ std .mem .eql (u8 , key , action .action_name ++ "Response" ) or
714+ std .mem .eql (u8 , key , action .action_name ++ "Result" ) or
715+ isOtherNormalResponse (response_types .NormalResponse , key );
714716 var raw_response_parsed = false ;
715717 var stream = json .TokenStream .init (data );
716718 const parsed_response_ptr = blk : {
@@ -734,6 +736,7 @@ pub fn Request(comptime request_action: anytype) type {
734736 log .debug ("Appears server has provided a raw response" , .{});
735737 raw_response_parsed = true ;
736738 const ptr = try options .client .allocator .create (response_types .NormalResponse );
739+ errdefer options .client .allocator .destroy (ptr );
737740 @field (ptr .* , std .meta .fields (action .Response )[0 ].name ) =
738741 json .parse (response_types .RawResponse , & stream , parser_options ) catch | e | {
739742 log .err (
@@ -761,6 +764,14 @@ pub fn Request(comptime request_action: anytype) type {
761764 };
762765}
763766
767+ fn isOtherNormalResponse (comptime T : type , first_key : []const u8 ) bool {
768+ const fields = std .meta .fields (T );
769+ if (fields .len != 1 ) return false ;
770+ const first_field = fields [0 ];
771+ if (! @hasDecl (T , "fieldNameFor" )) return false ;
772+ const expected_key = T .fieldNameFor (undefined , first_field .name );
773+ return std .mem .eql (u8 , first_key , expected_key );
774+ }
764775fn coerceFromString (comptime T : type , val : []const u8 ) anyerror ! T {
765776 if (@typeInfo (T ) == .optional ) return try coerceFromString (@typeInfo (T ).optional .child , val );
766777 // TODO: This is terrible...fix it
@@ -2270,3 +2281,59 @@ test "rest_xml_with_input: S3 put object" {
22702281 try std .testing .expectEqualStrings ("AES256" , result .response .server_side_encryption .? );
22712282 try std .testing .expectEqualStrings ("37b51d194a7513e45b56f6524f2d51f2" , result .response .e_tag .? );
22722283}
2284+ test "raw ECR timestamps" {
2285+ // This is a way to test the json parsing. Ultimately the more robust tests
2286+ // should be preferred, but in this case we were tracking down an issue
2287+ // for which the root cause was the incorrect type being passed to the parse
2288+ // routine
2289+ const allocator = std .testing .allocator ;
2290+ const ecr = (Services (.{.ecr }){}).ecr ;
2291+ const options = json.ParseOptions {
2292+ .allocator = allocator ,
2293+ .allow_camel_case_conversion = true , // new option
2294+ .allow_snake_case_conversion = true , // new option
2295+ .allow_unknown_fields = true , // new option. Cannot yet handle non-struct fields though
2296+ .allow_missing_fields = false , // new option. Cannot yet handle non-struct fields though
2297+ };
2298+ var stream = json .TokenStream .init (
2299+ \\{"authorizationData":[{"authorizationToken":"***","expiresAt":1.7385984915E9,"proxyEndpoint":"https://146325435496.dkr.ecr.us-west-2.amazonaws.com"}]}
2300+ );
2301+ const ptr = try json .parse (ecr .get_authorization_token .Response , & stream , options );
2302+ defer json .parseFree (ecr .get_authorization_token .Response , ptr , options );
2303+ }
2304+ test "json_1_1: ECR timestamps" {
2305+ // See: https://github.com/elerch/aws-sdk-for-zig/issues/5
2306+ // const old = std.testing.log_level;
2307+ // defer std.testing.log_level = old;
2308+ // std.testing.log_level = .debug;
2309+ const allocator = std .testing .allocator ;
2310+ var test_harness = TestSetup .init (.{
2311+ .allocator = allocator ,
2312+ .server_response =
2313+ \\{"authorizationData":[{"authorizationToken":"***","expiresAt":1.7385984915E9,"proxyEndpoint":"https://146325435496.dkr.ecr.us-west-2.amazonaws.com"}]}
2314+ // \\{"authorizationData":[{"authorizationToken":"***","expiresAt":1.738598491557E9,"proxyEndpoint":"https://146325435496.dkr.ecr.us-west-2.amazonaws.com"}]}
2315+ ,
2316+ .server_response_headers = &.{
2317+ .{ .name = "Content-Type" , .value = "application/json" },
2318+ .{ .name = "x-amzn-RequestId" , .value = "QBI72OUIN8U9M9AG6PCSADJL4JVV4KQNSO5AEMVJF66Q9ASUAAJG" },
2319+ },
2320+ });
2321+ defer test_harness .deinit ();
2322+ const options = try test_harness .start ();
2323+ const ecr = (Services (.{.ecr }){}).ecr ;
2324+ std .log .debug ("Typeof response {}" , .{@TypeOf (ecr.get_authorization_token.Response {})});
2325+ const call = try test_harness .client .call (ecr.get_authorization_token.Request {}, options );
2326+ defer call .deinit ();
2327+ test_harness .stop ();
2328+ // Request expectations
2329+ try std .testing .expectEqual (std .http .Method .POST , test_harness .request_options .request_method );
2330+ try std .testing .expectEqualStrings ("/" , test_harness .request_options .request_target );
2331+ try test_harness .request_options .expectHeader ("X-Amz-Target" , "AmazonEC2ContainerRegistry_V20150921.GetAuthorizationToken" );
2332+ // Response expectations
2333+ try std .testing .expectEqualStrings ("QBI72OUIN8U9M9AG6PCSADJL4JVV4KQNSO5AEMVJF66Q9ASUAAJG" , call .response_metadata .request_id );
2334+ try std .testing .expectEqual (@as (usize , 1 ), call .response .authorization_data .? .len );
2335+ try std .testing .expectEqualStrings ("***" , call .response .authorization_data .? [0 ].authorization_token .? );
2336+ try std .testing .expectEqualStrings ("https://146325435496.dkr.ecr.us-west-2.amazonaws.com" , call .response .authorization_data .? [0 ].proxy_endpoint .? );
2337+ // try std.testing.expectEqual(@as(i64, 1.73859841557E9), call.response.authorization_data.?[0].expires_at.?);
2338+ try std .testing .expectEqual (@as (f128 , 1.7385984915E9 ), call .response .authorization_data .? [0 ].expires_at .? );
2339+ }
0 commit comments