class Plum::Client

Constants

DEFAULT_CONFIG

Attributes

config[R]
host[R]
port[R]
session[R]
socket[R]

Public Class Methods

new(host, port = nil, config = {}) click to toggle source

Creates a new HTTP client. @param host [String | IO] the host to connect, or IO object. @param port [Integer] the port number to connect @param config [Hash<Symbol, Object>] the client configuration

# File lib/plum/client.rb, line 28
def initialize(host, port = nil, config = {})
  if host.is_a?(IO)
    @socket = host
  else
    @host = host
    @port = port || (config[:scheme] == "https" ? 443 : 80)
  end
  @config = DEFAULT_CONFIG.merge(hostname: host).merge(config)
  @started = false
end
start(host, port = nil, config = {}, &block) click to toggle source

Creates a new HTTP client and starts communication. A shorthand for ‘Plum::Client.new(args).start(&block)`

# File lib/plum/client.rb, line 19
def self.start(host, port = nil, config = {}, &block)
  client = self.new(host, port, config)
  client.start(&block)
end

Public Instance Methods

close() click to toggle source

Closes the connection immediately.

# File lib/plum/client.rb, line 69
def close
  @session.close if @session
ensure
  @socket.close if @socket
end
request(headers, body, options = {}, &block) click to toggle source

Creates a new HTTP request. @param headers [Hash<String, String>] the request headers @param body [String] the request body @param options [Hash<Symbol, Object>] request options @param block [Proc] if passed, it will be called when received response headers.

# File lib/plum/client.rb, line 80
def request(headers, body, options = {}, &block)
  raise ArgumentError, ":method and :path headers are required" unless headers[":method"] && headers[":path"]
  @session.request(headers, body, @config.merge(options), &block)
end
resume(response = nil) click to toggle source

Resume communication with the server, until the specified (or all running) requests are complete. @param response [Response] if specified, waits only for the response @return [Response] if parameter response is specified

# File lib/plum/client.rb, line 59
def resume(response = nil)
  if response
    @session.succ until response.failed? || response.finished?
    response
  else
    @session.succ until @session.empty?
  end
end
start() { |self| ... } click to toggle source

Starts communication. If block passed, waits for asynchronous requests and closes the connection after calling the block.

# File lib/plum/client.rb, line 41
def start(&block)
  raise IOError, "Session already started" if @started
  _start
  if block_given?
    begin
      ret = yield(self)
      resume
      return ret
    ensure
      close
    end
  end
  self
end

Private Instance Methods

_connect() click to toggle source

@return [Boolean] http2 nego?

# File lib/plum/client.rb, line 134
def _connect
  @socket = TCPSocket.open(@host, @port)

  if @config[:scheme] == "https"
    ctx = @config[:ssl_context] || new_ssl_ctx
    @socket = OpenSSL::SSL::SSLSocket.new(@socket, ctx)
    @socket.hostname = @config[:hostname] if @socket.respond_to?(:hostname=)
    @socket.sync_close = true
    @socket.connect
    @socket.post_connection_check(@config[:hostname]) if ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE

    @socket.alpn_protocol == "h2"
  end
end
_request_helper(method, path, body, options, &block) click to toggle source
# File lib/plum/client.rb, line 182
def _request_helper(method, path, body, options, &block)
  base = { ":method" => method,
           ":path" => path,
           "user-agent" => @config[:user_agent] }
  base.merge!(options[:headers]) if options[:headers]
  request(base, body, options, &block)
end
_start() click to toggle source
# File lib/plum/client.rb, line 149
def _start
  @started = true

  klass = @config[:http2] ? ClientSession : LegacyClientSession
  nego = @socket || _connect

  if @config[:http2]
    if @config[:scheme] == "https"
      klass = nego ? ClientSession : LegacyClientSession
    else
      klass = UpgradeClientSession
    end
  else
    klass = LegacyClientSession
  end

  @session = klass.new(@socket, @config)
end
new_ssl_ctx() click to toggle source
# File lib/plum/client.rb, line 168
def new_ssl_ctx
  ctx = OpenSSL::SSL::SSLContext.new
  ctx.ssl_version = :TLSv1_2
  ctx.verify_mode = @config[:verify_mode]
  cert_store = OpenSSL::X509::Store.new
  cert_store.set_default_paths
  ctx.cert_store = cert_store
  if @config[:http2]
    ctx.ciphers = "ALL:!" + SSLSocketServerConnection::CIPHER_BLACKLIST.join(":!")
    ctx.alpn_protocols = ["h2", "http/1.1"]
  end
  ctx
end