Class: SpiderGazelle::Connection

Inherits:
Object
  • Object
show all
Includes:
Const
Defined in:
lib/spider-gazelle/connection.rb

Defined Under Namespace

Classes: Hijack

Constant Summary collapse

DUMMY_PROGRESS =
self.method :on_progress

Constants included from Const

SpiderGazelle::Const::ASCII_8BIT, SpiderGazelle::Const::ASYNC, SpiderGazelle::Const::CGI_VER, SpiderGazelle::Const::CHUNKED, SpiderGazelle::Const::CLOSE, SpiderGazelle::Const::CLOSE_CHUNKED, SpiderGazelle::Const::COLON, SpiderGazelle::Const::COLON_SPACE, SpiderGazelle::Const::COMMA, SpiderGazelle::Const::CONNECTION, SpiderGazelle::Const::CONTENT_LENGTH, SpiderGazelle::Const::CONTENT_LENGTH2, SpiderGazelle::Const::CONTENT_TYPE, SpiderGazelle::Const::DASH, SpiderGazelle::Const::DEFAULT_TYPE, SpiderGazelle::Const::EMPTY, SpiderGazelle::Const::ERROR_400_RESPONSE, SpiderGazelle::Const::ERROR_404_RESPONSE, SpiderGazelle::Const::ERROR_408_RESPONSE, SpiderGazelle::Const::ERROR_500_RESPONSE, SpiderGazelle::Const::ERROR_503_RESPONSE, SpiderGazelle::Const::GATEWAY_INTERFACE, SpiderGazelle::Const::HEAD, SpiderGazelle::Const::HEX_SIZE_CHUNKED_RESPONSE, SpiderGazelle::Const::HIJACK, SpiderGazelle::Const::HIJACK_IO, SpiderGazelle::Const::HIJACK_P, SpiderGazelle::Const::HTTP, SpiderGazelle::Const::HTTPS, SpiderGazelle::Const::HTTP_11, SpiderGazelle::Const::HTTP_CONTENT_LENGTH, SpiderGazelle::Const::HTTP_CONTENT_TYPE, SpiderGazelle::Const::HTTP_HOST, SpiderGazelle::Const::HTTP_META, SpiderGazelle::Const::HTTP_STATUS_DEFAULT, SpiderGazelle::Const::INTERNAL_PIPE_BACKLOG, SpiderGazelle::Const::KEEP_ALIVE, SpiderGazelle::Const::KILL_GAZELLE, SpiderGazelle::Const::LINE_END, SpiderGazelle::Const::LOCALHOST, SpiderGazelle::Const::NEWLINE, SpiderGazelle::Const::NO_TLS, SpiderGazelle::Const::PATH_INFO, SpiderGazelle::Const::PORT_443, SpiderGazelle::Const::PORT_80, SpiderGazelle::Const::QUERY_STRING, SpiderGazelle::Const::QUESTION_MARK, SpiderGazelle::Const::RACK, SpiderGazelle::Const::RACK_ERRORS, SpiderGazelle::Const::RACK_INPUT, SpiderGazelle::Const::RACK_MULTIPROCESS, SpiderGazelle::Const::RACK_MULTITHREAD, SpiderGazelle::Const::RACK_RUN_ONCE, SpiderGazelle::Const::RACK_URL_SCHEME, SpiderGazelle::Const::RACK_VERSION, SpiderGazelle::Const::REMOTE_ADDR, SpiderGazelle::Const::REQUEST_METHOD, SpiderGazelle::Const::REQUEST_PATH, SpiderGazelle::Const::REQUEST_URI, SpiderGazelle::Const::SCRIPT_NAME, SpiderGazelle::Const::SERVER, SpiderGazelle::Const::SERVER_NAME, SpiderGazelle::Const::SERVER_PORT, SpiderGazelle::Const::SERVER_PROTOCOL, SpiderGazelle::Const::SERVER_SOFTWARE, SpiderGazelle::Const::SPACE, SpiderGazelle::Const::SPIDER_GAZELLE_VERSION, SpiderGazelle::Const::TRANSFER_ENCODING, SpiderGazelle::Const::UNDERSCORE, SpiderGazelle::Const::USE_TLS, SpiderGazelle::Const::ZERO

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(gazelle, loop, socket, port, state, app, queue) ⇒ Connection

