Module: Net::HTTPHeader

Included in:
HTTPGenericRequest, HTTPResponse
Defined in:
lib/rubysl/net/http/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”



1160
1161
1162
1163
# File 'lib/rubysl/net/http/http.rb', line 1160

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.



1166
1167
1168
1169
1170
1171
1172
# File 'lib/rubysl/net/http/http.rb', line 1166

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"]


1189
1190
1191
1192
1193
1194
1195
# File 'lib/rubysl/net/http/http.rb', line 1189

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.



1450
1451
1452
# File 'lib/rubysl/net/http/http.rb', line 1450

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)


1361
1362
1363
1364
1365
# File 'lib/rubysl/net/http/http.rb', line 1361

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

#content_lengthObject

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



1342
1343
1344
1345
1346
1347
# File 'lib/rubysl/net/http/http.rb', line 1342

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



1349
1350
1351
1352
1353
1354
1355
# File 'lib/rubysl/net/http/http.rb', line 1349

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.



1370
1371
1372
1373
1374
1375
# File 'lib/rubysl/net/http/http.rb', line 1370

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.



1385
1386
1387
1388
1389
1390
1391
# File 'lib/rubysl/net/http/http.rb', line 1385

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.



1256
1257
1258
# File 'lib/rubysl/net/http/http.rb', line 1256

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.



1271
1272
1273
1274
1275
1276
# File 'lib/rubysl/net/http/http.rb', line 1271

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

#each_capitalized_name(&block) ⇒ Object

Iterates for each capitalized header names.



1240
1241
1242
1243
1244
1245
# File 'lib/rubysl/net/http/http.rb', line 1240

def each_capitalized_name(&block)   #:yield: +key+
  return to_enum(__method__) unless block_given?
  @header.each_key do |k|
    yield capitalize(k)
  end
end

#each_headerObject Also known as: each

Iterates for each header names and values.



1222
1223
1224
1225
1226
1227
# File 'lib/rubysl/net/http/http.rb', line 1222

def each_header   #:yield: +key+, +value+
  return to_enum(__method__) unless block_given?
  @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.



1232
1233
1234
1235
# File 'lib/rubysl/net/http/http.rb', line 1232

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

#each_valueObject

Iterates for each header values.



1248
1249
1250
1251
1252
1253
# File 'lib/rubysl/net/http/http.rb', line 1248

def each_value   #:yield: +value+
  return to_enum(__method__) unless block_given?
  @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 nil, if there’s no header field named key. See Hash#fetch



1216
1217
1218
1219
# File 'lib/rubysl/net/http/http.rb', line 1216

def fetch(key, *args, &block)   #:yield: +key+
  a = @header.fetch(key.downcase, *args, &block)
  a.join(', ')
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"


1208
1209
1210
1211
# File 'lib/rubysl/net/http/http.rb', line 1208

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

#initialize_http_header(initheader) ⇒ Object



1143
1144
1145
1146
1147
1148
1149
1150
# File 'lib/rubysl/net/http/http.rb', line 1143

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)


1261
1262
1263
# File 'lib/rubysl/net/http/http.rb', line 1261

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.



1395
1396
1397
1398
# File 'lib/rubysl/net/http/http.rb', line 1395

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.



1455
1456
1457
# File 'lib/rubysl/net/http/http.rb', line 1455

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.



1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
# File 'lib/rubysl/net/http/http.rb', line 1287

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.



1378
1379
1380
1381
# File 'lib/rubysl/net/http/http.rb', line 1378

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.



1425
1426
1427
# File 'lib/rubysl/net/http/http.rb', line 1425

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.



1437
1438
1439
1440
# File 'lib/rubysl/net/http/http.rb', line 1437

def set_form_data(params, sep = '&')
  self.body = params.map {|k,v| "#{urlencode(k.to_s)}=#{urlencode(v.to_s)}" }.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


1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
# File 'lib/rubysl/net/http/http.rb', line 1309

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



1152
1153
1154
# File 'lib/rubysl/net/http/http.rb', line 1152

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”).



1403
1404
1405
1406
1407
1408
# File 'lib/rubysl/net/http/http.rb', line 1403

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.



1266
1267
1268
# File 'lib/rubysl/net/http/http.rb', line 1266

def to_hash
  @header.dup
end

#type_paramsObject

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



1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
# File 'lib/rubysl/net/http/http.rb', line 1412

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