-
Notifications
You must be signed in to change notification settings - Fork 996
Description
Basic Info
- Faraday Version: 1.3.0
- Ruby Version: 2.7.2
- Ruby on Rails Version: 6.1
Issue description
I'm trying to make a POST call to a secured host (which is only available from certain machines/IPs). However Faraday throws a Net::ReadTimeout exception while I'm doing it (and before throwing it, it freezes for a substantial amount of time waiting for something).
BUT! The same call via cURL works perfectly fine, it returns the data from the API momentarily (so it's not like Faraday gives too little time before throwing a timeout). It also works if I rewrite the code using Net::HTTP.
This is a persistent issue for me, the behavior above is happening every time I try it.
Please note I will replace the real host name in the examples below because it won't make any difference since it would be impossible for you guys to call it (this a host available from certain IPs only).
Steps to reproduce
My Faraday call which I'm trying to run within rails c
console.
begin
url = 'https://www.somehost.fr/public-api/v1/candidate/account'
headers = { 'Content-Type' => 'application/json;charset=UTF-8' }
connection = Faraday.new(url: url, headers: headers)
response = connection.post do |request|
request.body = {
email: '[email protected]',
password: 'password',
loginAfterSuccess: true,
remember_me: true
}.to_json
end
puts response.body
rescue StandardError => e
puts e.class
puts e.message
puts e.backtrace
end
It gives the following:
Faraday::TimeoutError
Net::ReadTimeout with #<TCPSocket:(closed)>
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/net/protocol.rb:217:in `rbuf_fill'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/net/protocol.rb:191:in `readuntil'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/net/protocol.rb:201:in `readline'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/net/http/response.rb:42:in `read_status_line'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/net/http/response.rb:31:in `read_new'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/net/http.rb:1528:in `block in transport_request'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/net/http.rb:1519:in `catch'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/net/http.rb:1519:in `transport_request'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/net/http.rb:1492:in `request'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/airbrake-11.0.1/lib/airbrake/rails/net_http.rb:11:in `block in request'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/airbrake-11.0.1/lib/airbrake/rack.rb:25:in `capture_timing'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/airbrake-11.0.1/lib/airbrake/rails/net_http.rb:10:in `request'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/faraday-net_http-1.0.0/lib/faraday/adapter/net_http.rb:152:in `block in request_via_request_method'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/net/http.rb:933:in `start'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/faraday-net_http-1.0.0/lib/faraday/adapter/net_http.rb:146:in `request_via_request_method'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/faraday-net_http-1.0.0/lib/faraday/adapter/net_http.rb:131:in `request_with_wrapped_block'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/faraday-net_http-1.0.0/lib/faraday/adapter/net_http.rb:122:in `perform_request'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/faraday-net_http-1.0.0/lib/faraday/adapter/net_http.rb:66:in `block in call'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/faraday-1.3.0/lib/faraday/adapter.rb:60:in `connection'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/faraday-net_http-1.0.0/lib/faraday/adapter/net_http.rb:64:in `call'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/faraday-1.3.0/lib/faraday/request/url_encoded.rb:25:in `call'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/faraday-1.3.0/lib/faraday/rack_builder.rb:154:in `build_response'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/faraday-1.3.0/lib/faraday/connection.rb:492:in `run_request'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/faraday-1.3.0/lib/faraday/connection.rb:279:in `post'
(irb):5:in `irb_binding'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb/workspace.rb:114:in `eval'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb/workspace.rb:114:in `evaluate'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb/context.rb:459:in `evaluate'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb.rb:541:in `block (2 levels) in eval_input'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb.rb:704:in `signal_status'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb.rb:538:in `block in eval_input'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb/ruby-lex.rb:166:in `block (2 levels) in each_top_level_statement'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb/ruby-lex.rb:151:in `loop'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb/ruby-lex.rb:151:in `block in each_top_level_statement'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb/ruby-lex.rb:150:in `catch'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb/ruby-lex.rb:150:in `each_top_level_statement'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb.rb:537:in `eval_input'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb.rb:472:in `block in run'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb.rb:471:in `catch'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb.rb:471:in `run'
/usr/share/rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/irb.rb:400:in `start'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/railties-6.1.0/lib/rails/commands/console/console_command.rb:70:in `start'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/railties-6.1.0/lib/rails/commands/console/console_command.rb:19:in `start'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/railties-6.1.0/lib/rails/commands/console/console_command.rb:102:in `perform'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/railties-6.1.0/lib/rails/command/base.rb:69:in `perform'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/railties-6.1.0/lib/rails/command.rb:50:in `invoke'
/opt/applications/app-name/shared/bundle/ruby/2.7.0/gems/railties-6.1.0/lib/rails/commands.rb:18:in `<top (required)>'
./bin/rails:11:in `require'
./bin/rails:11:in `<main>'
This is my cURL request (which I think is almost identical to the Faraday code above?):
curl -v --compressed -H 'Content-Type: application/json;charset=UTF-8' -d '{"email":"[email protected]","password":"password","loginAfterSuccess":true,"remember_me":true}' "https://www.somehost.fr/public-api/v1/candidate/account"
This is what I get in response (once again, I replaced real hosts, IPs, and other sensitive info here):
* Trying 1.2.3.4...
* Connected to www.somehost.fr (1.2.3.4) port 443 (#0)
* found 129 certificates in /etc/ssl/certs/ca-certificates.crt
* found 520 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_256_GCM_SHA384
* server certificate verification OK
* server certificate status verification SKIPPED
* common name: somehost.de (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject: C=DE,ST=Berlin,L=Berlin,O=Company Name,CN=somehost.de
* start date: Thu, 12 Mar 2020 00:00:00 GMT
* expire date: Fri, 11 Jun 2021 12:00:00 GMT
* issuer: C=US,O=DigiCert Inc,CN=DigiCert SHA2 Secure Server CA
* compression: NULL
* ALPN, server accepted to use http/1.1
> POST /public-api/v1/candidate/account HTTP/1.1
> Host: www.somehost.fr
> User-Agent: curl/7.47.0
> Accept: */*
> Accept-Encoding: deflate, gzip
> Content-Type: application/json;charset=UTF-8
> Content-Length: 102
>
* upload completely sent off: 102 out of 102 bytes
< HTTP/1.1 201 Created
< Content-Type: application/json;charset=utf-8
< Expires: Fri, 12 Mar 2021 08:53:49 GMT
< Pragma: no-cache
< Cache-Control: no-cache, no-store, must-revalidate
< x-instance: 5.69/web
< x-xss-protection: 1; mode=block: 10.147.4.207
< x-content-type-options: nosniff: 10.147.4.207
< Content-Encoding: gzip
< Vary: Accept-Encoding
< Content-Length: 808
< Date: Fri, 12 Mar 2021 08:53:49 GMT
< Connection: keep-alive
< Set-Cookie: cfid=00001111-aaaa-bbbb-aa19-aa111c111111;Path=/;Expires=Thu, 01-Apr-2021 10:31:52 UTC;HTTPOnly;HttpOnly;Secure
< Set-Cookie: cftoken=0;Path=/;Expires=Thu, 01-Apr-2021 10:31:52 UTC;HTTPOnly;HttpOnly;Secure
< Set-Cookie: cfid=00001111-aaaa-bbbb-aa19-aa111c111111;path=/;HTTPOnly;HttpOnly;Secure
< Set-Cookie: cftoken=0;path=/;HTTPOnly;HttpOnly;Secure
< Set-Cookie: USER_HASH_ID=00001111-aaaa-bbbb-aa19-aa111c111111;Path=/;Expires=Sat, 12-Mar-2022 08:53:48 UTC
< Set-Cookie: V5=1;Path=/;Expires=Thu, 10-Jun-2021 08:53:48 UTC
< Set-Cookie: UXUSER=%20%3B%20%3B%20%3B;Path=/;Expires=Sun, 11-Apr-2021 08:53:48 UTC
< Set-Cookie: UXUSER=BLACKLIST%3BA%3B%20%3B;Path=/;Expires=Sun, 11-Apr-2021 08:53:48 UTC
< Set-Cookie: COMPANYV5LANG=fr;Path=/;Expires=Sat, 11-Mar-2051 16:45:18 UTC
< Set-Cookie: COMPANYV5LANG=fr;Path=/;Expires=Sat, 12-Mar-2022 08:53:48 UTC
< Set-Cookie: authHash=;Path=/;Expires=Fri, 12-Mar-2021 08:53:48 UTC
< Set-Cookie: CIDFORRETURNINGVISIT=DirectEntry;Path=/;Expires=Sat, 12-Mar-2022 08:53:48 UTC
< Set-Cookie: CIDFORRETURNINGVISITISSET=%22yes%22;Path=/;Expires=Sat, 12-Mar-2022 08:53:48 UTC
< Set-Cookie: SIMID=4361323;Path=/
< Set-Cookie: JSESSIONID=1111EDB222291EE3333BED7C6B4D4444; Path=/; HttpOnly;HttpOnly;Secure
< Set-Cookie: authHash=SomeLongJWT;Path=/;Expires=Fri, 12-Mar-2021 08:55:49 UTC;HTTPOnly
< Set-Cookie: STRGR=1;Path=/;Expires=Sun, 05-Mar-2051 08:53:49 UTC
< Set-Cookie: ONLINE_CF=10.147.5.69; path=/
< Server: API Gateway
< Strict-Transport-Security: max-age=15552000 ; IncludeSubDomains
< Set-Cookie: bm_sz=SomeLongCode; Domain=.somehost.fr; Path=/; Expires=Fri, 12 Mar 2021 12:53:48 GMT; Max-Age=14399; HttpOnly
< Set-Cookie: _abck=SomeLongCode; Domain=.somehost.fr; Path=/; Expires=Sat, 12 Mar 2022 08:53:49 GMT; Max-Age=31536000; Secure
<
{"authHash":"SomeLongJWT","userLoggedIn":true,"success":true,"candidateId":1122333,"confirmationEmailSent":true}
* Connection #0 to host www.somehost.fr left intact
And this is the call I make using Net::HTTP:
uri = URI('https://www.somehost.fr/public-api/v1/candidate/account')
headers = { 'Content-Type': 'application/json;charset=UTF-8' }
Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
request = Net::HTTP::Post.new(uri, headers)
request.body = {
email: '[email protected]',
password: 'password',
loginAfterSuccess: true,
remember_me: true
}.to_json
response = http.request(request)
puts response.body
end
And I get the correct response this way:
{"authHash":"SomeJWT","userLoggedIn":true,"success":true,"candidateId":1112233,"confirmationEmailSent":true}
Am I missing some option or flag I should be passing with Faraday? Or does it look like a bug in Faraday? Any help would be appreciated!