class HTTP::Message


p res.header.first
assert_equal(1, res.header.size)
end
p value<br>res.header.each do |value|
res = clnt.get(url)
3. Gets response header.
p res.status #=> 200, 501, etc. (Integer)
res = clnt.get(url)
2. Gets response status code.
p res.content #=> String
res = clnt.get(url)
1. Gets response message body.
== How to use HTTP response message
Some attributes are only for a request or a response, not both.
HTTP response data from Message.
methods of HTTPClient returns so users need to know how to extract
don’t need to care about it. Response message is the instance that
Request message is generated from given parameters internally so users
Represents a HTTP message. A message is for a request or a response.

def body_encoding

Returns content encoding
def body_encoding
  @http_header.body_encoding
end

def content

Returns a content of message body. A String or an IO.
def content
  @http_body.content
end

def content_type

Returns 'Content-Type' header value.
def content_type
  @http_header.content_type
end

def content_type=(content_type)

Sets 'Content-Type' header value. Overrides if already exists.
def content_type=(content_type)
  @http_header.content_type = content_type
end

def cookies

Do we need 'Cookie' support in request header?
Supports 'Set-Cookie' in response header only.
Extracts cookies from 'Set-Cookie' header.
def cookies
  set_cookies = http_header['set-cookie']
  unless set_cookies.empty?
    uri = http_header.request_uri
    set_cookies.map { |str|
      cookie = WebAgent::Cookie.new
      cookie.parse(str, uri)
      cookie
    }
  end
end

def create_query_part_str(query) # :nodoc:

:nodoc:
def create_query_part_str(query) # :nodoc:
  if multiparam_query?(query)
    escape_query(query)
  elsif query.respond_to?(:read)
    query = query.read
  else
    query.to_s
  end
end

def dump(dev = '')

dev needs to respond to <<.
Dumps message (header and body) to given dev.
def dump(dev = '')
  str = @http_header.dump + CRLF
  if @http_header.chunked
    dev = @http_body.dump_chunked(str, dev)
  elsif @http_body
    dev = @http_body.dump(str, dev)
  else
    dev << str
  end
  dev
end

def escape(str) # :nodoc:

:nodoc:
def escape(str) # :nodoc:
  str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(/([^ a-zA-Z0-9_.-]+)/) {
    '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
  }.tr(' ', '+')
end

def escape(str) # :nodoc:

:nodoc:
def escape(str) # :nodoc:
  str.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
    '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
  }.tr(' ', '+')
end

def escape_query(query) # :nodoc:

:nodoc:
def escape_query(query) # :nodoc:
  pairs = []
  query.each { |attr, value|
    left = escape(attr.to_s) << '='
    if values = Array.try_convert(value)
      values.each { |value|
        if value.respond_to?(:read)
          value = value.read
        end
        pairs.push(left + escape(value.to_s))
      }
    else
      if value.respond_to?(:read)
        value = value.read
      end
      pairs.push(left << escape(value.to_s))
    end
  }
  pairs.join('&')
end

def file?(obj)

(get/post/etc.)
but there's no problem as far as using it for non-following methods
defines :pos= but raises an Exception for pos= such as StringIO
Rewinding is only needed for following HTTP redirect. Some IO impl
* must respond to :pos and :pos= to rewind for reading.
* must respond to :read for retrieving String chunks.
Returns true if the given object is a File. In HTTPClient, a file is;
def file?(obj)
  obj.respond_to?(:read) and obj.respond_to?(:pos) and
    obj.respond_to?(:pos=)
end

def headers

(It returns an Array always)
headers like 'Set-Cookie'. Use header['Set-Cookie'] for that purpose.
single value so you can't extract exact value when a message has multiple
Returns Hash of header. key and value are both String. Each key has a
def headers
  Hash[*http_header.all.flatten]
end

def http_body=(body)

Sets a new body. header.body_size is updated with new body.size.
def http_body=(body)
  @http_body = body
  @http_header.body_size = @http_body.size if @http_header
end

def http_version

Returns HTTP version in a HTTP header. String.
def http_version
  @http_header.http_version
end

def http_version=(http_version)

Sets HTTP version in a HTTP header. String.
def http_version=(http_version)
  @http_header.http_version = http_version
end

def initialize # :nodoc:

:nodoc:
Message.new_response instead.
Use Message.new_connect_request, Message.new_request or
Creates a Message. This method should be used internally.
def initialize # :nodoc:
  @http_header = Headers.new
  @http_body = @peer_cert = nil
end

def internal_mime_type(path)

