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
def body_encoding @http_header.body_encoding end
def content
def content @http_body.content end
def content_type
def content_type @http_header.content_type end
def content_type=(content_type)
def content_type=(content_type) @http_header.content_type = content_type end
def cookies
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:
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 = '')
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:
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:
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:
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)
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
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)
def http_body=(body) @http_body = body @http_header.body_size = @http_body.size if @http_header end
def http_version
def http_version @http_header.http_version end
def http_version=(http_version)
def http_version=(http_version) @http_header.http_version = http_version end
def initialize # :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)
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)
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:
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
def mime_type_handler @@mime_type_handler end
def mime_type_handler=(handler)
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)
def multiparam_query?(query) query.is_a?(Array) or query.is_a?(Hash) end
def new_connect_request(uri)
'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)
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)
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?
def ok? HTTP::Status.successful?(status) end
def parse(query)
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
def reason @http_header.reason_phrase end
def reason=(reason)
def reason=(reason) @http_header.reason_phrase = reason end
def redirect?
def redirect? HTTP::Status.redirect?(status) end
def see_other?
def see_other? status == HTTP::Status::SEE_OTHER end
def status
def status @http_header.status_code end
def status=(status)
Sets HTTP status code of response. Integer.
def status=(status) @http_header.status_code = status end
def unescape(string)
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