@@ -615,8 +615,10 @@ maybe_get_role_from_instance_metadata() ->
615615% % Instance Metadata service, returning the Region if successful.
616616% % end.
617617parse_az_response ({error , _ }) -> {error , undefined };
618- parse_az_response ({ok , {{_ , 200 , _ }, _ , Body }})
619- -> {ok , region_from_availability_zone (Body )};
618+ parse_az_response ({ok , {{_ , 200 , _ }, _ , Body }}) when is_binary (Body ) ->
619+ {ok , region_from_availability_zone (binary_to_list (Body ))};
620+ parse_az_response ({ok , {{_ , 200 , _ }, _ , Body }}) ->
621+ {ok , region_from_availability_zone (Body )};
620622parse_az_response ({ok , {{_ , _ , _ }, _ , _ }}) -> {error , undefined }.
621623
622624
@@ -626,7 +628,8 @@ parse_az_response({ok, {{_, _, _}, _, _}}) -> {error, undefined}.
626628% % body value is the string to process.
627629% % end.
628630parse_body_response ({error , _ }) -> {error , undefined };
629- parse_body_response ({ok , {{_ , 200 , _ }, _ , Body }}) -> {ok , Body };
631+ parse_body_response ({ok , {{_ , 200 , _ }, _ , Body }}) when is_binary (Body ) -> {ok , binary_to_list (Body )};
632+ parse_body_response ({ok , {{_ , 200 , _ }, _ , Body }}) when is_list (Body ) -> {ok , Body };
630633parse_body_response ({ok , {{_ , 401 , _ }, _ , _ }}) ->
631634 ? LOG_ERROR (get_instruction_on_instance_metadata_error (" Unauthorized instance metadata service request." )),
632635 {error , undefined };
@@ -655,9 +658,35 @@ parse_credentials_response({ok, {{_, 200, _}, _, Body}}) ->
655658% % @doc Wrap httpc:get/4 to simplify Instance Metadata service v2 requests
656659% % @end
657660perform_http_get_instance_metadata (URL ) ->
658- ? LOG_DEBUG (" Querying instance metadata service: ~tp " , [URL ]),
659- httpc :request (get , {URL , instance_metadata_request_headers ()},
660- [{timeout , ? DEFAULT_HTTP_TIMEOUT }], []).
661+ ? LOG_DEBUG (" Querying instance metadata service: ~tp " , [URL ]),
662+ % Parse metadata service URL
663+ {Host , Port , Path } = rabbitmq_aws :parse_uri (URL ),
664+ % Simple Gun connection for metadata service
665+ Opts = #{transport => tcp , protocols => [http ]}, % HTTP only, no TLS
666+ case gun :open (Host , Port , Opts ) of
667+ {ok , ConnPid } ->
668+ case gun :await_up (ConnPid , 5000 ) of
669+ {ok , _Protocol } ->
670+ Headers = instance_metadata_request_headers (),
671+ StreamRef = gun :get (ConnPid , Path , Headers ),
672+ Result = case gun :await (ConnPid , StreamRef , ? DEFAULT_HTTP_TIMEOUT ) of
673+ {response , fin , Status , RespHeaders } ->
674+ {ok , {{http_version , Status , rabbitmq_aws :status_text (Status )}, RespHeaders , <<>>}};
675+ {response , nofin , Status , RespHeaders } ->
676+ {ok , Body } = gun :await_body (ConnPid , StreamRef , ? DEFAULT_HTTP_TIMEOUT ),
677+ {ok , {{http_version , Status , rabbitmq_aws :status_text (Status )}, RespHeaders , Body }};
678+ {error , Reason } ->
679+ {error , Reason }
680+ end ,
681+ gun :close (ConnPid ),
682+ Result ;
683+ {error , Reason } ->
684+ gun :close (ConnPid ),
685+ {error , Reason }
686+ end ;
687+ {error , Reason } ->
688+ {error , Reason }
689+ end .
661690
662691-spec get_instruction_on_instance_metadata_error (string ()) -> string ().
663692% % @doc Return error message on failures related to EC2 Instance Metadata Service with a reference to AWS document.
@@ -717,6 +746,7 @@ region_from_availability_zone(Value) ->
717746% % @doc Attempt to obtain EC2 IMDSv2 token.
718747% % @end
719748load_imdsv2_token () ->
749+ <<<<<<< HEAD
720750 TokenUrl = imdsv2_token_url (),
721751 ? LOG_INFO (" Attempting to obtain EC2 IMDSv2 token from ~tp ..." , [TokenUrl ]),
722752 case httpc :request (put , {TokenUrl , [{? METADATA_TOKEN_TTL_HEADER , integer_to_list (? METADATA_TOKEN_TTL_SECONDS )}]},
@@ -733,6 +763,58 @@ load_imdsv2_token() ->
733763 " Falling back to EC2 IMDSv1 for now. It is recommended to use EC2 IMDSv2." ), [Other ]),
734764 undefined
735765 end .
766+ =======
767+ TokenUrl = imdsv2_token_url (),
768+ rabbit_log :info (" Attempting to obtain EC2 IMDSv2 token from ~tp ..." , [TokenUrl ]),
769+ % Parse metadata service URL
770+ {Host , Port , Path } = rabbitmq_aws :parse_uri (TokenUrl ),
771+ % Simple Gun connection for metadata service
772+ Opts = #{transport => tcp , protocols => [http ]}, % HTTP only, no TLS
773+ case gun :open (Host , Port , Opts ) of
774+ {ok , ConnPid } ->
775+ case gun :await_up (ConnPid , 5000 ) of
776+ {ok , _Protocol } ->
777+ % PUT request with IMDSv2 token TTL header
778+ Headers = [{? METADATA_TOKEN_TTL_HEADER , integer_to_list (? METADATA_TOKEN_TTL_SECONDS )}],
779+ StreamRef = gun :put (ConnPid , Path , Headers , <<>>),
780+ Result = case gun :await (ConnPid , StreamRef , ? DEFAULT_HTTP_TIMEOUT ) of
781+ {response , fin , 200 , _RespHeaders } ->
782+ rabbit_log :debug (" Successfully obtained EC2 IMDSv2 token." ),
783+ <<>>; % Empty body for fin response
784+ {response , nofin , 200 , _RespHeaders } ->
785+ {ok , Body } = gun :await_body (ConnPid , StreamRef , ? DEFAULT_HTTP_TIMEOUT ),
786+ rabbit_log :debug (" Successfully obtained EC2 IMDSv2 token." ),
787+ binary_to_list (Body );
788+ {response , _ , 400 , _RespHeaders } ->
789+ rabbit_log :warning (" Failed to obtain EC2 IMDSv2 token: Missing or Invalid Parameters – The PUT request is not valid." ),
790+ undefined ;
791+ {error , Reason } ->
792+ rabbit_log :warning (
793+ get_instruction_on_instance_metadata_error (" Failed to obtain EC2 IMDSv2 token: ~tp . "
794+ " Falling back to EC2 IMDSv1 for now. It is recommended to use EC2 IMDSv2." ), [Reason ]),
795+ undefined ;
796+ Other ->
797+ rabbit_log :warning (
798+ get_instruction_on_instance_metadata_error (" Failed to obtain EC2 IMDSv2 token: ~tp . "
799+ " Falling back to EC2 IMDSv1 for now. It is recommended to use EC2 IMDSv2." ), [Other ]),
800+ undefined
801+ end ,
802+ gun :close (ConnPid ),
803+ Result ;
804+ {error , Reason } ->
805+ gun :close (ConnPid ),
806+ rabbit_log :warning (
807+ get_instruction_on_instance_metadata_error (" Failed to connect for EC2 IMDSv2 token: ~tp . "
808+ " Falling back to EC2 IMDSv1 for now. It is recommended to use EC2 IMDSv2." ), [Reason ]),
809+ undefined
810+ end ;
811+ {error , Reason } ->
812+ rabbit_log :warning (
813+ get_instruction_on_instance_metadata_error (" Failed to open connection for EC2 IMDSv2 token: ~tp . "
814+ " Falling back to EC2 IMDSv1 for now. It is recommended to use EC2 IMDSv2." ), [Reason ]),
815+ undefined
816+ end .
817+ >>>>>>> f04e9ce16a (Fully remove httpc )
736818
737819
738820- spec instance_metadata_request_headers () -> headers ().
0 commit comments