Module: Net::HTTPHeader

Included in:
HTTPGenericRequest, HTTPResponse
Defined in:
lib/extensions/net-http/net/http.rb

Overview

Header module.

Provides access to @header in the mixed-into class as a hash-like object, except with case-insensitive keys. Also provides methods for accessing commonly-used header values in a more convenient format.

Instance Method Summary collapse

Instance Method Details

#[](key) ⇒ Object

Returns the header field corresponding to the case-insensitive key. For example, a key of “Content-Type” might return “text/html”



1337
1338
1339
1340
# File 'lib/extensions/net-http/net/http.rb', line 1337

def [](key)
  a = @header[key.downcase] or return nil
  a.join(', ')
end

#[]=(key, val) ⇒ Object

Sets the header field corresponding to the case-insensitive key.



1343
1344
1345
1346
1347
1348
1349
# File 'lib/extensions/net-http/net/http.rb', line 1343

def []=(key, val)
  unless val
    @header.delete key.downcase
    return val
  end
  @header[key.downcase] = [val]
end

#add_field(key, val) ⇒ Object

Ruby 1.8.3

Adds header field instead of replace. Second argument val must be a String. See also #[]=, #[] and #get_fields.

request.add_field 'X-My-Header', 'a'
p request['X-My-Header']              #=> "a"
p request.get_fields('X-My-Header')   #=> ["a"]
request.add_field 'X-My-Header', 'b'
p request['X-My-Header']              #=> "a, b"
p request.get_fields('X-My-Header')   #=> ["a", "b"]
request.add_field 'X-My-Header', 'c'
p request['X-My-Header']              #=> "a, b, c"
p request.get_fields('X-My-Header')   #=> ["a", "b", "c"]


1366
1367
1368
1369
1370
1371
1372
# File 'lib/extensions/net-http/net/http.rb', line 1366

def add_field(key, val)
  if @header.key?(key.downcase)
    @header[key.downcase].push val
  else
    @header[key.downcase] = [val]
  end
end

#basic_auth(account, password) ⇒ Object

Set the Authorization: header for “Basic” authorization.



1639
1640
1641
# File 'lib/extensions/net-http/net/http.rb', line 1639

def basic_auth(, password)
  @header['authorization'] = [basic_encode(, password)]
end

#chunked?Boolean

Returns “true” if the “transfer-encoding” header is present and set to “chunked”. This is an HTTP/1.1 feature, allowing the the content to be sent in “chunks” without at the outset stating the entire content length.

Returns:

  • (Boolean)


1539
1540
1541
1542
1543
# File 'lib/extensions/net-http/net/http.rb', line 1539