See mime_type_handler=.
Default MIME type handler.
def internal_mime_type(path)
  case path
  when /\.txt$/i
    'text/plain'
  when /\.(htm|html)$/i
    'text/html'
  when /\.doc$/i
    'application/msword'
  when /\.png$/i
    'image/png'
  when /\.gif$/i
    'image/gif'
  when /\.(jpg|jpeg)$/i
    'image/jpeg'
  else
    'application/octet-stream'
  end
end

def keep_alive_enabled?(version)

version:: String
Returns true if the given HTTP version allows keep alive connection.
def keep_alive_enabled?(version)
  version >= '1.1'
end

def mime_type(path) # :nodoc:

:nodoc:
def mime_type(path) # :nodoc:
  if @@mime_type_handler
    res = @@mime_type_handler.call(path)
    if !res || res.to_s == ''
      return 'application/octet-stream'
    else
      return res
    end
  else
    internal_mime_type(path)
  end
end

def mime_type_handler

Returns MIME type handler.
def mime_type_handler
  @@mime_type_handler
end

def mime_type_handler=(handler)

The handler is nil by default.
When you set nil to the handler, internal_mime_type is used instead.

'application/octet-stream' is used.
When the handler returns nil or an empty String,
a MIME type String e.g. 'text/html'.
handler must respond to :call with a single argument :path and returns

Sets MIME type handler.
def mime_type_handler=(handler)
  @@mime_type_handler = handler
end

def multiparam_query?(query)

Returns true if the given query (or body) has a multiple parameter.
def multiparam_query?(query)
  query.is_a?(Array) or query.is_a?(Hash)
end

def new_connect_request(uri)

uri:: an URI that need to connect. Only uri.host and uri.port are used.
'CONNECT' request does not have Body.
Creates a Message instance of 'CONNECT' request.
def new_connect_request(uri)
  m = new
  m.http_header.init_connect_request(uri)
  m.http_header.body_size = nil
  m
end

def new_request(method, uri, query = nil, body = nil, boundary = nil)

a multipart/form-data using this boundary String.
boundary:: When the boundary given, it is sent as
[["a", "b"], ["a", "c"]] => 'a=b&a=c'.
Give an array to pass multiple value like
e.g. { "a" => "b" } => 'a=b'.
body:: a Hash or an Array of body part.
[["a", "b"], ["a", "c"]] => 'http://host/part?a=b&a=c'
Give an array to pass multiple value like
e.g. { "a" => "b" } => 'http://host/part?a=b'
query:: a Hash or an Array of query part of URL.
uri:: an URI object which represents an URL of web resource.
method:: HTTP method String.
Creates a Message instance of general request.
def new_request(method, uri, query = nil, body = nil, boundary = nil)
  m = new
  m.http_header.init_request(method, uri, query)
  m.http_body = Body.new
  m.http_body.init_request(body || '', boundary)
  if body
    m.http_header.body_size = m.http_body.size
    m.http_header.chunked = true if m.http_body.size.nil?
  else
    m.http_header.body_size = nil
  end
  m
end

def new_response(body, req = nil)

body:: a String or an IO of response message body.
Creates a Message instance of response.
def new_response(body, req = nil)
  m = new
  m.http_header.init_response(Status::OK, req)
  m.http_body = Body.new
  m.http_body.init_response(body)
  m.http_header.body_size = m.http_body.size || 0
  m
end

def ok?

Convenience method to return boolean of whether we had a successful request
def ok?
  HTTP::Status.successful?(status)
end

def parse(query)

from CGI.parse
def parse(query)
  params = Hash.new([].freeze)
  query.split(/[&;]/n).each do |pairs|
    key, value = pairs.split('=',2).collect{|v| unescape(v) }
    if params.has_key?(key)
      params[key].push(value)
    else
      params[key] = [value]
    end
  end
  params
end

def reason

Returns HTTP status reason phrase in response. String.
def reason
  @http_header.reason_phrase
end

def reason=(reason)

Sets HTTP status reason phrase of response. String.
def reason=(reason)
  @http_header.reason_phrase = reason
end

def redirect?

def redirect?
  HTTP::Status.redirect?(status)
end

def see_other?

SEE_OTHER is a redirect, but it should sent as GET
def see_other?
  status == HTTP::Status::SEE_OTHER
end

def status

Returns HTTP status code in response. Integer.
def status
  @http_header.status_code
end

def status=(status)

Reason phrase is updated, too.
Sets HTTP status code of response. Integer.
def status=(status)
  @http_header.status_code = status
end

def unescape(string)

from CGI.unescape
def unescape(string)
  string.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n) do
    [$1.delete('%')].pack('H*')
  end
end

def version

def version
  warn(VERSION_WARNING)
  @http_header.http_version.to_f
end

def version=(version)

def version=(version)
  warn(VERSION_WARNING)
  @http_header.http_version = version
end