class UV::Http::Parser

Attributes

reason[RW]

We need to flush the response on disconnect if content-length is undefined As per the HTTP spec

request[R]

Public Class Methods

new() click to toggle source
# File lib/uv-rays/http/parser.rb, line 32
def initialize
    @parser = ::HttpParser::Parser.new(self)
    @state = ::HttpParser::Parser.new_instance
    @state.type = :response
    @headers = nil
end

Public Instance Methods

eof() click to toggle source
# File lib/uv-rays/http/parser.rb, line 150
def eof
    return if @request.nil?

    if @headers_complete && (@headers['Content-Length'].nil? || @request.method == :head)
        on_message_complete(nil)
    else
        # Reject if this is a partial response
        @request.reject(@reason || :partial_response)
        cleanup
    end
end
new_request(request) click to toggle source
# File lib/uv-rays/http/parser.rb, line 43
def new_request(request)
    @headers = nil
    @request = request
    @headers_complete = false
    @state.reset!
end
on_body(parser, data) click to toggle source
# File lib/uv-rays/http/parser.rb, line 127
def on_body(parser, data)
    if @request.streaming?
        @request.notify(data)
    else
        @body << data
    end
end
on_header_field(parser, data) click to toggle source
# File lib/uv-rays/http/parser.rb, line 83
def on_header_field(parser, data)
    @header = data
end
on_header_value(parser, data) click to toggle source
# File lib/uv-rays/http/parser.rb, line 87
def on_header_value(parser, data)
    case @header
    when 'Set-Cookie'
        @request.set_cookie(data)

    when 'Connection'
        # Overwrite the default
        @close_connection = data == 'close'

    when 'Transfer-Encoding'
        # If chunked we'll buffer streaming data for notification
        @chunked = data == 'chunked'

    end

    # Duplicate headers we'll place into an array
    current = @headers[@header]
    if current
        arr = @headers[@header] = Array(current)
        arr << data
    else
        @headers[@header] = data
    end
end
on_headers_complete(parser) click to toggle source
# File lib/uv-rays/http/parser.rb, line 112
def on_headers_complete(parser)
    @headers_complete = true

    # https://github.com/joyent/http-parser indicates we should extract
    # this information here
    @headers.http_version = @state.http_version
    @headers.status = @state.http_status
    @headers.cookies = @request.cookies_hash
    @headers.keep_alive = !@close_connection

    # User code may throw an error
    # Errors will halt the processing and return a PAUSED error
    @request.set_headers(@headers)
end
on_message_begin(parser) click to toggle source

Parser Callbacks:

# File lib/uv-rays/http/parser.rb, line 65
def on_message_begin(parser)
    @headers = Headers.new
    @body = String.new
    @chunked = false
    @close_connection = false
end
on_message_complete(parser) click to toggle source
# File lib/uv-rays/http/parser.rb, line 135
def on_message_complete(parser)
    @headers.body = @body

    if @request.resolve(@headers)
        cleanup
    else
        req = @request
        cleanup
        new_request(req)
    end
end
on_status(parser, data) click to toggle source
# File lib/uv-rays/http/parser.rb, line 72
def on_status(parser, data)
    @headers.reason_phrase = data

    # Different HTTP versions have different defaults
    if @state.http_minor == 0
        @close_connection = true
    else
        @close_connection = false
    end
end
received(data) click to toggle source
# File lib/uv-rays/http/parser.rb, line 50
def received(data)
    if @parser.parse(@state, data)
        if @request
            @request.reject(@state.error)
            @request = nil
            @response = nil
            return true
        end
    end

    false
end

Private Instance Methods

cleanup() click to toggle source
# File lib/uv-rays/http/parser.rb, line 166
def cleanup
    @request = nil
    @body = nil
    @headers = nil
    @reason = nil
    @headers_complete = false
end