def chunked?
  return false unless @header['transfer-encoding']
  field = self['Transfer-Encoding']
  (/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false
end

#connection_close?Boolean

Returns:

  • (Boolean)


1653
1654
1655
1656
# File 'lib/extensions/net-http/net/http.rb', line 1653

def connection_close?
  tokens(@header['connection']).include?('close') or
  tokens(@header['proxy-connection']).include?('close')
end

#connection_keep_alive?Boolean

Returns:

  • (Boolean)


1658
1659
1660
1661
# File 'lib/extensions/net-http/net/http.rb', line 1658

def connection_keep_alive?
  tokens(@header['connection']).include?('keep-alive') or
  tokens(@header['proxy-connection']).include?('keep-alive')
end

#content_lengthObject

Returns an Integer object which represents the Content-Length: header field or nil if that field is not provided.



1520
1521
1522
1523
1524
1525
# File 'lib/extensions/net-http/net/http.rb', line 1520

def content_length
  return nil unless key?('Content-Length')
  len = self['Content-Length'].slice(/\d+/) or
      raise HTTPHeaderSyntaxError, 'wrong Content-Length format'
  len.to_i
end

#content_length=(len) ⇒ Object



1527
1528
1529
1530
1531
1532
1533
# File 'lib/extensions/net-http/net/http.rb', line 1527

def content_length=(len)
  unless len
    @header.delete 'content-length'
    return nil
  end
  @header['content-length'] = [len.to_i.to_s]
end

#content_rangeObject

Returns a Range object which represents Content-Range: header field. This indicates, for a partial entity body, where this fragment fits inside the full entity body, as range of byte offsets.



1548
1549
1550
1551
1552
1553
# File 'lib/extensions/net-http/net/http.rb', line 1548

def content_range
  return nil unless @header['content-range']
  m = %r<bytes\s+(\d+)-(\d+)/(\d+|\*)>i.match(self['Content-Range']) or
      raise HTTPHeaderSyntaxError, 'wrong Content-Range format'
  m[1].to_i .. m[2].to_i
end

#content_typeObject

Returns a content type string such as “text/html”. This method returns nil if Content-Type: header field does not exist.



1563
1564
1565
1566
1567
1568
1569
# File 'lib/extensions/net-http/net/http.rb', line 1563

def content_type
  return nil unless main_type()
  if sub_type()
  then "#{main_type()}/#{sub_type()}"
  else main_type()
  end
end

#delete(key) ⇒ Object

Removes a header field.



1434
1435
1436
# File 'lib/extensions/net-http/net/http.rb', line 1434

def delete(key)
  @header.delete(key.downcase)
end

#each_capitalizedObject Also known as: canonical_each

As for #each_header, except the keys are provided in capitalized form.



1449
1450
1451
1452
1453
1454
# File 'lib/extensions/net-http/net/http.rb', line 1449

def each_capitalized
  block_given? or return enum_for(__method__)
  @header.each do |k,v|
    yield capitalize(k), v.join(', ')
  end
end

#each_capitalized_nameObject

Iterates for each capitalized header names.



1418
1419
1420
1421
1422
1423
# File 'lib/extensions/net-http/net/http.rb', line 1418

def each_capitalized_name  #:yield: +key+
  block_given? or return enum_for(__method__)
  @header.each_key do |k|
    yield capitalize(k)
  end
end

#each_headerObject Also known as: each

Iterates for each header names and values.



1400
1401
1402
1403
1404
1405
# File 'lib/extensions/net-http/net/http.rb', line 1400

def each_header   #:yield: +key+, +value+
  block_given? or return enum_for(__method__)
  @header.each do |k,va|
    yield k, va.join(', ')
  end
end

#each_name(&block) ⇒ Object Also known as: each_key

Iterates for each header names.



1410
1411
1412
1413
# File 'lib/extensions/net-http/net/http.rb', line 1410

def each_name(&block)   #:yield: +key+
  block_given? or return enum_for(__method__)
  @header.each_key(&block)
end

#each_valueObject

Iterates for each header values.



1426
1427
1428
1429
1430
1431
# File 'lib/extensions/net-http/net/http.rb', line 1426

def each_value   #:yield: +value+
  block_given? or return enum_for(__method__)
  @header.each_value do |va|
    yield va.join(', ')
  end
end

#fetch(key, *args, &block) ⇒ Object

Returns the header field corresponding to the case-insensitive key. Returns the default value args, or the result of the block, or raises an IndexErrror if there’s no header field named key See Hash#fetch



1394
1395
1396
1397
# File 'lib/extensions/net-http/net/http.rb', line 1394

def fetch(key, *args, &block)   #:yield: +key+
  a = @header.fetch(key.downcase, *args, &block)
  a.kind_of?(Array) ? a.join(', ') : a
end

#get_fields(key) ⇒ Object

Ruby 1.8.3

Returns an array of header field strings corresponding to the case-insensitive key. This method allows you to get duplicated header fields without any processing. See also #[].

p response.get_fields('Set-Cookie')
  #=> ["session=al98axx; expires=Fri, 31-Dec-1999 23:58:23",
       "query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"]
p response['Set-Cookie']
  #=> "session=al98axx; expires=Fri, 31-Dec-1999 23:58:23, query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"


1385
1386
1387
1388
# File 'lib/extensions/net-http/net/http.rb', line 1385

def get_fields(key)
  return nil unless @header[key.downcase]
  @header[key.downcase].dup
end

#initialize_http_header(initheader) ⇒ Object



1320
1321
1322
1323
1324
1325
1326
1327
# File 'lib/extensions/net-http/net/http.rb', line 1320

def initialize_http_header(initheader)
  @header = {}
  return unless initheader
  initheader.each do |key, value|
    warn "net/http: warning: duplicated HTTP header: #{key}" if key?(key) and $VERBOSE
    @header[key.downcase] = [value.strip]
  end
end

#key?(key) ⇒ Boolean

true if key header exists.

Returns:

  • (Boolean)


1439
1440
1441
# File 'lib/extensions/net-http/net/http.rb', line 1439

def key?(key)
  @header.key?(key.downcase)
end

#main_typeObject

Returns a content type string such as “text”. This method returns nil if Content-Type: header field does not exist.



1573
1574
1575
1576
# File 'lib/extensions/net-http/net/http.rb', line 1573

def main_type
  return nil unless @header['content-type']
  self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip
end

#proxy_basic_auth(account, password) ⇒ Object

Set Proxy-Authorization: header for “Basic” authorization.



1644
1645
1646
# File 'lib/extensions/net-http/net/http.rb', line 1644

