Parent

Included Modules

Thin::Connection

Connection between the server and client. This class is instanciated by EventMachine on each new connection that is opened.

Constants

AsyncResponse

This is a template async response. N.B. Can’t use string for body on 1.9

Attributes

app[RW]

Rack application (adapter) served by this connection.

backend[RW]

Backend to the server

request[RW]

Current request served by the connection

response[RW]

Next response sent through the connection

threaded[W]

Calling the application in a threaded allowing concurrent processing of requests.

Public Instance Methods

can_persist!() click to toggle source

Allows this connection to be persistent.

     # File lib/thin/connection.rb, line 160
160:     def can_persist!
161:       @can_persist = true
162:     end
can_persist?() click to toggle source

Return true if this connection is allowed to stay open and be persistent.

     # File lib/thin/connection.rb, line 165
165:     def can_persist?
166:       @can_persist
167:     end
close_request_response() click to toggle source
     # File lib/thin/connection.rb, line 129
129:     def close_request_response
130:       @request.async_close.succeed if @request.async_close
131:       @request.close  rescue nil
132:       @response.close rescue nil
133:     end
handle_error() click to toggle source

Logs catched exception and closes the connection.

     # File lib/thin/connection.rb, line 123
123:     def handle_error
124:       log "!! Unexpected error while processing request: #{$!.message}"
125:       log_error
126:       close_connection rescue nil
127:     end
persistent?() click to toggle source

Return true if the connection must be left open and ready to be reused for another request.

     # File lib/thin/connection.rb, line 171
171:     def persistent?
172:       @can_persist && @response.persistent?
173:     end
post_init() click to toggle source

Get the connection ready to process a request.

    # File lib/thin/connection.rb, line 30
30:     def post_init
31:       @request  = Request.new
32:       @response = Response.new
33:     end
post_process(result) click to toggle source
     # File lib/thin/connection.rb, line 89
 89:     def post_process(result)
 90:       return unless result
 91:       result = result.to_a
 92:       
 93:       # Status code -1 indicates that we're going to respond later (async).
 94:       return if result.first == AsyncResponse.first
 95: 
 96:       @response.status, @response.headers, @response.body = *result
 97: 
 98:       log "!! Rack application returned nil body. Probably you wanted it to be an empty string?" if @response.body.nil?
 99: 
100:       # Make the response persistent if requested by the client
101:       @response.persistent! if @request.persistent?
102: 
103:       # Send the response
104:       @response.each do |chunk|
105:         trace { chunk }
106:         send_data chunk
107:       end
108: 
109:     rescue Exception
110:       handle_error
111:     ensure
112:       # If the body is being deferred, then terminate afterward.
113:       if @response.body.respond_to?(:callback) && @response.body.respond_to?(:errback)
114:         @response.body.callback { terminate_request }
115:         @response.body.errback  { terminate_request }
116:       else
117:         # Don't terminate the response if we're going async.
118:         terminate_request unless result && result.first == AsyncResponse.first
119:       end
120:     end
pre_process() click to toggle source
    # File lib/thin/connection.rb, line 57
57:     def pre_process
58:       # Add client info to the request env
59:       @request.remote_address = remote_address
60: 
61:       # Connection may be closed unless the App#call response was a [-1, ...]
62:       # It should be noted that connection objects will linger until this 
63:       # callback is no longer referenced, so be tidy!
64:       @request.async_callback = method(:post_process)
65:       
66:       if @backend.ssl?
67:         @request.env["rack.url_scheme"] = "https"
68:         
69:         if cert = get_peer_cert
70:           @request.env['rack.peer_cert'] = cert
71:         end
72:       end
73: 
74:       # When we're under a non-async framework like rails, we can still spawn
75:       # off async responses using the callback info, so there's little point
76:       # in removing this.
77:       response = AsyncResponse
78:       catch(:async) do
79:         # Process the request calling the Rack adapter
80:         response = @app.call(@request.env)
81:       end
82:       response
83:     rescue Exception
84:       handle_error
85:       terminate_request
86:       nil # Signal to post_process that the request could not be processed
87:     end
process() click to toggle source

Called when all data was received and the request is ready to be processed.

    # File lib/thin/connection.rb, line 47
47:     def process
48:       if threaded?
49:         @request.threaded = true
50:         EventMachine.defer(method(:pre_process), method(:post_process))
51:       else
52:         @request.threaded = false
53:         post_process(pre_process)
54:       end
55:     end
receive_data(data) click to toggle source

Called when data is received from the client.

    # File lib/thin/connection.rb, line 36
36:     def receive_data(data)
37:       trace { data }
38:       process if @request.parse(data)
39:     rescue InvalidRequest => e
40:       log "!! Invalid request"
41:       log_error e
42:       close_connection
43:     end
remote_address() click to toggle source

IP Address of the remote client.

     # File lib/thin/connection.rb, line 183
183:     def remote_address
184:       socket_address
185:     rescue Exception
186:       log_error
187:       nil
188:     end
terminate_request() click to toggle source

Does request and response cleanup (closes open IO streams and deletes created temporary files). Re-initializes response and request if client supports persistent connection.

     # File lib/thin/connection.rb, line 139
139:     def terminate_request
140:       unless persistent?
141:         close_connection_after_writing rescue nil
142:         close_request_response
143:       else
144:         close_request_response
145:         # Prepare the connection for another request if the client
146:         # supports HTTP pipelining (persistent connection).
147:         post_init
148:       end
149:     end
threaded?() click to toggle source

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?.

     # File lib/thin/connection.rb, line 178
178:     def threaded?
179:       @threaded || (@app.respond_to?(:deferred?) && @app.deferred?(@request.env))
180:     end
unbind() click to toggle source

Called when the connection is unbinded from the socket and can no longer be used to process requests.

     # File lib/thin/connection.rb, line 153
153:     def unbind
154:       @request.async_close.succeed if @request.async_close
155:       @response.body.fail if @response.body.respond_to?(:fail)
156:       @backend.connection_finished(self)
157:     end

Protected Instance Methods

socket_address() click to toggle source

Returns IP address of peer as a string.

     # File lib/thin/connection.rb, line 192
192:       def socket_address
193:         Socket.unpack_sockaddr_in(get_peername)[1]
194:       end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.