Class: Docker::API::Response

Inherits:
Object
  • Object
show all
Defined in:
lib/docker/api/response.rb,
sig/docker/api/core.rbs

Overview

What the daemon said, before anything has interpreted it.

The status is kept alongside the body because Docker uses it to carry meaning: 204 for a successful delete, 304 for "already in that state". A layer that returned only a parsed body would throw that away.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(status:, headers: {}, body: nil) ⇒ Response

Returns a new instance of Response.

Parameters:

  • status (Integer)

    the HTTP status

  • headers (Hash) (defaults to: {})

    response headers in any casing

  • body (String, nil) (defaults to: nil)

    the raw body

  • status: (Integer)
  • headers: (Hash[untyped, untyped]) (defaults to: {})
  • body: (String, nil) (defaults to: nil)


27
28
29
30
31
# File 'lib/docker/api/response.rb', line 27

def initialize(status:, headers: {}, body: nil)
  @status = Integer(status)
  @headers = normalize(headers)
  @body = body.to_s
end

Instance Attribute Details

#bodyString (readonly)

Returns the raw body. Empty when the body was streamed to a block instead of buffered.

Returns:

  • (String)

    the raw body. Empty when the body was streamed to a block instead of buffered.



22
23
24
# File 'lib/docker/api/response.rb', line 22

def body
  @body
end

#headersHash{String => String} (readonly)

Returns response headers, downcased keys.

Returns:

  • (Hash{String => String})

    response headers, downcased keys



18
19
20
# File 'lib/docker/api/response.rb', line 18

def headers
  @headers
end

#statusInteger (readonly)

Returns the HTTP status.

Returns:

  • (Integer)

    the HTTP status



15
16
17
# File 'lib/docker/api/response.rb', line 15

def status
  @status
end

Instance Method Details

#[](name) ⇒ String?

Returns the value of a header, case-insensitively.

Parameters:

  • name (String, Symbol)

Returns:

  • (String, nil)

    the value of a header, case-insensitively



86
87
88
# File 'lib/docker/api/response.rb', line 86

def [](name)
  headers[name.to_s.downcase]
end

#jsonHash, ...

The body parsed as JSON.

Returns:

  • (Hash, Array, nil)

    the parsed body, or nil when there was none

Raises:



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/docker/api/response.rb', line 37

def json
  return @json if defined?(@json)

  @json = if body.empty?
            nil
          else
            begin
              JSON.parse(body)
            rescue JSON::ParserError => e
              raise StreamError.new(
                "expected JSON from the daemon but could not parse it: #{e.message}",
                status: status, response: self
              )
            end
          end
end

#json!Hash, Array

The body parsed as JSON, when a document is required rather than merely hoped for.

#json answers nil for an empty body, which is right: 204 and 304 are ordinary Docker answers and carry nothing. But most callers immediately index the result -- .json["Id"], .json["StatusCode"] -- and against an empty body that is NoMethodError: undefined method '[]' for nil, a bare Ruby error escaping the hierarchy this gem promises is the only thing a caller has to rescue.

Reaching this means a daemon, proxy or API-compatible shim answered a documented-success status with no body, so name that rather than letting a nil propagate to whichever accessor touches it first.

Returns:

  • (Hash, Array)

    the parsed body

Raises:



70
71
72
73
74
75
76
77
78
# File 'lib/docker/api/response.rb', line 70

def json!
  parsed = json
  return parsed unless parsed.nil?

  raise StreamError.new(
    "the daemon answered HTTP #{status} with an empty body, but this call needs a JSON document",
    status: status, response: self
  )
end

#success?Boolean

Returns whether the status is in the 2xx range.

Returns:

  • (Boolean)

    whether the status is in the 2xx range



81
82
83
# File 'lib/docker/api/response.rb', line 81

def success?
  (200..299).cover?(status)
end

#to_sString Also known as: inspect

Returns:

  • (String)


91
92
93
# File 'lib/docker/api/response.rb', line 91

def to_s
  "#<Docker::API::Response status=#{status} bytes=#{body.bytesize}>"
end