Returns a new instance of Connection.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/spider-gazelle/connection.rb', line 18

def initialize(gazelle, loop, socket, port, state, app, queue)
  # A single parser instance per-connection (supports pipelining)
  @state = state
  @pending = []

  # Work callback for thread pool processing
  @request = nil
  @work = method :work

  # Called after the work on the thread pool is complete
  @send_response = method :send_response
  @send_error = method :send_error

  # Used to chain promises (ensures requests are processed in order)
  @process_next = method :process_next
  # Keep track of work queue head to prevent unintentional GC
  @current_worker = queue
  # Start queue with an existing resolved promise (::Libuv::Q::ResolvedPromise.new(@loop, true))
  @queue_worker = queue

  # Socket for writing the response
  @socket = socket
  @app = app
  @port = port
  @tls = @socket.tls?
  @loop = loop
  @gazelle = gazelle
  @async_callback = method :deferred_callback

  # Remove connection if the socket closes
  socket.finally &method(:unlink)
end

Instance Attribute Details

#async_callbackObject (readonly)

For Request



16
17
18
# File 'lib/spider-gazelle/connection.rb', line 16

def async_callback
  @async_callback
end

#loopObject (readonly)

For Request



16
17
18
# File 'lib/spider-gazelle/connection.rb', line 16

def loop
  @loop
end

#parsingObject (readonly)

For Gazelle



14
15
16
# File 'lib/spider-gazelle/connection.rb', line 14

def parsing
  @parsing
end

#portObject (readonly)

For Request



16
17
18
# File 'lib/spider-gazelle/connection.rb', line 16

def port
  @port
end

#socketObject (readonly)

For Request



16
17
18
# File 'lib/spider-gazelle/connection.rb', line 16

def socket
  @socket
end

#stateObject (readonly)

For Gazelle



14
15
16
# File 'lib/spider-gazelle/connection.rb', line 14

def state
  @state
end

#tlsObject (readonly)

For Request



16
17
18
# File 'lib/spider-gazelle/connection.rb', line 16

def tls
  @tls
end

Class Method Details

.on_progress(data, socket) ⇒ Object



10
# File 'lib/spider-gazelle/connection.rb', line 10

def self.on_progress(data, socket); end

Instance Method Details

#finished_parsingObject

Chains the work in a promise queue



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/spider-gazelle/connection.rb', line 62

def finished_parsing
  if !@state.keep_alive?
    @parsing.keep_alive = false
    # We don't want to do any more work than we need to
    @socket.stop_read
  end

  @parsing.upgrade = @state.upgrade?
  @pending.push @parsing
  @queue_worker = @queue_worker.then @process_next
end

#parsing_errorObject

The parser encountered an error



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/spider-gazelle/connection.rb', line 75

def parsing_error
  # Grab the error
  send_error @state.error

  # We no longer care for any further requests from this client
  # however we will finish processing any valid pipelined requests before shutting down
  @socket.stop_read
  @queue_worker = @queue_worker.then do
    @socket.write ERROR_400_RESPONSE
    @socket.shutdown
  end
end

#remote_ipObject

Lazy eval the IP



52
53
54
# File 'lib/spider-gazelle/connection.rb', line 52

def remote_ip
  @remote_ip ||= @socket.peername[0]
end

#response(data) ⇒ Object

Schedule send



89
90
91
# File 'lib/spider-gazelle/connection.rb', line 89

def response(data)
  @loop.schedule
end

#start_parsingObject

Creates a new request state object



57
58
59
# File 'lib/spider-gazelle/connection.rb', line 57

def start_parsing
  @parsing = Request.new self, @app
end