raptor-io 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/LICENSE +30 -0
- data/README.md +51 -0
- data/lib/rack/handler/raptor-io.rb +130 -0
- data/lib/raptor-io.rb +11 -0
- data/lib/raptor-io/error.rb +19 -0
- data/lib/raptor-io/protocol.rb +6 -0
- data/lib/raptor-io/protocol/error.rb +10 -0
- data/lib/raptor-io/protocol/http.rb +34 -0
- data/lib/raptor-io/protocol/http/client.rb +685 -0
- data/lib/raptor-io/protocol/http/error.rb +16 -0
- data/lib/raptor-io/protocol/http/headers.rb +132 -0
- data/lib/raptor-io/protocol/http/message.rb +67 -0
- data/lib/raptor-io/protocol/http/request.rb +307 -0
- data/lib/raptor-io/protocol/http/request/manipulator.rb +117 -0
- data/lib/raptor-io/protocol/http/request/manipulators.rb +217 -0
- data/lib/raptor-io/protocol/http/request/manipulators/authenticator.rb +110 -0
- data/lib/raptor-io/protocol/http/request/manipulators/authenticators/basic.rb +36 -0
- data/lib/raptor-io/protocol/http/request/manipulators/authenticators/digest.rb +135 -0
- data/lib/raptor-io/protocol/http/request/manipulators/authenticators/negotiate.rb +69 -0
- data/lib/raptor-io/protocol/http/request/manipulators/authenticators/ntlm.rb +29 -0
- data/lib/raptor-io/protocol/http/request/manipulators/redirect_follower.rb +65 -0
- data/lib/raptor-io/protocol/http/response.rb +166 -0
- data/lib/raptor-io/protocol/http/server.rb +446 -0
- data/lib/raptor-io/ruby.rb +4 -0
- data/lib/raptor-io/ruby/hash.rb +24 -0
- data/lib/raptor-io/ruby/ipaddr.rb +15 -0
- data/lib/raptor-io/ruby/openssl.rb +23 -0
- data/lib/raptor-io/ruby/string.rb +27 -0
- data/lib/raptor-io/socket.rb +175 -0
- data/lib/raptor-io/socket/comm.rb +143 -0
- data/lib/raptor-io/socket/comm/local.rb +94 -0
- data/lib/raptor-io/socket/comm/sapni.rb +75 -0
- data/lib/raptor-io/socket/comm/socks.rb +237 -0
- data/lib/raptor-io/socket/comm_chain.rb +30 -0
- data/lib/raptor-io/socket/error.rb +45 -0
- data/lib/raptor-io/socket/switch_board.rb +183 -0
- data/lib/raptor-io/socket/switch_board/route.rb +42 -0
- data/lib/raptor-io/socket/tcp.rb +231 -0
- data/lib/raptor-io/socket/tcp/ssl.rb +77 -0
- data/lib/raptor-io/socket/tcp_server.rb +16 -0
- data/lib/raptor-io/socket/tcp_server/ssl.rb +52 -0
- data/lib/raptor-io/socket/udp.rb +0 -0
- data/lib/raptor-io/version.rb +6 -0
- data/lib/tasks/yard.rake +26 -0
- data/spec/rack/handler/raptor_spec.rb +140 -0
- data/spec/raptor-io/protocol/http/client_spec.rb +671 -0
- data/spec/raptor-io/protocol/http/headers_spec.rb +189 -0
- data/spec/raptor-io/protocol/http/message_spec.rb +5 -0
- data/spec/raptor-io/protocol/http/request/manipulators/authenticator_spec.rb +193 -0
- data/spec/raptor-io/protocol/http/request/manipulators/authenticators/basic_spec.rb +32 -0
- data/spec/raptor-io/protocol/http/request/manipulators/authenticators/digest_spec.rb +76 -0
- data/spec/raptor-io/protocol/http/request/manipulators/authenticators/negotiate_spec.rb +52 -0
- data/spec/raptor-io/protocol/http/request/manipulators/authenticators/ntlm_spec.rb +37 -0
- data/spec/raptor-io/protocol/http/request/manipulators/redirect_follower_spec.rb +51 -0
- data/spec/raptor-io/protocol/http/request/manipulators_spec.rb +202 -0
- data/spec/raptor-io/protocol/http/request_spec.rb +965 -0
- data/spec/raptor-io/protocol/http/response_spec.rb +236 -0
- data/spec/raptor-io/protocol/http/server_spec.rb +345 -0
- data/spec/raptor-io/ruby/hash_spec.rb +20 -0
- data/spec/raptor-io/ruby/string_spec.rb +20 -0
- data/spec/raptor-io/socket/comm/local_spec.rb +50 -0
- data/spec/raptor-io/socket/switch_board/route_spec.rb +49 -0
- data/spec/raptor-io/socket/switch_board_spec.rb +87 -0
- data/spec/raptor-io/socket/tcp/ssl_spec.rb +18 -0
- data/spec/raptor-io/socket/tcp_server/ssl_spec.rb +59 -0
- data/spec/raptor-io/socket/tcp_server_spec.rb +19 -0
- data/spec/raptor-io/socket/tcp_spec.rb +14 -0
- data/spec/raptor-io/socket_spec.rb +16 -0
- data/spec/raptor-io/version_spec.rb +10 -0
- data/spec/spec_helper.rb +56 -0
- data/spec/support/fixtures/raptor/protocol/http/request/manipulators/manifoolators/fooer.rb +25 -0
- data/spec/support/fixtures/raptor/protocol/http/request/manipulators/niccolo_machiavelli.rb +20 -0
- data/spec/support/fixtures/raptor/protocol/http/request/manipulators/options_validator.rb +28 -0
- data/spec/support/fixtures/raptor/socket/ssl_server.crt +18 -0
- data/spec/support/fixtures/raptor/socket/ssl_server.key +15 -0
- data/spec/support/lib/path_helpers.rb +11 -0
- data/spec/support/lib/webserver_option_parser.rb +26 -0
- data/spec/support/lib/webservers.rb +120 -0
- data/spec/support/shared/contexts/with_ssl_server.rb +70 -0
- data/spec/support/shared/contexts/with_tcp_server.rb +58 -0
- data/spec/support/shared/examples/raptor/comm_examples.rb +26 -0
- data/spec/support/shared/examples/raptor/protocols/http/message.rb +106 -0
- data/spec/support/shared/examples/raptor/socket_examples.rb +135 -0
- data/spec/support/webservers/raptor/protocols/http/client.rb +100 -0
- data/spec/support/webservers/raptor/protocols/http/client_close_connection.rb +29 -0
- data/spec/support/webservers/raptor/protocols/http/client_https.rb +43 -0
- data/spec/support/webservers/raptor/protocols/http/request/manipulators/authenticators/basic.rb +9 -0
- data/spec/support/webservers/raptor/protocols/http/request/manipulators/authenticators/digest.rb +22 -0
- data/spec/support/webservers/raptor/protocols/http/request/manipulators/redirect_follower.rb +11 -0
- metadata +336 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
module RaptorIO
|
2
|
+
module Protocol::HTTP
|
3
|
+
|
4
|
+
class Request
|
5
|
+
|
6
|
+
# Base manipulator class, all manipulator components should inherit from it.
|
7
|
+
#
|
8
|
+
# @author Tasos Laskos <tasos_laskos@rapid7.com>
|
9
|
+
# @abstract
|
10
|
+
class Manipulator
|
11
|
+
|
12
|
+
#
|
13
|
+
# {HTTP::Request::Manipulator} error namespace.
|
14
|
+
#
|
15
|
+
# All {HTTP::Request::Manipulator} errors inherit from and live under it.
|
16
|
+
#
|
17
|
+
# @author Tasos "Zapotek" Laskos
|
18
|
+
#
|
19
|
+
class Error < Request::Error
|
20
|
+
|
21
|
+
# Indicates invalid options for a manipulator.
|
22
|
+
#
|
23
|
+
# @author Tasos Laskos
|
24
|
+
class InvalidOptions < Error
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [HTTP::Client] Current HTTP client instance.
|
30
|
+
attr_reader :client
|
31
|
+
|
32
|
+
# @return [HTTP::Request] Request to manipulate.
|
33
|
+
attr_reader :request
|
34
|
+
|
35
|
+
# @return [Hash] Manipulator options.
|
36
|
+
attr_reader :options
|
37
|
+
|
38
|
+
# @param [HTTP::Client] client
|
39
|
+
# HTTP client which will handle the request.
|
40
|
+
# @param [HTTP::Request] request
|
41
|
+
# Request to process.
|
42
|
+
def initialize( client, request, options = {} )
|
43
|
+
@client = client
|
44
|
+
@request = request
|
45
|
+
@options = options
|
46
|
+
end
|
47
|
+
|
48
|
+
# Delivers the manipulator's payload.
|
49
|
+
# @abstract
|
50
|
+
def run
|
51
|
+
end
|
52
|
+
|
53
|
+
# Delegates the work to another manipulator.
|
54
|
+
#
|
55
|
+
# @param [Symbol] manipulator Manipulator to run.
|
56
|
+
# @param [Hash] opts Manipulator options.
|
57
|
+
def delegate( manipulator, opts = options )
|
58
|
+
Request::Manipulators.process( manipulator, client, request, opts )
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Hash] Persistent storage -- per {HTTP::Client} instance.
|
62
|
+
def datastore
|
63
|
+
client.datastore[shortname]
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [String] Shortname of `self`.
|
67
|
+
def shortname
|
68
|
+
self.class.shortname
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [Hash{Symbol=>Array<String>}]
|
72
|
+
# Option names keys for and error messages for values.
|
73
|
+
def validate_options
|
74
|
+
self.class.validate_options!( options, client )
|
75
|
+
end
|
76
|
+
|
77
|
+
class <<self
|
78
|
+
|
79
|
+
# @return [Hash{Symbol=>Array<String>}]
|
80
|
+
# Option names keys for and error messages for values.
|
81
|
+
def validate_options( &block )
|
82
|
+
fail ArgumentError, 'Missing block.' if !block_given?
|
83
|
+
@validator = block
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# @param [Hash] options Manipulator options.
|
88
|
+
# @param [HTTP::Client] client Applicable client.
|
89
|
+
#
|
90
|
+
# @return [Hash{Symbol=>Array<String>}]
|
91
|
+
# Option names keys for and error messages for values.
|
92
|
+
#
|
93
|
+
# @abstract
|
94
|
+
def validate_options!( options, client )
|
95
|
+
@validator ? @validator.call( options, client ) : {}
|
96
|
+
end
|
97
|
+
|
98
|
+
# @return [String] Shortname of `self`.
|
99
|
+
def shortname
|
100
|
+
@shortname ||= Request::Manipulators.class_to_name( self )
|
101
|
+
end
|
102
|
+
|
103
|
+
# Registers manipulators which inherit from this class.
|
104
|
+
#
|
105
|
+
# @see Request::Manipulators#register
|
106
|
+
def inherited( manipulator_klass )
|
107
|
+
Request::Manipulators.register(
|
108
|
+
Request::Manipulators.path_to_name( caller.first.split( ':' ).first ),
|
109
|
+
manipulator_klass
|
110
|
+
)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module RaptorIO
|
2
|
+
module Protocol::HTTP
|
3
|
+
|
4
|
+
class Request
|
5
|
+
|
6
|
+
require_relative 'manipulator'
|
7
|
+
|
8
|
+
# Namespace holding all Request manipulators and providing some helper methods
|
9
|
+
# for management.
|
10
|
+
#
|
11
|
+
# @author Tasos Laskos <tasos_laskos@rapid7.com>
|
12
|
+
module Manipulators
|
13
|
+
|
14
|
+
class <<self
|
15
|
+
include Enumerable
|
16
|
+
|
17
|
+
# @return [String] Directory of the manipulators' repository.
|
18
|
+
attr_reader :library
|
19
|
+
|
20
|
+
# @param [String] manipulator
|
21
|
+
# Manipulator to run -- will be loaded if needed.
|
22
|
+
# @param [HTTP::Client] client
|
23
|
+
# Applicable client.
|
24
|
+
# @param [HTTP::Request] request
|
25
|
+
# Request to process.
|
26
|
+
# @param [Hash] options
|
27
|
+
# Manipulator options.
|
28
|
+
def process( manipulator, client, request, options = {} )
|
29
|
+
load( manipulator ).new( client, request, options ).run
|
30
|
+
end
|
31
|
+
|
32
|
+
# Performs batch validation of manipulator options.
|
33
|
+
#
|
34
|
+
# @param [Hash{String=>Hash}] manipulators
|
35
|
+
# Manipulators for keys and their options as values.
|
36
|
+
# @param [HTTP::Client] client
|
37
|
+
# Applicable client.
|
38
|
+
#
|
39
|
+
# @return [Hash{String=>Hash}]
|
40
|
+
# Manipulators for keys and error hashes as values.
|
41
|
+
#
|
42
|
+
def validate_batch_options( manipulators, client )
|
43
|
+
errors = {}
|
44
|
+
manipulators.each do |manipulator, options|
|
45
|
+
errors[manipulator] =
|
46
|
+
validate_options( manipulator, options, client )
|
47
|
+
end
|
48
|
+
errors.reject { |_, errs| errs.empty? }
|
49
|
+
end
|
50
|
+
|
51
|
+
# Same as {.validate_batch_options} but raises exception on errors.
|
52
|
+
def validate_batch_options!( manipulators, client )
|
53
|
+
errors = validate_batch_options( manipulators, client )
|
54
|
+
if errors.any?
|
55
|
+
fail Request::Manipulator::Error::InvalidOptions, errors.to_s
|
56
|
+
end
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
60
|
+
# @param [String] manipulator
|
61
|
+
# @param [Hash] options Manipulator options.
|
62
|
+
# @param [HTTP::Client] client Applicable client.
|
63
|
+
#
|
64
|
+
# @return [Hash{Symbol=>Array<String>}]
|
65
|
+
# Option names keys for and error messages for values.
|
66
|
+
def validate_options( manipulator, options, client )
|
67
|
+
load( manipulator ).validate_options!( options, client )
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param [String] directory Directory including manipulators.
|
71
|
+
def library=( directory )
|
72
|
+
@library = File.expand_path( directory ) + '/'
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [Array<String>] Paths of all manipulators.
|
76
|
+
def paths
|
77
|
+
Dir.glob( "#{library}**/*.rb" )
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [Array<Symbol>] Names of all manipulators.
|
81
|
+
def available
|
82
|
+
paths.map { |path| path_to_name path }
|
83
|
+
end
|
84
|
+
|
85
|
+
# @param [Symbol] manipulator
|
86
|
+
# Loads a manipulator by name.
|
87
|
+
#
|
88
|
+
# @return [Class] Loaded manipulator.
|
89
|
+
def load( manipulator )
|
90
|
+
manipulator = normalize_name( manipulator )
|
91
|
+
return @manipulators[manipulator] if @manipulators.include? manipulator
|
92
|
+
|
93
|
+
Kernel.load name_to_path( manipulator )
|
94
|
+
@manipulators[manipulator]
|
95
|
+
end
|
96
|
+
|
97
|
+
# Loads all manipulators.
|
98
|
+
#
|
99
|
+
# @return [Hash] All manipulators.
|
100
|
+
def load_all
|
101
|
+
paths.each { |path| load path_to_name( path ) }
|
102
|
+
loaded
|
103
|
+
end
|
104
|
+
|
105
|
+
# @param [Symbol] manipulator
|
106
|
+
# Unloads a manipulator by name.
|
107
|
+
#
|
108
|
+
# @return [Bool]
|
109
|
+
# `true` if the manipulator was unloaded successfully, `false` if no
|
110
|
+
# matching one was found.
|
111
|
+
def unload( manipulator )
|
112
|
+
klass = @manipulators.delete( normalize_name( manipulator ) )
|
113
|
+
return false if !klass
|
114
|
+
|
115
|
+
container = self
|
116
|
+
klass.to_s.gsub( "#{self}::", '' ).split( '::' )[0...-1].each do |c|
|
117
|
+
container = container.const_get( c.to_sym )
|
118
|
+
end
|
119
|
+
|
120
|
+
container.instance_eval do
|
121
|
+
remove_const klass.to_s.split( ':' ).last.to_sym
|
122
|
+
end
|
123
|
+
|
124
|
+
# Remove the container namespaces themselves if they're now empty.
|
125
|
+
container = self
|
126
|
+
klass.to_s.gsub( "#{self}::", '' ).split( '::' )[0...-1].each do |c|
|
127
|
+
container = container.const_get( c.to_sym )
|
128
|
+
if container != self && container.constants.empty?
|
129
|
+
remove_const container.to_s.split( ':' ).last.to_sym
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
true
|
134
|
+
end
|
135
|
+
|
136
|
+
# Unloads all manipulators.
|
137
|
+
def unload_all
|
138
|
+
@manipulators.keys.each { |manipulator| unload manipulator }
|
139
|
+
nil
|
140
|
+
end
|
141
|
+
|
142
|
+
# @param [Block] block
|
143
|
+
# Block to be passed each manipulator name=>class.
|
144
|
+
# @return [Enumerator, Manipulators]
|
145
|
+
# `Enumerator` if no `block` is given, `self` otherwise.
|
146
|
+
def each( &block )
|
147
|
+
return enum_for( __method__ ) if !block_given?
|
148
|
+
@manipulators.each( &block )
|
149
|
+
self
|
150
|
+
end
|
151
|
+
|
152
|
+
# @return [Hash] All manipulators as a frozen hash.
|
153
|
+
def loaded
|
154
|
+
@manipulators.dup.freeze
|
155
|
+
end
|
156
|
+
|
157
|
+
# Registers a manipulator.
|
158
|
+
#
|
159
|
+
# @param [Symbol] name
|
160
|
+
# @param [Base] klass
|
161
|
+
#
|
162
|
+
# @return [Manipulator] `self`
|
163
|
+
#
|
164
|
+
# @private
|
165
|
+
def register( name, klass )
|
166
|
+
@manipulators[normalize_name( name )] = klass
|
167
|
+
self
|
168
|
+
end
|
169
|
+
|
170
|
+
# Resets the manipulators by unloading all and settings the {#library} to
|
171
|
+
# its default setting.
|
172
|
+
def reset
|
173
|
+
unload_all if @manipulators
|
174
|
+
|
175
|
+
@library = File.expand_path( File.dirname( __FILE__ ) + '/manipulators' ) + '/'
|
176
|
+
@manipulators = {}
|
177
|
+
end
|
178
|
+
|
179
|
+
# @param [String] name Manipulator name.
|
180
|
+
# @return [Bool] `true` if the given manipulator exists, `false` otherwise.
|
181
|
+
def exist?( name )
|
182
|
+
File.exist? name_to_path( name )
|
183
|
+
end
|
184
|
+
|
185
|
+
# @param [String] path FS path to a manipulator.
|
186
|
+
# @return [String] Manipulator shortname.
|
187
|
+
def path_to_name( path )
|
188
|
+
normalize_name path.gsub( library, '' ).gsub( /(.+)\.rb$/, '\1' )
|
189
|
+
end
|
190
|
+
|
191
|
+
# @param [Class] klass Manipulator class.
|
192
|
+
# @return [String, nil]
|
193
|
+
# Manipulator shortname, `nil` if the manipulator isn't loaded.
|
194
|
+
def class_to_name( klass )
|
195
|
+
@manipulators.select { |name, k| return name if k == klass }
|
196
|
+
nil
|
197
|
+
end
|
198
|
+
|
199
|
+
# @param [String] name Manipulator shortname.
|
200
|
+
# @return [String] Manipulator FS path.
|
201
|
+
def name_to_path( name )
|
202
|
+
File.expand_path "#{library}/#{name}.rb"
|
203
|
+
end
|
204
|
+
|
205
|
+
# @param [String, Symbol] name Manipulator name.
|
206
|
+
# @return [String] Manipulator name.
|
207
|
+
def normalize_name( name )
|
208
|
+
name.to_s
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
reset
|
213
|
+
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module RaptorIO
|
2
|
+
module Protocol::HTTP
|
3
|
+
class Request
|
4
|
+
|
5
|
+
module Manipulators
|
6
|
+
|
7
|
+
# Namespace for all authenticator manipulators.
|
8
|
+
module Authenticators
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
# Implements automatic HTTP authentication.
|
13
|
+
#
|
14
|
+
# @author Tasos Laskos
|
15
|
+
#
|
16
|
+
class Authenticator < Manipulator
|
17
|
+
|
18
|
+
validate_options do |options, _|
|
19
|
+
errors = {}
|
20
|
+
next errors if options[:skip]
|
21
|
+
|
22
|
+
[:username, :password].each do |option|
|
23
|
+
errors[option] = [ "Can't be blank." ] if options[option].to_s.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
errors
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
datastore[:tries] ||= 0
|
31
|
+
return if skip?
|
32
|
+
|
33
|
+
callbacks = request.callbacks.dup
|
34
|
+
request.clear_callbacks
|
35
|
+
|
36
|
+
# We need to block until authentication is complete, that's why we requeue
|
37
|
+
# and run.
|
38
|
+
|
39
|
+
requeue
|
40
|
+
request.on_complete do |response|
|
41
|
+
auth_type = type( response )
|
42
|
+
|
43
|
+
if !failed? && response.code == 401 && supported?( auth_type )
|
44
|
+
retry_with_auth( auth_type, response )
|
45
|
+
else
|
46
|
+
request.callbacks = callbacks
|
47
|
+
request.handle_response response
|
48
|
+
request.clear_callbacks
|
49
|
+
end
|
50
|
+
end
|
51
|
+
client.run
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# @note Set by one of the authenticators, not `self`.
|
57
|
+
# @return [Bool] `true` if authentication failed, `false` otherwise.
|
58
|
+
def failed?
|
59
|
+
!!datastore[:failed]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Retries the request with authentication.
|
63
|
+
#
|
64
|
+
# @param [Symbol] type Authenticator to use.
|
65
|
+
# @param [RaptorIO::Protocol::HTTP::Response] response
|
66
|
+
# Response signaling the need to authenticate.
|
67
|
+
def retry_with_auth( type, response )
|
68
|
+
datastore[:tries] += 1
|
69
|
+
|
70
|
+
remove_client_authenticators if ![:ntlm, :negotiate].include?( type )
|
71
|
+
client.manipulators.merge!({
|
72
|
+
"authenticators/#{type}" => options.merge( response: response )
|
73
|
+
})
|
74
|
+
requeue
|
75
|
+
end
|
76
|
+
|
77
|
+
# Requeues the request after the proper authenticator has been enabled.
|
78
|
+
def requeue
|
79
|
+
client.queue( request, shortname => { skip: true } )
|
80
|
+
end
|
81
|
+
|
82
|
+
# @param [RaptorIO::Protocol::HTTP::Response] response
|
83
|
+
# Response signaling the need to authenticate.
|
84
|
+
# @return [Symbol] Authentication type.
|
85
|
+
def type( response )
|
86
|
+
response.headers['www-authenticate'].to_s.split( ' ' ).first.to_s.downcase.to_s.to_sym
|
87
|
+
end
|
88
|
+
|
89
|
+
def skip?
|
90
|
+
failed? || !!options[:skip]
|
91
|
+
end
|
92
|
+
|
93
|
+
# @param [Symbol] type Authentication type to check.
|
94
|
+
# @return [Bool]
|
95
|
+
# `true` if the authentication `type` is supported, `false` otherwise.
|
96
|
+
def supported?( type )
|
97
|
+
Request::Manipulators.exist? "authenticators/#{type}"
|
98
|
+
end
|
99
|
+
|
100
|
+
# Removes all enabled authenticators.
|
101
|
+
def remove_client_authenticators
|
102
|
+
client.manipulators.reject!{ |k, _| k.start_with? 'authenticator' }
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RaptorIO
|
2
|
+
module Protocol::HTTP
|
3
|
+
class Request
|
4
|
+
|
5
|
+
module Manipulators
|
6
|
+
module Authenticators
|
7
|
+
|
8
|
+
#
|
9
|
+
# Implements HTTP Basic authentication.
|
10
|
+
#
|
11
|
+
# @author Tasos Laskos
|
12
|
+
#
|
13
|
+
class Basic < Manipulator
|
14
|
+
|
15
|
+
def run
|
16
|
+
request.headers['Authorization'] =
|
17
|
+
"Basic #{Base64.encode64("#{username}:#{password}").chomp}"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def username
|
23
|
+
options[:username]
|
24
|
+
end
|
25
|
+
|
26
|
+
def password
|
27
|
+
options[:password]
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|