Class: RaptorIO::Protocol::HTTP::Client
- Inherits:
-
Object
- Object
- RaptorIO::Protocol::HTTP::Client
- Defined in:
- lib/raptor-io/protocol/http/client.rb
Overview
HTTP Client class.
Constant Summary collapse
- DEFAULT_OPTIONS =
Default client options.
{ concurrency: 20, user_agent: "RaptorIO::HTTP/#{RaptorIO::VERSION}", timeout: 10, manipulators: {}, ssl_version: :TLSv1, ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE, ssl_context: nil }.freeze
Instance Attribute Summary collapse
-
#concurrency ⇒ Integer
Maximum open sockets.
-
#datastore ⇒ Hash
Persistent storage for the manipulators..
-
#manipulators ⇒ Hash{Symbol=>Hash}
Request manipulators, and their options, to be run against each queued request.
-
#ssl_context ⇒ OpenSSL::SSL::SSLContext
SSL context to use.
-
#ssl_verify_mode ⇒ Constant
Peer verification mode.
-
#ssl_version ⇒ Symbol
SSL version.
-
#switch_board ⇒ SwitchBoard
readonly
The routing table from which this Client will make new TCP connections.
-
#timeout ⇒ Integer, Float
Timeout in seconds.
-
#user_agent ⇒ String
User-agent string to use.
Instance Method Summary collapse
- #get(url, options = {}, &block) ⇒ Request, Response
-
#initialize(options = {}) ⇒ Client
constructor
A new instance of Client.
-
#open_socket_count ⇒ Integer
Amount of open sockets.
- #post(url, options = {}, &block) ⇒ Request, Response
-
#queue(request, manipulators = {}) ⇒ Request
(also: #<<)
Queues a Request.
-
#queue_size ⇒ Integer
The amount of queued requests.
- #request(url, options = {}, &block) ⇒ Request, Response
- #run ⇒ Object
-
#update_manipulators(manipulators) ⇒ Object
Updates the client #manipulators and perform and sanity check on their options.
Constructor Details
#initialize(options = {}) ⇒ Client
Returns a new instance of Client.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/raptor-io/protocol/http/client.rb', line 74 def initialize( = {} ) @switch_board = .delete(:switch_board) unless @switch_board.respond_to?(:create_tcp) raise ArgumentError, 'Must provide a :switch_board' end DEFAULT_OPTIONS.merge( ).each do |k, v| begin send( "#{k}=", try_dup( v ) ) rescue NoMethodError instance_variable_set( "@#{k}".to_sym, try_dup( v ) ) end end validate_manipulators!( manipulators ) # Holds Request objects. @queue = [] # Persistent storage for request manipulators. @datastore = Hash.new { |h, k| h[k] = {} } reset_sockets reset_pending_responses end |
Instance Attribute Details
#concurrency ⇒ Integer
Returns Maximum open sockets.
18 19 20 |
# File 'lib/raptor-io/protocol/http/client.rb', line 18 def concurrency @concurrency end |
#datastore ⇒ Hash
Returns Persistent storage for the manipulators..
29 30 31 |
# File 'lib/raptor-io/protocol/http/client.rb', line 29 def datastore @datastore end |
#manipulators ⇒ Hash{Symbol=>Hash}
Returns Request manipulators, and their options, to be run against each queued request.
26 27 28 |
# File 'lib/raptor-io/protocol/http/client.rb', line 26 def manipulators @manipulators end |
#ssl_context ⇒ OpenSSL::SSL::SSLContext
Returns SSL context to use.
38 39 40 |
# File 'lib/raptor-io/protocol/http/client.rb', line 38 def ssl_context @ssl_context end |
#ssl_verify_mode ⇒ Constant
Returns Peer verification mode.
35 36 37 |
# File 'lib/raptor-io/protocol/http/client.rb', line 35 def ssl_verify_mode @ssl_verify_mode end |
#ssl_version ⇒ Symbol
Returns SSL version.
32 33 34 |
# File 'lib/raptor-io/protocol/http/client.rb', line 32 def ssl_version @ssl_version end |
#switch_board ⇒ SwitchBoard (readonly)
Returns The routing table from which this RaptorIO::Protocol::HTTP::Client will make new TCP connections.
42 43 44 |
# File 'lib/raptor-io/protocol/http/client.rb', line 42 def switch_board @switch_board end |
#timeout ⇒ Integer, Float
Returns Timeout in seconds.
15 16 17 |
# File 'lib/raptor-io/protocol/http/client.rb', line 15 def timeout @timeout end |
#user_agent ⇒ String
Returns User-agent string to use.
21 22 23 |
# File 'lib/raptor-io/protocol/http/client.rb', line 21 def user_agent @user_agent end |
Instance Method Details
#get(url, options = {}, &block) ⇒ Request, Response
171 172 173 |
# File 'lib/raptor-io/protocol/http/client.rb', line 171 def get( url, = {}, &block ) request( url, .merge( http_method: :get ), &block ) end |
#open_socket_count ⇒ Integer
Returns Amount of open sockets.
304 305 306 |
# File 'lib/raptor-io/protocol/http/client.rb', line 304 def open_socket_count open_sockets.size end |
#post(url, options = {}, &block) ⇒ Request, Response
181 182 183 |
# File 'lib/raptor-io/protocol/http/client.rb', line 181 def post( url, = {}, &block ) request( url, .merge( http_method: :post ), &block ) end |
#queue(request, manipulators = {}) ⇒ Request Also known as: <<
Queues a Request.
198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/raptor-io/protocol/http/client.rb', line 198 def queue( request, manipulators = {} ) validate_manipulators!( manipulators ) request.timeout ||= timeout @manipulators.merge( manipulators ).each do |manipulator, | Request::Manipulators.process( manipulator, self, request, ) end @queue << request request end |
#queue_size ⇒ Integer
Returns The amount of queued requests.
186 187 188 |
# File 'lib/raptor-io/protocol/http/client.rb', line 186 def queue_size @queue.size end |
#request(url, options = {}, &block) ⇒ Request, Response
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/raptor-io/protocol/http/client.rb', line 141 def request( url, = {}, &block ) = .dup [:timeout] ||= @timeout req = Request.new( .merge( url: url ) ) req.headers['User-Agent'] = @user_agent if !@user_agent.to_s.empty? case [:cookies] when Hash req.headers['Cookie'] = [:cookies].map { |k, v| "#{k}=#{v}" }.join( ';' ) when String req.headers['Cookie'] = [:cookies] end return sync_request( req, [:manipulators] || {} ) if [:mode] == :sync req.on_complete( &block ) if block_given? queue( req, [:manipulators] || {} ) req end |
#run ⇒ Object
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/raptor-io/protocol/http/client.rb', line 213 def run while @queue.any? # Get us some seeds. consume_requests while @sockets[:done].size != @sockets[:lookup_request].size if @sockets[:reads].any? # Use the lowest available timeout for #select. lowest_timeout = @sockets[:reads].map { |socket| @pending_responses[socket][:timeout] }.sort.first clock = Time.now res = select( @sockets[:reads], nil, @sockets[:reads], lowest_timeout ) waiting_time = Time.now - clock # Adjust the timeouts for *all* sockets since they all benefited from # the #select waiting period which just elapsed. # # And this is the whole reason for keeping track of timeouts externally. @pending_responses.each do |_, pending_response| pending_response[:timeout] -= waiting_time pending_response[:timeout] = 0 if pending_response[:timeout] < 0 end # #select timed out, go digging. if !res # Find and handle the sockets which timed out. @sockets[:reads].each do |socket| if waiting_time >= @pending_responses[socket][:timeout] error = RaptorIO::Error::Timeout.new( 'Request timed-out.' ) error.set_backtrace( caller ) handle_error( @sockets[:lookup_request][socket], error, socket ) end # Fill the available pool space. consume_requests end # #select didn't time out, yay! else # Handle sockets with errors -- like reset connections. if res[2].any? res[2].each do |socket| handle_error( @sockets[:lookup_request][socket], nil, socket ) # Fill the available pool space. consume_requests end end # Handle sockets which are ready to be read. if res[0].any? res[0].each do |socket| # Buffer/handle the response for the given socket. read( socket ) # Fill the available pool space. consume_requests end end end end next if @sockets[:writes].empty? _, writes, errors = select( nil, @sockets[:writes], @sockets[:writes] ) errors.each do |socket| handle_error( @sockets[:lookup_request][socket], nil, socket ) end writes.each do |socket| # Send the request for the given socket. write( socket ) # Fully utilize our socket allowance. consume_requests end end end reset_sockets reset_pending_responses nil end |
#update_manipulators(manipulators) ⇒ Object
Updates the client #manipulators and perform and sanity check on their options.
108 109 110 111 |
# File 'lib/raptor-io/protocol/http/client.rb', line 108 def update_manipulators( manipulators ) validate_manipulators!( manipulators ) @manipulators.merge!( manipulators ) end |