JuliaCloud / AWS.jl

Julia interface to AWS
MIT License
160 stars 62 forks source link

SESv2 using the wrong endpoint #408

Open jsahil730 opened 3 years ago

jsahil730 commented 3 years ago

SESv2 tries to access ses.<region>.amazonaws.com while instead the endpoints for this api are supposed to be under email.<region>.amazonaws.com; therefore a DNSError is observed with the request.

julia> SESv2.send_email(Dict())
ERROR: DNSError: ses.ap-south-1.amazonaws.com, unknown node or service (EAI_NONAME)
Stacktrace:
  [1] getalladdrinfo(host::String)
    @ Sockets C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Sockets\src\addrinfo.jl:113
  [2] getalladdrinfo
    @ C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Sockets\src\addrinfo.jl:122 [inlined]
  [3] getconnection(::Type{Sockets.TCPSocket}, host::SubString{String}, port::String; keepalive::Bool, connect_timeout::Int64, readtimeout::Int64,
 kw::Base.Iterators.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol, Symbol}, NamedTuple{(:require_ssl_verification, :iofunction, :response_stream), Tuple{Bool, Nothing, Nothing}}})
    @ HTTP.ConnectionPool C:\Users\DELL\.julia\packages\HTTP\4AvE2\src\ConnectionPool.jl:659
  [4] #getconnection#29
    @ C:\Users\DELL\.julia\packages\HTTP\4AvE2\src\ConnectionPool.jl:728 [inlined]
  [5] newconnection(pod::HTTP.ConnectionPool.Pod, T::Type, host::SubString{String}, port::SubString{String}, pipeline_limit::Int64, require_ssl_verification::Bool, idle_timeout::Int64; kw::Base.Iterators.Pairs{Symbol, Nothing, Tuple{Symbol, Symbol}, NamedTuple{(:iofunction, :response_stream), Tuple{Nothing, Nothing}}})
    @ HTTP.ConnectionPool C:\Users\DELL\.julia\packages\HTTP\4AvE2\src\ConnectionPool.jl:626
  [6] getconnection(::Type{HTTP.ConnectionPool.Transaction{MbedTLS.SSLContext}}, host::SubString{String}, port::SubString{String}; connection_limit::Int64, pipeline_limit::Int64, idle_timeout::Int64, reuse_limit::Int64, require_ssl_verification::Bool, kw::Base.Iterators.Pairs{Symbol, Nothing, Tuple{Symbol, Symbol}, NamedTuple{(:iofunction, :response_stream), Tuple{Nothing, Nothing}}})
    @ HTTP.ConnectionPool C:\Users\DELL\.julia\packages\HTTP\4AvE2\src\ConnectionPool.jl:570
  [7] request(::Type{HTTP.ConnectionRequest.ConnectionPoolLayer{HTTP.StreamRequest.StreamLayer{Union{}}}}, url::URIs.URI, req::HTTP.Messages.Request, body::String; proxy::Nothing, socket_type::Type, reuse_limit::Int64, kw::Base.Iterators.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol, Symbol}, NamedTuple{(:iofunction, :require_ssl_verification, :response_stream), Tuple{Nothing, Bool, Nothing}}})
    @ HTTP.ConnectionRequest C:\Users\DELL\.julia\packages\HTTP\4AvE2\src\ConnectionRequest.jl:85
  [8] request(::Type{HTTP.ExceptionRequest.ExceptionLayer{HTTP.ConnectionRequest.ConnectionPoolLayer{HTTP.StreamRequest.StreamLayer{Union{}}}}}, ::URIs.URI, ::Vararg{Any, N} where N; kw::Base.Iterators.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol, Symbol}, NamedTuple{(:iofunction, :require_ssl_verification, :response_stream), Tuple{Nothing, Bool, Nothing}}})
    @ HTTP.ExceptionRequest C:\Users\DELL\.julia\packages\HTTP\4AvE2\src\ExceptionRequest.jl:19
  [9] request(::Type{HTTP.MessageRequest.MessageLayer{HTTP.ExceptionRequest.ExceptionLayer{HTTP.ConnectionRequest.ConnectionPoolLayer{HTTP.StreamRequest.StreamLayer{Union{}}}}}}, method::String, url::URIs.URI, headers::Vector{Pair{SubString{String}, SubString{String}}}, body::String; http_version::VersionNumber, target::String, parent::Nothing, iofunction::Nothing, kw::Base.Iterators.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol}, NamedTuple{(:require_ssl_verification, :response_stream), Tuple{Bool, Nothing}}})
    @ HTTP.MessageRequest C:\Users\DELL\.julia\packages\HTTP\4AvE2\src\MessageRequest.jl:66
 [10] request(::Type{HTTP.BasicAuthRequest.BasicAuthLayer{HTTP.MessageRequest.MessageLayer{HTTP.ExceptionRequest.ExceptionLayer{HTTP.ConnectionRequest.ConnectionPoolLayer{HTTP.StreamRequest.StreamLayer{Union{}}}}}}}, method::String, url::URIs.URI, headers::Vector{Pair{SubString{String}, SubString{String}}}, body::String; kw::Base.Iterators.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol}, NamedTuple{(:require_ssl_verification, :response_stream), Tuple{Bool, Nothing}}})
    @ HTTP.BasicAuthRequest C:\Users\DELL\.julia\packages\HTTP\4AvE2\src\BasicAuthRequest.jl:28
 [11] macro expansion
    @ C:\Users\DELL\.julia\packages\Mocking\U41JO\src\mock.jl:29 [inlined]
 [12] macro expansion
    @ C:\Users\DELL\.julia\packages\AWS\MbHfM\src\utilities\request.jl:176 [inlined]
 [13] macro expansion
    @ C:\Users\DELL\.julia\packages\Retry\vS1bg\src\repeat_try.jl:192 [inlined]
 [14] _http_request(http_backend::AWS.HTTPBackend, request::Request)
    @ AWS C:\Users\DELL\.julia\packages\AWS\MbHfM\src\utilities\request.jl:169
 [15] macro expansion
    @ C:\Users\DELL\.julia\packages\Mocking\U41JO\src\mock.jl:29 [inlined]
 [16] macro expansion
    @ C:\Users\DELL\.julia\packages\AWS\MbHfM\src\utilities\request.jl:79 [inlined]
 [17] macro expansion
    @ C:\Users\DELL\.julia\packages\Retry\vS1bg\src\repeat_try.jl:192 [inlined]
 [18] submit_request(aws::AWSConfig, request::Request; return_headers::Bool)
    @ AWS C:\Users\DELL\.julia\packages\AWS\MbHfM\src\utilities\request.jl:76
 [19] (::RestJSONService)(request_method::String, request_uri::String, args::Dict{String, Any}; aws_config::AWSConfig)
    @ AWS C:\Users\DELL\.julia\packages\AWS\MbHfM\src\AWS.jl:353
 [20] send_email(Content::Dict{Any, Any}; aws_config::AWSConfig)
    @ Main.SESv2 C:\Users\DELL\.julia\packages\AWS\MbHfM\src\services\sesv2.jl:1465
 [21] send_email(Content::Dict{Any, Any})
    @ Main.SESv2 C:\Users\DELL\.julia\packages\AWS\MbHfM\src\services\sesv2.jl:1465
 [22] top-level scope
    @ REPL[5]:1

Here is the link to the corresponding API details in botocore.

Can you suggest a good workaround for now as well? Thanks!

iamed2 commented 3 years ago

The main issue is this: https://github.com/JuliaCloud/AWS.jl/blob/master/src/api_generation/low_level.jl#L56

We need to have our services differentiate between signing name and endpoint prefix.

This code needs to use signing name: https://github.com/JuliaCloud/AWS.jl/blob/master/src/utilities/sign.jl#L49

But I believe all other code should use endpoint prefix.

@mattBrzezinski's suggested workaround from the JuliaLang slack is to use SESv1 for now.

krishvishal commented 3 years ago

For now I'm hardcoding the endpoint to get SESv2 working. Its a hack.

you can take a look at here: https://github.com/krishvishal/AWS.jl/blob/master/src/AWS.jl#L178

iamed2 commented 3 years ago

Well, I looked into it and SESv1 has always used the same endpoint, so that's not a solution.

@krishvishal If you made that use a dict (const CUSTOM_ENDPOINTS = Dict("ses"=>"email")) so it could be extended for more services I would accept the PR as a temporary fix!