Class: HTTP::Cookie::Scanner

### Home Classes Methods

### In Files

- lib/http/cookie/scanner.rb

### Parent

StringScanner

### Methods

- ::new
- ::quote
- #parse_cookie_date
- #scan_cookie
- #scan_dquoted
- #scan_name
- #scan_name_value
- #scan_set_cookie
- #scan_value
- #skip_wsp

### Files

- LICENSE.txt

### Class/Module Index

Quicksearch

- HTTP
- HTTP::Cookie
- HTTP::Cookie::Scanner
- HTTP::CookieJar
- HTTP::CookieJar::AbstractSaver
- HTTP::CookieJar::AbstractStore
- HTTP::CookieJar::CookiestxtSaver
- HTTP::CookieJar::HashStore
- HTTP::CookieJar::MozillaStore
- HTTP::CookieJar::YAMLSaver
- Array
- Hash
- String

No matching classes.

# HTTP::Cookie::Scanner

### Constants

RE_BAD_CHAR
RE_COOKIE_COMMA

  A pattern that matches the comma in a (typically date) value.

RE_NAME

  A pattern that matches a cookie name or attribute name which may be empty, capturing trailing whitespace.

RE_WSP

  Whitespace.

### Public Class Methods

new(string, logger = nil) click to toggle source

    # File lib/http/cookie/scanner.rb, line 18
    def initialize(string, logger = nil)
      @logger = logger
      super(string)
    end

quote(s) click to toggle source

    # File lib/http/cookie/scanner.rb, line 24
    def quote(s)
      return s unless s.match(RE_BAD_CHAR)
      '"' << s.gsub(/([\\"])/, "\\\\\\1") << '"'
    end

### Public Instance Methods

parse_cookie_date(s) click to toggle source

    # File lib/http/cookie/scanner.rb, line 102
    def parse_cookie_date(s)
      # RFC 6265 5.1.1
      time = day_of_month = month = year = nil

      s.split(/[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]+/).each { |token|
        case
        when time.nil? && token.match(/\A(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?(?=\D|\z)/)
          sec =
            if $3
              $3.to_i
            else
              # violation of the RFC
              @logger.warn("Time lacks the second part: #{token}") if @logger
              0
            end
          time = [$1.to_i, $2.to_i, sec]
        when day_of_month.nil? && token.match(/\A(\d{1,2})(?=\D|\z)/)
          day_of_month = $1.to_i
        when month.nil? && token.match(/\A(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/)
          month = $1.capitalize
        when year.nil? && token.match(/\A(\d{2,4})(?=\D|\z)/)
          year = $1.to_i
        end
      }

      if day_of_month.nil? || month.nil? || year.nil? || time.nil?
        return nil
      end

      case day_of_month
      when 1..31
      else
        return nil
      end

      case year
      when 100..1600
        return nil
      when 70..99
        year += 1900
      when 0..69
        year += 2000
      end

      hh, mm, ss = time
      if hh > 23 || mm > 59 || ss > 59
        return nil
      end

      tuple_to_time(day_of_month, month, year, time)
    end

scan_cookie() click to toggle source

    # File lib/http/cookie/scanner.rb, line 216
    def scan_cookie
      # RFC 6265 4.1.1 & 5.4
      until eos?
        skip_wsp

        name, value = scan_name_value

        yield name, value if value

        # The comma is used as separator for concatenating multiple
        # values of a header.
        skip(/[;,]/)
      end
    end

scan_dquoted() click to toggle source

    # File lib/http/cookie/scanner.rb, line 34
    def scan_dquoted
      ''.tap { |s|
        case
        when skip(/"/)
          break
        when skip(/\\/)
          s << getch
        when scan(/[^"\\]+/)
          s << matched
        end until eos?
      }
    end

scan_name() click to toggle source

    # File lib/http/cookie/scanner.rb, line 47
    def scan_name
      scan(RE_NAME).tap { |s|
        s.rstrip! if s
      }
    end

scan_name_value() click to toggle source

    # File lib/http/cookie/scanner.rb, line 71
    def scan_name_value
      name = scan_name
      if skip(/\=/)
        value = scan_value
      else
        scan_value
        value = nil
      end
      [name, value]
    end

scan_set_cookie() click to toggle source

    # File lib/http/cookie/scanner.rb, line 154
    def scan_set_cookie
      # RFC 6265 4.1.1 & 5.2
      until eos?
        start = pos
        len = nil

        skip_wsp

        name, value = scan_name_value
        if value.nil?
          @logger.warn("Cookie definition lacks a name-value pair.") if @logger
        elsif name.empty?
          @logger.warn("Cookie definition has an empty name.") if @logger
          value = nil
        end
        attrs = {}

        case
        when skip(/,/)
          # The comma is used as separator for concatenating multiple
          # values of a header.
          len = (pos - 1) - start
          break
        when skip(/;/)
          skip_wsp
          aname, avalue = scan_name_value
          next if aname.empty? || value.nil?
          aname.downcase!
          case aname
          when 'expires'
            # RFC 6265 5.2.1
            avalue &&= parse_cookie_date(avalue) or next
          when 'max-age'
            # RFC 6265 5.2.2
            next unless /\A-?\d+\z/.match(avalue)
          when 'domain'
            # RFC 6265 5.2.3
            # An empty value SHOULD be ignored.
            next if avalue.nil? || avalue.empty?
          when 'path'
            # RFC 6265 5.2.4
            # A relative path must be ignored rather than normalizing it
            # to "/".
            next unless /\A\//.match(avalue)
          when 'secure', 'httponly'
            # RFC 6265 5.2.5, 5.2.6
            avalue = true
          end
          attrs[aname] = avalue
        end until eos?

        len ||= pos - start

        if len > HTTP::Cookie::MAX_LENGTH
          @logger.warn("Cookie definition too long: #{name}") if @logger
          next
        end

        yield name, value, attrs if value
      end
    end

scan_value() click to toggle source

    # File lib/http/cookie/scanner.rb, line 53
    def scan_value
      ''.tap { |s|
        case
        when scan(/[^,;"]+/)
          s << matched
        when skip(/"/)
          # RFC 6265 2.2
          # A cookie-value may be DQUOTE'd.
          s << scan_dquoted
        when check(/;|#{RE_COOKIE_COMMA}/)
          break
        else
          s << getch
        end until eos?
        s.rstrip!
      }
    end

skip_wsp() click to toggle source

    # File lib/http/cookie/scanner.rb, line 30
    def skip_wsp
      skip(RE_WSP)
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.