# module WebSocket::HTTP::Headers

### Constants

CR
HEADER_LINE

  RFC 2616 grammar rules:

        CHAR           = <any US-ASCII character (octets 0 - 127)>

        CTL            = <any US-ASCII control character
                         (octets 0 - 31) and DEL (127)>

        SP             = <US-ASCII SP, space (32)>

        HT             = <US-ASCII HT, horizontal-tab (9)>

        token          = 1*<any CHAR except CTLs or separators>

        separators     = "(" | ")" | "<" | ">" | "@"
                       | "," | ";" | ":" | "\" | <">
                       | "/" | "[" | "]" | "?" | "="
                       | "{" | "}" | SP | HT

  Or, as redefined in RFC 7230:

        token          = 1*tchar

        tchar          = "!" / "#" / "$" / "%" / "&" / "'" / "*"
                       / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
                       / DIGIT / ALPHA
                       ; any VCHAR, except delimiters

LF
MAX_LINE_LENGTH

### Attributes

headers[R]

### Public Class Methods

new() click to toggle source

    # File lib/websocket/http/headers.rb, line 40
    def initialize
      @buffer  = []
      @env     = {}
      @headers = {}
      @stage   = 0
    end

### Public Instance Methods

complete?() click to toggle source

    # File lib/websocket/http/headers.rb, line 47
    def complete?
      @stage == 2
    end

error?() click to toggle source

    # File lib/websocket/http/headers.rb, line 51
    def error?
      @stage == -1
    end

parse(chunk) click to toggle source

    # File lib/websocket/http/headers.rb, line 55
    def parse(chunk)
      chunk.each_byte do |octet|
        if octet == LF and @stage < 2
          @buffer.pop if @buffer.last == CR
          if @buffer.empty?
            complete if @stage == 1
          else
            result = case @stage
                     when 0 then start_line(string_buffer)
                     when 1 then header_line(string_buffer)
                     end

            if result
              @stage = 1
            else
              error
            end
          end
          @buffer = []
        else
          @buffer << octet if @stage >= 0
          error if @stage < 2 and @buffer.size > MAX_LINE_LENGTH
        end
      end
      @env['rack.input'] = StringIO.new(string_buffer)
    end

### Private Instance Methods

complete() click to toggle source

    # File lib/websocket/http/headers.rb, line 84
    def complete
      @stage = 2
    end

error() click to toggle source

    # File lib/websocket/http/headers.rb, line 88
    def error
      @stage = -1
    end

header_line(line) click to toggle source

    # File lib/websocket/http/headers.rb, line 92
    def header_line(line)
      return false unless parsed = line.scan(HEADER_LINE).first

      key   = HTTP.normalize_header(parsed[0])
      value = parsed[1].strip

      if @headers.has_key?(key)
        @headers[key] << ', ' << value
      else
        @headers[key] = value
      end
      true
    end

string_buffer() click to toggle source

    # File lib/websocket/http/headers.rb, line 106
    def string_buffer
      @buffer.pack('C*')
    end