Class: HTTP::Client

Inherits:
Object
  • Object
show all
Includes:
Chainable
Defined in:
lib/http/client.rb

Overview

Clients make requests and receive responses

Constant Summary collapse

BUFFER_SIZE =

Input buffer size

16_384

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Chainable

#accept, #auth, #basic_auth, #connect, #default_headers, #default_headers=, #default_options=, #delete, #follow, #get, #head, #options, #patch, #post, #put, #stream, #trace, #via, #with_headers

Constructor Details

#initialize(default_options = {}) ⇒ Client

Returns a new instance of Client.



17
18
19
20
21
# File 'lib/http/client.rb', line 17

def initialize(default_options = {})
  @default_options = HTTP::Options.new(default_options)
  @parser = HTTP::Response::Parser.new
  @socket = nil
end

Instance Attribute Details

#default_optionsObject (readonly)

Returns the value of attribute default_options.



15
16
17
# File 'lib/http/client.rb', line 15

def default_options
  @default_options
end

Instance Method Details

#perform(req, options) ⇒ Object

Perform a single (no follow) HTTP request



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/http/client.rb', line 44

def perform(req, options)
  # finish previous response if client was re-used
  # TODO: this is pretty wrong, as socket shoud be part of response
  #       connection, so that re-use of client will not break multiple
  #       chunked responses
  finish_response

  uri = req.uri

  # TODO: keep-alive support
  @socket = options[:socket_class].open(req.socket_host, req.socket_port)
  @socket = start_tls(@socket, uri.host, options) if uri.is_a?(URI::HTTPS) && !req.using_proxy?

  req.stream @socket

  read_headers!

  body = Response::Body.new(self)
  res  = Response.new(@parser.status_code, @parser.http_version, @parser.headers, body, uri)

  finish_response if :head == req.verb

  res
end

#readpartial(size = BUFFER_SIZE) ⇒ String, Nil

Read a chunk of the body

Returns:

  • (String)

    data chunk

  • (Nil)

    when no more data left



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/http/client.rb', line 73

def readpartial(size = BUFFER_SIZE)
  return unless @socket

  begin
    read_more size
    finished = @parser.finished?
  rescue EOFError
    finished = true
  end

  chunk = @parser.chunk

  finish_response if finished

  chunk.to_s
end

#request(verb, uri, opts = {}) ⇒ Object

Make an HTTP request



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/http/client.rb', line 24

def request(verb, uri, opts = {})
  opts    = @default_options.merge(opts)
  uri     = make_request_uri(uri, opts)
  headers = opts.headers
  proxy   = opts.proxy
  body    = make_request_body(opts, headers)

  req = HTTP::Request.new(verb, uri, headers, proxy, body)
  res = perform req, opts

  if opts.follow
    res = Redirector.new(opts.follow).perform req, res do |request|
      perform request, opts
    end
  end

  res
end