Class: Thin::Connection
- Inherits:
-
EventMachine::Connection
- Object
- EventMachine::Connection
- Thin::Connection
- Includes:
- Logging
- Defined in:
- lib/thin/connection.rb
Overview
Connection between the server and client. This class is instanciated by EventMachine on each new connection that is opened.
Direct Known Subclasses
Constant Summary collapse
- CONTENT_LENGTH =
'Content-Length'.freeze
- TRANSFER_ENCODING =
'Transfer-Encoding'.freeze
- CHUNKED_REGEXP =
/\bchunked\b/i.freeze
Instance Attribute Summary collapse
-
#app ⇒ Object
Rack application (adapter) served by this connection.
-
#backend ⇒ Object
Backend to the server.
-
#request ⇒ Object
Current request served by the connection.
-
#response ⇒ Object
Next response sent through the connection.
-
#threaded ⇒ Object
writeonly
Calling the application in a threaded allowing concurrent processing of requests.
Instance Method Summary collapse
-
#can_persist! ⇒ Object
Allows this connection to be persistent.
-
#can_persist? ⇒ Boolean
Return
true
if this connection is allowed to stay open and be persistent. - #handle_error ⇒ Object
-
#persistent? ⇒ Boolean
Return
true
if the connection must be left open and ready to be reused for another request. -
#post_init ⇒ Object
Get the connection ready to process a request.
- #post_process(result) ⇒ Object
- #pre_process ⇒ Object
-
#process ⇒ Object
Called when all data was received and the request is ready to be processed.
-
#receive_data(data) ⇒ Object
Called when data is received from the client.
-
#remote_address ⇒ Object
IP Address of the remote client.
- #terminate_request ⇒ Object
-
#threaded? ⇒ Boolean
true
ifapp.call
will be called inside a thread. -
#unbind ⇒ Object
Called when the connection is unbinded from the socket and can no longer be used to process requests.
Methods included from Logging
#debug, debug, debug?, #log, log, #log_error, log_error, #silent, #silent=, silent?, #trace, trace, trace?
Instance Attribute Details
#app ⇒ Object
Rack application (adapter) served by this connection.
15 16 17 |
# File 'lib/thin/connection.rb', line 15 def app @app end |
#backend ⇒ Object
Backend to the server
18 19 20 |
# File 'lib/thin/connection.rb', line 18 def backend @backend end |
#request ⇒ Object
Current request served by the connection
21 22 23 |
# File 'lib/thin/connection.rb', line 21 def request @request end |
#response ⇒ Object
Next response sent through the connection
24 25 26 |
# File 'lib/thin/connection.rb', line 24 def response @response end |
#threaded=(value) ⇒ Object (writeonly)
Calling the application in a threaded allowing concurrent processing of requests.
28 29 30 |
# File 'lib/thin/connection.rb', line 28 def threaded=(value) @threaded = value end |
Instance Method Details
#can_persist! ⇒ Object
Allows this connection to be persistent.
118 119 120 |
# File 'lib/thin/connection.rb', line 118 def can_persist! @can_persist = true end |
#can_persist? ⇒ Boolean
Return true
if this connection is allowed to stay open and be persistent.
123 124 125 |
# File 'lib/thin/connection.rb', line 123 def can_persist? @can_persist end |
#handle_error ⇒ Object
96 97 98 99 100 |
# File 'lib/thin/connection.rb', line 96 def handle_error log "!! Unexpected error while processing request: #{$!.}" log_error close_connection rescue nil end |
#persistent? ⇒ Boolean
Return true
if the connection must be left open and ready to be reused for another request.
129 130 131 |
# File 'lib/thin/connection.rb', line 129 def persistent? @can_persist && @response.persistent? end |
#post_init ⇒ Object
Get the connection ready to process a request.
31 32 33 34 |
# File 'lib/thin/connection.rb', line 31 def post_init @request = Request.new @response = Response.new end |
#post_process(result) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/thin/connection.rb', line 70 def post_process(result) return unless result # Set the Content-Length header if possible set_content_length(result) if need_content_length?(result) @response.status, @response.headers, @response.body = result # Make the response persistent if requested by the client @response.persistent! if @request.persistent? # Send the response @response.each do |chunk| trace { chunk } send_data chunk end # If no more request on that same connection, we close it. close_connection_after_writing unless persistent? rescue Object handle_error ensure terminate_request end |
#pre_process ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/thin/connection.rb', line 58 def pre_process # Add client info to the request env @request.remote_address = remote_address # Process the request calling the Rack adapter @app.call(@request.env) rescue Object handle_error terminate_request nil # Signal to post_process that the request could not be processed end |
#process ⇒ Object
Called when all data was received and the request is ready to be processed.
48 49 50 51 52 53 54 55 56 |
# File 'lib/thin/connection.rb', line 48 def process if threaded? @request.threaded = true EventMachine.defer(method(:pre_process), method(:post_process)) else @request.threaded = false post_process(pre_process) end end |
#receive_data(data) ⇒ Object
Called when data is received from the client.
37 38 39 40 41 42 43 44 |
# File 'lib/thin/connection.rb', line 37 def receive_data(data) trace { data } process if @request.parse(data) rescue InvalidRequest => e log "!! Invalid request" log_error e close_connection end |
#remote_address ⇒ Object
IP Address of the remote client.
141 142 143 144 145 146 |
# File 'lib/thin/connection.rb', line 141 def remote_address @request.forwarded_for || socket_address rescue Object log_error nil end |
#terminate_request ⇒ Object
102 103 104 105 106 107 108 109 |
# File 'lib/thin/connection.rb', line 102 def terminate_request @request.close rescue nil @response.close rescue nil # Prepare the connection for another request if the client # supports HTTP pipelining (persistent connection). post_init if persistent? end |
#threaded? ⇒ Boolean
true
if app.call
will be called inside a thread. You can set all requests as threaded setting Connection#threaded=true
or on a per-request case returning true
in app.deferred?
.
136 137 138 |
# File 'lib/thin/connection.rb', line 136 def threaded? @threaded || (@app.respond_to?(:deferred?) && @app.deferred?(@request.env)) end |
#unbind ⇒ Object
Called when the connection is unbinded from the socket and can no longer be used to process requests.
113 114 115 |
# File 'lib/thin/connection.rb', line 113 def unbind @backend.connection_finished(self) end |