Module: OpenURI::Meta

Defined in:
lib/open-uri.rb

Overview

Mixin for holding meta-information.

Constant Summary collapse

RE_LWS =

:stopdoc:

/[\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.



459
460
461
# File 'lib/open-uri.rb', line 459

def base_uri
  @base_uri
end

#metaObject (readonly)

returns a Hash that represents header fields. The Hash keys are downcased for canonicalization. The Hash values are a field body. If there are multiple field with same field name, the field values are concatenated with a comma.



466
467
468
# File 'lib/open-uri.rb', line 466

def meta
  @meta
end

#metasObject (readonly)

returns a Hash that represents header fields. The Hash keys are downcased for canonicalization. The Hash value are an array of field values.



471
472
473
# File 'lib/open-uri.rb', line 471

def metas
  @metas
end

#statusObject

returns an Array that consists of status code and message.



455
456
457
# File 'lib/open-uri.rb', line 455

def status
  @status
end

Class Method Details

.init(obj, src = nil) ⇒ Object

:nodoc:



438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
# File 'lib/open-uri.rb', line 438

def Meta.init(obj, src=nil) # :nodoc:
  obj.extend Meta
  obj.instance_eval {
    @base_uri = nil
    @meta = {} # name to string.  legacy.
    @metas = {} # name to array of strings.
  }
  if src
    obj.status = src.status
    obj.base_uri = src.base_uri
    src.metas.each {|name, values|
      obj.meta_add_field2(name, values)
    }
  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 that case, “utf-8” is returned as defined by RFC6838 4.2.1



557
558
559
560
561
562
563
564
565
566
567
568
# File 'lib/open-uri.rb', line 557

def charset
  type, *parameters = content_type_parse
  if pair = parameters.assoc('charset')
    pair.last.downcase
  elsif block_given?
    yield
  elsif type && %r{\Atext/} =~ type
    "utf-8" # RFC6838 4.2.1
  else
    nil
  end
end

#content_encodingObject

Returns a list of encodings in Content-Encoding field as an array of strings.

The encodings are downcased for canonicalization.



574
575
576
577
578
579
580
581
# File 'lib/open-uri.rb', line 574

def content_encoding
  vs = @metas['content-encoding']
  if vs && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ (v = vs.join(', '))
    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.



542
543
544
545
# File 'lib/open-uri.rb', line 542

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

#content_type_parseObject

:startdoc:



520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
# File 'lib/open-uri.rb', line 520

def content_type_parse # :nodoc:
  vs = @metas['content-type']
  # The last (?:;#{RE_LWS}?)? matches extra ";" which violates RFC2045.
  if vs && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ vs.join(', ')
    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.



504
505
506
507
508
509
510
511
# File 'lib/open-uri.rb', line 504

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

#meta_add_field(name, value) ⇒ Object

:nodoc:



499
500
501
# File 'lib/open-uri.rb', line 499

def meta_add_field(name, value) # :nodoc:
  meta_add_field2(name, [value])
end

#meta_add_field2(name, values) ⇒ Object

:nodoc:



492
493
494
495
496
497
# File 'lib/open-uri.rb', line 492

def meta_add_field2(name, values) # :nodoc:
  name = name.downcase
  @metas[name] = values
  @meta[name] = values.join(', ')
  meta_setup_encoding if name == 'content-type'
end

#meta_setup_encodingObject

:nodoc:



473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
# File 'lib/open-uri.rb', line 473

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