class Arachni::HTTP::ProxyServer

@author Tasos “Zapotek” Laskos <tasos.laskos@arachni-scanner.com>

Constants

DEFAULT_CONCURRENCY

Public Class Methods

new( options = {} ) click to toggle source

@param [Hash] options @option options [String] :address (‘0.0.0.0’)

Address to bind to.

@option options [Integer] :port

Port number to listen on -- defaults to a random port.

@option options [Integer] :timeout

HTTP time-out for each request in milliseconds.

@option options [Integer] :concurrency (DEFAULT_CONCURRENCY)

Amount of origin requests to be active at any given time.

@option options [Block] :response_handler

Block to be called to handle each response as it arrives -- will be
passed the request and response.

@option options [Block] :request_handler

Block to be called to handle each request as it arrives -- will be
passed the request and response.
# File lib/arachni/http/proxy_server.rb, line 41
def initialize( options = {} )
    @reactor = Arachni::Reactor.new(
        # Higher than the defaults to keep object allocations down.
        select_timeout:    0.1,
        max_tick_interval: 0.1
    )
    @options = options

    @active_connections = Concurrent::Map.new

    @options[:concurrency] ||= DEFAULT_CONCURRENCY
    @options[:address]     ||= '127.0.0.1'
    @options[:port]        ||= Utilities.available_port

    @concurrency_control_tokens = @reactor.create_queue
end

Public Instance Methods

active_connections() click to toggle source
# File lib/arachni/http/proxy_server.rb, line 129
def active_connections
    @active_connections.keys
end
get_request_token( &block ) click to toggle source
# File lib/arachni/http/proxy_server.rb, line 82
def get_request_token( &block )
    @concurrency_control_tokens.pop( &block )
end
has_available_request_tokens?() click to toggle source
# File lib/arachni/http/proxy_server.rb, line 90
def has_available_request_tokens?
    @concurrency_control_tokens.empty?
end
has_pending_requests?() click to toggle source

@return [Bool]

`true` if the proxy has pending requests, `false` otherwise.
# File lib/arachni/http/proxy_server.rb, line 119
def has_pending_requests?
    pending_requests != 0
end
mark_connection_active( connection ) click to toggle source
# File lib/arachni/http/proxy_server.rb, line 133
def mark_connection_active( connection )
    @active_connections.put_if_absent( connection, nil )
end
mark_connection_inactive( connection ) click to toggle source
# File lib/arachni/http/proxy_server.rb, line 137
def mark_connection_inactive( connection )
    @active_connections.delete connection
end
pending_requests() click to toggle source

@return [Integer]

Amount of active requests.
# File lib/arachni/http/proxy_server.rb, line 125
def pending_requests
    @active_connections.size
end
return_request_token( token ) click to toggle source
# File lib/arachni/http/proxy_server.rb, line 86
def return_request_token( token )
    @concurrency_control_tokens << token
end
running?() click to toggle source

@return [Bool]

`true` if the server is running, `false` otherwise.
# File lib/arachni/http/proxy_server.rb, line 107
def running?
    @reactor.running?
end
shutdown() click to toggle source
# File lib/arachni/http/proxy_server.rb, line 94
def shutdown
    print_debug_level_2 'Shutting down...'

    @thread_pool.kill if @thread_pool

    @reactor.stop
    @reactor.wait

    print_debug_level_2 '...shutdown.'
end
start_async() click to toggle source

Starts the server without blocking, it’ll only block until the server is up and running and ready to accept connections.

# File lib/arachni/http/proxy_server.rb, line 60
def start_async
    print_debug_level_2 'Starting...'

    @reactor.run_in_thread

    @options[:concurrency].times do |i|
        @concurrency_control_tokens << i
    end

    @reactor.on_error do |_, e|
        print_exception e
    end

    @reactor.listen(
        @options[:address], @options[:port], Connection,
        @options.merge( parent: self )
    )

    print_debug_level_2 "...started at: #{url}"
    nil
end
url() click to toggle source

@return [String]

Proxy server URL.
# File lib/arachni/http/proxy_server.rb, line 113
def url
    "http://#{@options[:address]}:#{@options[:port]}"
end