def proxy_basic_auth(, password)
  @header['proxy-authorization'] = [basic_encode(, password)]
end

#rangeObject

Returns an Array of Range objects which represents Range: header field, or nil if there is no such header.



1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
# File 'lib/extensions/net-http/net/http.rb', line 1465

def range
  return nil unless @header['range']
  self['Range'].split(/,/).map {|spec|
    m = /bytes\s*=\s*(\d+)?\s*-\s*(\d+)?/i.match(spec) or
            raise HTTPHeaderSyntaxError, "wrong Range: #{spec}"
    d1 = m[1].to_i
    d2 = m[2].to_i
    if    m[1] and m[2] then  d1..d2
    elsif m[1]          then  d1..-1
    elsif          m[2] then -d2..-1
    else
      raise HTTPHeaderSyntaxError, 'range is not specified'
    end
  }
end

#range_lengthObject

The length of the range represented in Content-Range: header.



1556
1557
1558
1559
# File 'lib/extensions/net-http/net/http.rb', line 1556

def range_length
  r = content_range() or return nil
  r.end - r.begin + 1
end

#set_content_type(type, params = {}) ⇒ Object Also known as: content_type=

Set Content-Type: header field by type and params. type must be a String, params must be a Hash.



1603
1604
1605
# File 'lib/extensions/net-http/net/http.rb', line 1603

def set_content_type(type, params = {})
  @header['content-type'] = [type + params.map{|k,v|"; #{k}=#{v}"}.join('')]
end

#set_form_data(params, sep = '&') ⇒ Object Also known as: form_data=

Set header fields and a body from HTML form data. params should be a Hash containing HTML form data. Optional argument sep means data record separator.

This method also set Content-Type: header field to application/x-www-form-urlencoded.

Example:

http.form_data = {"q" => "ruby", "lang" => "en"}
http.form_data = {"q" => ["ruby", "perl"], "lang" => "en"}
http.set_form_data({"q" => "ruby", "lang" => "en"}, ';')


1621
1622
1623
1624
# File 'lib/extensions/net-http/net/http.rb', line 1621

def set_form_data(params, sep = '&')
  self.body = params.map {|k, v| encode_kvpair(k, v) }.flatten.join(sep)
  self.content_type = 'application/x-www-form-urlencoded'
end

#set_range(r, e = nil) ⇒ Object Also known as: range=

Set Range: header from Range (arg r) or beginning index and length from it (arg idx&len).

req.range = (0..1023)
req.set_range 0, 1023


1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
# File 'lib/extensions/net-http/net/http.rb', line 1487

def set_range(r, e = nil)
  unless r
    @header.delete 'range'
    return r
  end
  r = (r...r+e) if e
  case r
  when Numeric
    n = r.to_i
    rangestr = (n > 0 ? "0-#{n-1}" : "-#{-n}")
  when Range
    first = r.first
    last = r.last
    last -= 1 if r.exclude_end?
    if last == -1
      rangestr = (first > 0 ? "#{first}-" : "-#{-first}")
    else
      raise HTTPHeaderSyntaxError, 'range.first is negative' if first < 0
      raise HTTPHeaderSyntaxError, 'range.last is negative' if last < 0
      raise HTTPHeaderSyntaxError, 'must be .first < .last' if first > last
      rangestr = "#{first}-#{last}"
    end
  else
    raise TypeError, 'Range/Integer is required'
  end
  @header['range'] = ["bytes=#{rangestr}"]
  r
end

#sizeObject Also known as: length

:nodoc: obsolete



1329
1330
1331
# File 'lib/extensions/net-http/net/http.rb', line 1329

def size   #:nodoc: obsolete
  @header.size
end

#sub_typeObject

Returns a content type string such as “html”. This method returns nil if Content-Type: header field does not exist or sub-type is not given (e.g. “Content-Type: text”).



1581
1582
1583
1584
1585
1586
# File 'lib/extensions/net-http/net/http.rb', line 1581

def sub_type
  return nil unless @header['content-type']
  main, sub = *self['Content-Type'].split(';').first.to_s.split('/')
  return nil unless sub
  sub.strip
end

#to_hashObject

Returns a Hash consist of header names and values.



1444
1445
1446
# File 'lib/extensions/net-http/net/http.rb', line 1444

def to_hash
  @header.dup
end

#type_paramsObject

Returns content type parameters as a Hash as like => “iso-2022-jp”.



1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
# File 'lib/extensions/net-http/net/http.rb', line 1590

def type_params
  result = {}
  list = self['Content-Type'].to_s.split(';')
  list.shift
  list.each do |param|
    k, v = *param.split('=', 2)
    result[k.strip] = v.strip
  end
  result
end