class SpiderGazelle::Gazelle::Request

Constants

PROTO_ENV
TODO

Add HTTP headers to the env and capitalise them and prefix them with HTTP_

convert - signs to underscores

Attributes

body[RW]
defer[R]
env[RW]
header[RW]
hijacked[R]
is_async[R]
keep_alive[RW]
upgrade[RW]
url[RW]

Public Class Methods

new(thread, app, port, remote_ip, scheme, socket) click to toggle source
Calls superclass method
# File lib/spider-gazelle/gazelle/request.rb, line 29
def initialize(thread, app, port, remote_ip, scheme, socket)
    super(thread, thread.defer)

    @socket = socket
    @app = app
    @body = String.new
    @header = String.new
    @url = String.new
    @env = PROTO_ENV.dup
    @env['SERVER_PORT'] = port
    @env['REMOTE_ADDR'] = remote_ip
    @env['rack.url_scheme'] = scheme
end

Public Instance Methods

execute!() click to toggle source
# File lib/spider-gazelle/gazelle/request.rb, line 44
def execute!
    @env['CONTENT_LENGTH'] = @env.delete('HTTP_CONTENT_LENGTH') || @body.bytesize.to_s
    @env['CONTENT_TYPE'] = @env.delete('HTTP_CONTENT_TYPE') || 'text/plain'
    @env['REQUEST_URI'] = @url.freeze

    # For Rack::Lint on 1.9, ensure that the encoding is always for spec
    @body.force_encoding(Encoding::ASCII_8BIT)
    @env['rack.input'] = StringIO.new @body

    # Break the request into its components
    query_start  = @url.index '?'
    if query_start
        path = @url[0...query_start].freeze
        @env['PATH_INFO'] = path
        @env['REQUEST_PATH'] = path
        @env['QUERY_STRING'] = @url[query_start + 1..-1].freeze
    else
        @env['PATH_INFO'] = @url
        @env['REQUEST_PATH'] = @url
        @env['QUERY_STRING'] = ''
    end

    # Grab the host name from the request
    if host = @env['HTTP_HOST']
        if colon = host.index(':')
            @env['SERVER_NAME'] = host[0, colon]
            @env['SERVER_PORT'] = host[colon + 1, host.bytesize]
        else
            @env['SERVER_NAME'] = host
        end
    else
        @env['SERVER_NAME'] = 'localhost'
    end

    if @upgrade == true && @env['HTTP_UPGRADE'] == 'h2c'
        # TODO:: implement the upgrade process here
    end

    # Provide hijack options
    @env['rack.hijack?'] = true
    @env['rack.hijack'] = proc { @env['rack.hijack_io'] = @socket }

    # Execute the request
    # NOTE:: Catch was overloaded by Promise so this does the trick now
    resp = ruby_catch(:async) { @app.call @env }
    if resp.nil? || resp[0] == -1
        @is_async = true

        # close the body for deferred responses
        unless resp.nil?
            body = resp[2]
            body.close if body.respond_to?(:close)
        end
    end
    resp
end