@@ -588,7 +588,7 @@ defmodule Mix.Utils do
588588
589589 # Starting an HTTP client profile allows us to scope
590590 # the effects of using an HTTP proxy to this function
591- { :ok , _pid } = :inets . start ( :httpc , [ { : profile, :mix } ] )
591+ { :ok , _pid } = :inets . start ( :httpc , profile: :mix )
592592
593593 headers = [ { 'user-agent' , 'Mix/#{ System . version ( ) } ' } ]
594594 request = { :binary . bin_to_list ( path ) , headers }
@@ -601,7 +601,28 @@ defmodule Mix.Utils do
601601 # If a proxy environment variable was supplied add a proxy to httpc.
602602 http_options = [ relaxed: true ] ++ proxy_config ( path )
603603
604- case :httpc . request ( :get , request , http_options , [ body_format: :binary ] , :mix ) do
604+ case httpc_request ( request , http_options ) do
605+ { :error , { :failed_connect , [ { :to_address , _ } , { inet , _ , reason } ] } }
606+ when inet in [ :inet , :inet6 ] and reason in [ :ehostunreach , :enetunreach ] ->
607+ :httpc . set_options ( [ ipfamily: fallback ( inet ) ] , :mix )
608+ request |> httpc_request ( http_options ) |> httpc_response ( )
609+
610+ response ->
611+ httpc_response ( response )
612+ end
613+ after
614+ :inets . stop ( :httpc , :mix )
615+ end
616+
617+ defp fallback ( :inet ) , do: :inet6
618+ defp fallback ( :inet6 ) , do: :inet
619+
620+ defp httpc_request ( request , http_options ) do
621+ :httpc . request ( :get , request , http_options , [ body_format: :binary ] , :mix )
622+ end
623+
624+ defp httpc_response ( response ) do
625+ case response do
605626 { :ok , { { _ , status , _ } , _ , body } } when status in 200 .. 299 ->
606627 { :ok , body }
607628
@@ -611,8 +632,6 @@ defmodule Mix.Utils do
611632 { :error , reason } ->
612633 { :remote , "httpc request failed with: #{ inspect ( reason ) } " }
613634 end
614- after
615- :inets . stop ( :httpc , :mix )
616635 end
617636
618637 defp file? ( path ) do
0 commit comments