ninenines / gun

HTTP/1.1, HTTP/2, Websocket client (and more) for Erlang/OTP.
ISC License
891 stars 232 forks source link

Connection closed for a specific host #228

Closed prodis closed 4 years ago

prodis commented 4 years ago

It is not possible to connect to the host apps.correios.com.br with SSL. Via curl works fine.

Gun

# Timeout
iex> {:ok, conn} = :gun.open('apps.correios.com.br', 443)
...> :gun.await_up(conn)
{:error, :timeout}

# Setting a long connection timeout
iex> {:ok, conn} = :gun.open('apps.correios.com.br', 443)
...> :gun.await_up(conn, 30000)
{:error, {:shutdown, :closed}}

Curl

curl -v 'https://apps.correios.com.br/SigepMasterJPA/AtendeClienteService/AtendeCliente' \
-H 'Content-Type: application/xml; charset=utf8' \
-d '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cli="http://cliente.bean.master.sigep.bsb.correios.com.br/">
    <soapenv:Header />
    <soapenv:Body>
        <cli:consultaCEP>
            <cep>13212-070</cep>
        </cli:consultaCEP>
    </soapenv:Body>
</soapenv:Envelope>'

*   Trying 201.48.198.92...
* TCP_NODELAY set
* Connected to apps.correios.com.br (201.48.198.92) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / AES256-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: OU=Domain Control Validated; CN=*.correios.com.br
*  start date: Nov 10 12:36:16 2017 GMT
*  expire date: Nov 10 12:36:16 2020 GMT
*  subjectAltName: host "apps.correios.com.br" matched cert's "*.correios.com.br"
*  issuer: C=BE; O=GlobalSign nv-sa; CN=AlphaSSL CA - SHA256 - G2
*  SSL certificate verify ok.
> POST /SigepMasterJPA/AtendeClienteService/AtendeCliente HTTP/1.1
> Host: apps.correios.com.br
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Type: application/xml; charset=utf8
> Content-Length: 349
>
* upload completely sent off: 349 out of 349 bytes
< HTTP/1.1 200 OK
< Date: Sat, 02 May 2020 11:23:28 GMT
< Server: Apache/2.4.10 (Debian)
< Content-Type: text/xml;charset=UTF-8
< Content-Length: 422
< Vary: Accept-Encoding,User-Agent
< Set-Cookie: app-%3FINTERNO%3Fpool_proxy_app_sigep_443=PNCCAIAK; Expires=Sat, 02-May-2020 11:43:27 GMT; Path=/
< Set-Cookie: sto-id-%3FEXTERNO_2%3Fpool_Proxy_reverso_Apps_443=KPABKIMA; Expires=Sat, 02-May-2020 11:43:27 GMT; Path=/
<
* Connection #0 to host apps.correios.com.br left intact
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:consultaCEPResponse xmlns:ns2="http://cliente.bean.master.sigep.bsb.correios.com.br/"><return><bairro>Parque Residencial Eloy Chaves</bairro><cep>13212070</cep><cidade>Jundiaí</cidade><complemento2></complemento2><end>Avenida Benedicto Castilho de Andrade</end><uf>SP</uf></return></ns2:consultaCEPResponse></soap:Body></soap:Envelope>* Closing connection 0

Using other Elixir/Erlang HTTP clients

Similar problem happens with Mint, httpc, ibrowse, and hackney with proxy, but it works fine using hackney without proxy. See this issue in hackney and this issue in Mint for more details.

Integration tests

I created some tests to run in Travis CI using different versions of Elixir and OTP: https://github.com/prodis/correios-cep-elixir/blob/a18b1536d9651bee24b9edd5b35df3c5912baed1/test/integration/gun_test.exs

Results in Travis: https://travis-ci.org/github/prodis/correios-cep-elixir/builds/682440205

My system info

* cowlib 2.6.0 (Hex package) (rebar3)
  locked at 2.6.0 (cowlib) 45a1a08e
  ok
* gun 1.3.2 (Hex package) (rebar3)
  locked at 1.3.2 (gun) ba323f0a
  ok

➜  ~ elixir -v
Erlang/OTP 22 [erts-10.7.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe] [dtrace]

Elixir 1.10.2 (compiled with Erlang/OTP 22)

➜  ~ mix hex.info
Hex:    0.20.5
Elixir: 1.10.2
OTP:    22.3.2

Built with: Elixir 1.10.0 and OTP 21.3

➜  ~ curl --version
curl 7.64.1 (x86_64-apple-darwin19.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.39.2
Release-Date: 2019-03-27
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL UnixSockets
essen commented 4 years ago

Works fine.

1> application:ensure_all_started(gun).
{ok,[crypto,asn1,public_key,ssl,cowlib,gun]}
2> {ok, Pid} = gun:open("apps.correios.com.br", 443, #{tls_opts => [{ciphers, ["AES256-SHA256"]}, {versions, ['tlsv1.2']}]}).
{ok,<0.110.0>}
3> gun:await_up(Pid).
{ok,http}

Gun does not make TLS work magically out of the box for you, and due to the transition to TLS 1.3 there's no configuration that works everywhere right now anyway.

prodis commented 4 years ago

Thanks for the explanation. I suppose your example is using version 2.0.0-pre.2 and not 1.3.2.

An example in Elixir to be used as a self-reference:

iex(1)> {:ok, conn} = :gun.open('apps.correios.com.br', 443, %{tls_opts: [ciphers: ['AES256-SHA256'], versions: [:"tlsv1.2"]]})
{:ok, #PID<0.273.0>}
iex(2)> :gun.await_up(conn)
{:ok, :http}
essen commented 4 years ago

Yes.