Module: OpenURI::Meta

Defined in:
lib/open-uri.rb

Overview

Mixin for holding meta-information.

Constant Summary collapse

RE_LWS =
/[\r\n\t ]+/n
RE_TOKEN =
%r{[^\x00- ()<>@,;:\\"/\[\]?={}\x7f]+}n
RE_QUOTED_STRING =
%r{"(?:[\r\n\t !#-\[\]-~\x80-\xff]|\\[\x00-\x7f])*"}n
RE_PARAMETERS =
%r{(?:;#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?=#{RE_LWS}?(?:#{RE_TOKEN}|#{RE_QUOTED_STRING})#{RE_LWS}?)*}n

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#base_uriObject

returns a URI that is the base of relative URIs in the data. It may differ from the URI supplied by a user due to redirection.



415
416
417
# File 'lib/open-uri.rb', line 415

def base_uri
  @base_uri
end

#metaObject (readonly)

returns a Hash that represents header fields. The Hash keys are downcased for canonicalization.



419
420
421
# File 'lib/open-uri.rb', line 419

def meta
  @meta
end

#statusObject

returns an Array that consists of status code and message.



411
412
413
# File 'lib/open-uri.rb', line 411

def status
  @status
end

Class Method Details

.init(obj, src = nil) ⇒ Object

:nodoc:



395
396
397
398
399
400
401
402
403
404
405
406
407
408
# File 'lib/open-uri.rb', line 395

def Meta.init(obj, src=nil) # :nodoc:
  obj.extend Meta
  obj.instance_eval {
    @base_uri = nil
    @meta = {}
  }
  if src
    obj.status = src.status
    obj.base_uri = src.base_uri
    src.meta.each {|name, value|
      obj.meta_add_field(name, value)
    }
  end
end

Instance Method Details

#charsetObject

returns a charset parameter in Content-Type field. It is downcased for canonicalization.

If charset parameter is not given but a block is given, the block is called and its result is returned. It can be used to guess charset.

If charset parameter and block is not given, nil is returned except text type in HTTP. In that case, "iso-8859-1" is returned as defined by RFC2616 3.7.1.



497
498
499
500
501
502
503
504
505
506
507
508
509
# File 'lib/open-uri.rb', line 497

def charset
  type, *parameters = content_type_parse
  if pair = parameters.assoc('charset')
    pair.last.downcase
  elsif block_given?
    yield
  elsif type && %r{\Atext/} =~ type &&
        @base_uri && /\Ahttp\z/i =~ @base_uri.scheme
    "iso-8859-1" # RFC2616 3.7.1
  else
    nil
  end
end

#content_encodingObject

returns a list of encodings in Content-Encoding field as an Array of String. The encodings are downcased for canonicalization.



514
515
516
517
518
519
520
521
# File 'lib/open-uri.rb', line 514

def content_encoding
  v = @meta['content-encoding']
  if v && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ v
    v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase}
  else
    []
  end
end

#content_typeObject

returns "type/subtype" which is MIME Content-Type. It is downcased for canonicalization. Content-Type parameters are stripped.



482
483
484
485
# File 'lib/open-uri.rb', line 482

def content_type
  type, *_ = content_type_parse
  type || 'application/octet-stream'
end

#content_type_parseObject

:nodoc:



460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
# File 'lib/open-uri.rb', line 460

def content_type_parse # :nodoc:
  v = @meta['content-type']
  # The last (?:;#{RE_LWS}?)? matches extra ";" which violates RFC2045.
  if v && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ v
    type = $1.downcase
    subtype = $2.downcase
    parameters = []
    $3.scan(/;#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?=#{RE_LWS}?(?:(#{RE_TOKEN})|(#{RE_QUOTED_STRING}))/no) {|att, val, qval|
      if qval
        val = qval[1...-1].gsub(/[\r\n\t !#-\[\]-~\x80-\xff]+|(\\[\x00-\x7f])/n) { $1 ? $1[1,1] : $& }
      end
      parameters << [att.downcase, val]
    }
    ["#{type}/#{subtype}", *parameters]
  else
    nil
  end
end

#last_modifiedObject

returns a Time that represents the Last-Modified field.



447
448
449
450
451
452
453
# File 'lib/open-uri.rb', line 447

def last_modified
  if v = @meta['last-modified']
    Time.httpdate(v)
  else
    nil
  end
end

#meta_add_field(name, value) ⇒ Object

:nodoc:



440
441
442
443
444
# File 'lib/open-uri.rb', line 440

def meta_add_field(name, value) # :nodoc:
  name = name.downcase
  @meta[name] = value
  meta_setup_encoding if name == 'content-type'
end

#meta_setup_encodingObject

:nodoc:



421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
# File 'lib/open-uri.rb', line 421

def meta_setup_encoding # :nodoc:
  charset = self.charset
  enc = nil
  if charset
    begin
      enc = Encoding.find(charset)
    rescue ArgumentError
    end
  end
  enc = Encoding::ASCII_8BIT unless enc
  if self.respond_to? :force_encoding
    self.force_encoding(enc)
  elsif self.respond_to? :string
    self.string.force_encoding(enc)
  else # Tempfile
    self.set_encoding enc
  end
end