Class: WSDL::HTTP::Client

Inherits:
Object
  • Object
show all
Includes:
RedirectGuard, Log
Defined in:
lib/wsdl/http/client.rb

Overview

HTTP client using Ruby's stdlib net/http.

This is the default HTTP client used by WSDL. It provides a simple interface for making GET and POST requests with no external dependencies.

Security Defaults

This client applies secure defaults out of the box:

  • Open timeout: 30 seconds
  • Write timeout: 60 seconds
  • Read timeout: 120 seconds
  • Redirect limit: 5 redirects maximum
  • SSL verification: Enabled by default (VERIFY_PEER)
  • Redirect SSRF protection: Blocks redirects to private/reserved networks
  • Scheme downgrade protection: Blocks HTTPS-to-HTTP redirects

These defaults prevent indefinite hangs, redirect loops, man-in-the-middle attacks, and SSRF via open redirects. You can customize them via #config which returns a Config instance.

Redirect Security

HTTP redirects are validated before following. The client blocks redirects that target private or reserved IP addresses to prevent SSRF (Server-Side Request Forgery) attacks. This protects against scenarios where a malicious WSDL endpoint redirects to internal network addresses such as cloud metadata services (+169.254.169.254+), loopback interfaces (+127.0.0.1+), or RFC 1918 private networks.

Blocked address ranges:

  • Loopback: 127.0.0.0/8, ::1
  • Private: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
  • Link-local: 169.254.0.0/16, fe80::/10
  • Current network: 0.0.0.0/8
  • Shared address space: 100.64.0.0/10
  • IETF protocol assignments: 192.0.0.0/24
  • Documentation: 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24
  • 6to4 relay anycast: 192.88.99.0/24
  • Benchmarking: 198.18.0.0/15
  • Reserved/broadcast: 240.0.0.0/4, 255.255.255.255
  • IPv6 unspecified: ::/128
  • NAT64: 64:ff9b::/96, 64:ff9b:1::/48
  • Discard-only: 100::/64
  • Teredo: 2001::/32
  • ORCHID: 2001:10::/28
  • IPv6 documentation: 2001:db8::/32
  • 6to4: 2002::/16

Both IP address literals in the URL and DNS-resolved addresses are checked. HTTPS-to-HTTP scheme downgrades are also blocked.

Examples:

Configuring timeouts

definition = WSDL.parse('https://example.com/service?wsdl')
client = WSDL::Client.new(definition)
client.http.open_timeout = 10
client.http.read_timeout = 60

Using a custom CA certificate

definition = WSDL.parse('https://example.com/service?wsdl')
client = WSDL::Client.new(definition)
client.http.ca_file = '/path/to/ca-bundle.crt'

Client certificate authentication (mutual TLS)

definition = WSDL.parse('https://example.com/service?wsdl')
client = WSDL::Client.new(definition)
client.http.cert = OpenSSL::X509::Certificate.new(File.read('/path/to/client.crt'))
client.http.key = OpenSSL::PKey::RSA.new(File.read('/path/to/client.key'))

Creating a custom HTTP client

class MyHTTPClient
  def initialize
    @connection = Faraday.new
  end

  # Expose the Faraday connection for user configuration
  # (e.g. client.http.options.timeout = 30).
  attr_reader :connection
  alias config connection

  def get(url)
    resp = @connection.get(url)
    WSDL::HTTP::Response.new(status: resp.status, headers: resp.headers, body: resp.body)
  end

  def post(url, headers, body)
    resp = @connection.post(url, body, headers)
    WSDL::HTTP::Response.new(status: resp.status, headers: resp.headers, body: resp.body)
  end
end

WSDL.http_client = MyHTTPClient

See Also:

Constant Summary collapse

REDIRECT_CODES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

HTTP redirect status codes.

[301, 302, 303, 307, 308].freeze
REDIRECT_TO_GET_CODES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Redirect codes that change the method to GET (RFC 7231).

[301, 302, 303].freeze

Constants included from RedirectGuard

RedirectGuard::DNS_RESOLUTION_TIMEOUT, RedirectGuard::PRIVATE_IP_RANGES, RedirectGuard::SENSITIVE_HEADERS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Log

#logger

Constructor Details

#initializeClient

Creates a new Client instance with secure defaults.



120
121
122
# File 'lib/wsdl/http/client.rb', line 120

def initialize
  @config = Config.new
end

Instance Attribute Details

#configConfig (readonly)

Returns the WSDL::HTTP::Config instance for customizing timeouts, SSL, and redirects.

Returns:

  • (Config)

    the configuration object



127
128
129
# File 'lib/wsdl/http/client.rb', line 127

def config
  @config
end

Instance Method Details

#get(url) ⇒ Response

Executes an HTTP GET request.

Parameters:

  • url (String)

    the URL to request

Returns:



133
134
135
136
# File 'lib/wsdl/http/client.rb', line 133

def get(url)
  warn_if_ssl_verification_disabled
  request_with_redirects(:get, URI(url))
end

#post(url, headers, body) ⇒ Response

Executes an HTTP POST request.

Parameters:

  • url (String)

    the URL to post to

  • headers (Hash)

    HTTP headers to include in the request

  • body (String)

    the request body

Returns:



144
145
146
147
# File 'lib/wsdl/http/client.rb', line 144

def post(url, headers, body)
  warn_if_ssl_verification_disabled
  request_with_redirects(:post, URI(url), headers, body)
end

#ssl_verification_disabled?Boolean

Checks if SSL certificate verification is currently disabled.

Returns:

  • (Boolean)

    true if SSL verification is disabled



152
153
154
# File 'lib/wsdl/http/client.rb', line 152

def ssl_verification_disabled?
  @config.verify_mode == OpenSSL::SSL::VERIFY_NONE
end