class HTTP::Message::Headers

Represents HTTP message header.

def [](key)

Returns an Array of header values for the given key.
def [](key)
  get(key).collect { |item| item[1] }
end

def []=(key, value)

Adds a header. See set.
def []=(key, value)
  set(key, value)
end

def add(key, value)

Adds a header. Addition order is preserved.
def add(key, value)
  if value.is_a?(Array)
    value.each do |v|
      @header_item.push([key, v])
    end
  else
    @header_item.push([key, value])
  end
end

def all

Returns an Array of all headers.
def all
  @header_item
end

def body_size=(body_size)

body_size == nil means that the body is_a? IO
Sets byte size of message body.
def body_size=(body_size)
  @body_size = body_size
end

def charset_label

def charset_label
  # TODO: should handle response encoding for 1.9 correctly.
  if RUBY_VERSION > "1.9"
    CHARSET_MAP[@body_charset] || 'us-ascii'
  else
    CHARSET_MAP[@body_charset || $KCODE] || 'us-ascii'
  end
end

def content_type

Returns 'Content-Type' header value.
def content_type
  self['Content-Type'][0]
end

def content_type=(content_type)

Sets 'Content-Type' header value. Overrides if already exists.
def content_type=(content_type)
  delete('Content-Type')
  self['Content-Type'] = content_type
end

def create_query_part()

def create_query_part()
  query_str = nil
  if @request_uri.query
    query_str = @request_uri.query
  end
  if @request_query
    if query_str
      query_str += "&#{Message.create_query_part_str(@request_query)}"
    else
      query_str = Message.create_query_part_str(@request_query)
    end
  end
  query_str
end

def create_query_uri()

def create_query_uri()
  if @request_method == 'CONNECT'
    return "#{@request_uri.host}:#{@request_uri.port}"
  end
  path = @request_uri.path
  path = '/' if path.nil? or path.empty?
  if query_str = create_query_part()
    path += "?#{query_str}"
  end
  path
end

def delete(key)

Deletes headers of the given key.
def delete(key)
  key = key.upcase
  @header_item.delete_if { |k, v| k.upcase == key }
end

def dump

Dumps message header part and returns a dumped String.
def dump
  set_header
  str = nil
  if @is_request
    str = request_line
  else
    str = response_status_line
  end
  str + @header_item.collect { |key, value|
    "#{ key }: #{ value }#{ CRLF }"
  }.join
end

def get(key = nil)

one header exists. If nil key given, it returns all headers.
of key and value. It returns an single element Array even if the only
Returns an Array of headers for the given key. Each element is a pair
def get(key = nil)
  if key.nil?
    all
  else
    key = key.upcase
    @header_item.find_all { |k, v| k.upcase == key }
  end
end

def init_connect_request(uri)

Initialize this instance as a CONNECT request.
def init_connect_request(uri)
  @is_request = true
  @request_method = 'CONNECT'
  @request_uri = uri
  @request_query = nil
  @http_version = '1.0'
end

def init_request(method, uri, query = nil)

Initialize this instance as a general request.
def init_request(method, uri, query = nil)
  @is_request = true
  @request_method = method
  @request_uri = uri || NIL_URI
  @request_query = query
  @request_absolute_uri = false
  self
end

def init_response(status_code, req = nil)

Initialize this instance as a response.
def init_response(status_code, req = nil)
  @is_request = false
  self.status_code = status_code
  if req
    @request_method = req.request_method
    @request_uri = req.request_uri
    @request_query = req.request_query
  end
  self
end

def initialize

init_connect_request for acutual initialize.
Creates a Message::Headers. Use init_request, init_response, or
def initialize
  @http_version = '1.1'
  @body_size = nil
  @chunked = false
  @request_method = nil
  @request_uri = nil
  @request_query = nil
  @request_absolute_uri = nil
  @status_code = nil
  @reason_phrase = nil
  @body_type = nil
  @body_charset = nil
  @body_date = nil
  @body_encoding = nil
  @is_request = nil
  @header_item = []
  @dumped = false
end

def request_line

def request_line
  path = create_query_uri()
  if @request_absolute_uri
    path = "#{ @request_uri.scheme }://#{ @request_uri.host }:#{ @request_uri.port }#{ path }"
  end
  "#{ @request_method } #{ path } HTTP/#{ @http_version }#{ CRLF }"
end

def response_status_line

def response_status_line
  if defined?(Apache)
    "HTTP/#{ @http_version } #{ @status_code } #{ @reason_phrase }#{ CRLF }"
  else
    "Status: #{ @status_code } #{ @reason_phrase }#{ CRLF }"
  end
end

def set(key, value)

Sets a header.
def set(key, value)
  delete(key)
  add(key, value)
end

def set_body_encoding

def set_body_encoding
  if type = self.content_type
    OpenURI::Meta.init(o = ''.dup)
    o.meta_add_field('content-type', type)
    @body_encoding = o.encoding
  end
end

def set_body_encoding

def set_body_encoding
  @body_encoding = nil
end

def set_date_header

Set Date header
def set_date_header
  set('Date', Time.now.httpdate)
end

def set_header

def set_header
  if @is_request
    set_request_header
  else
    set_response_header
  end
end

def set_headers(headers)

def set_headers(headers)
  headers.each do |key, value|
    add(key, value)
  end
  set_body_encoding
end

def set_request_header

def set_request_header
  return if @dumped
  @dumped = true
  keep_alive = Message.keep_alive_enabled?(@http_version)
  if !keep_alive and @request_method != 'CONNECT'
    set('Connection', 'close')
  end
  if @chunked
    set('Transfer-Encoding', 'chunked')
  elsif @body_size and (keep_alive or @body_size != 0)
    set('Content-Length', @body_size.to_s)
  end
  if @http_version >= '1.1' and get('Host').empty?
    if @request_uri.port == @request_uri.default_port
      # GFE/1.3 dislikes default port number (returns 404)
      set('Host', "#{@request_uri.hostname}")
    else
      set('Host', "#{@request_uri.hostname}:#{@request_uri.port}")
    end
  end
end

def set_response_header

def set_response_header
  return if @dumped
  @dumped = true
  if defined?(Apache) && self['Date'].empty?
    set_date_header
  end
  keep_alive = Message.keep_alive_enabled?(@http_version)
  if @chunked
    set('Transfer-Encoding', 'chunked')
  else
    if keep_alive or @body_size != 0
      set('Content-Length', @body_size.to_s)
    end
  end
  if @body_date
    set('Last-Modified', @body_date.httpdate)
  end
  if self['Content-Type'].empty?
    set('Content-Type', "#{ @body_type || 'text/html' }; charset=#{ charset_label }")
  end
end

def status_code=(status_code)

Sets status code and reason phrase.
def status_code=(status_code)
  @status_code = status_code
  @reason_phrase = STATUS_CODE_MAP[@status_code]
end