ronin-support 0.5.0.rc1 → 0.5.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,81 @@
1
+ #
2
+ # Copyright (c) 2006-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
3
+ #
4
+ # This file is part of Ronin Support.
5
+ #
6
+ # Ronin Support is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Ronin Support is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ module Ronin
21
+ module Fuzzing
22
+ #
23
+ # Fuzzing class that generates repeated data.
24
+ #
25
+ # @api semipublic
26
+ #
27
+ # @since 0.5.0
28
+ #
29
+ class Repeater
30
+
31
+ # The lengths to repeat the data by
32
+ attr_reader :lengths
33
+
34
+ #
35
+ # Initializes a new Repeater.
36
+ #
37
+ # @param [Enumerable, Integer] lengths
38
+ # The lengths to repeat the data by.
39
+ #
40
+ # @raise [TypeError]
41
+ # `lengths` must either be Enumerable or an Integer.
42
+ #
43
+ def initialize(lengths)
44
+ @lengths = case lengths
45
+ when Integer
46
+ [lengths]
47
+ when Enumerable
48
+ lengths
49
+ else
50
+ raise(TypeError,"argument must be Enumerable or an Integer")
51
+ end
52
+ end
53
+
54
+ #
55
+ # Enumerates through each length of repeated data.
56
+ #
57
+ # @param [#*] repeatable
58
+ # The repeatable data.
59
+ #
60
+ # @yield [repeated]
61
+ # The given block will be passed every repeated String.
62
+ #
63
+ # @yieldparam [String] repeated
64
+ # A repeated version of the String.
65
+ #
66
+ # @return [Enumerator]
67
+ # If no block is given, an Enumerator will be returned.
68
+ #
69
+ def each(repeatable)
70
+ return enum_for(__method__,repeatable) unless block_given?
71
+
72
+ @lengths.each do |length|
73
+ yield(repeatable * length)
74
+ end
75
+
76
+ return nil
77
+ end
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,133 @@
1
+ #
2
+ # Copyright (c) 2006-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
3
+ #
4
+ # This file is part of Ronin Support.
5
+ #
6
+ # Ronin Support is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Ronin Support is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ require 'chars'
21
+ require 'combinatorics/generator'
22
+ require 'combinatorics/list_comprehension'
23
+
24
+ module Ronin
25
+ module Fuzzing
26
+ #
27
+ # Fuzzing class that generates Strings based on a template.
28
+ #
29
+ # @api semipublic
30
+ #
31
+ # @since 0.5.0
32
+ #
33
+ class Template
34
+
35
+ include Enumerable
36
+
37
+ #
38
+ # Initializes a new Fuzzing template.
39
+ #
40
+ # @param [Array(<String,Symbol,Enumerable>, <Integer,Array,Range>)] fields
41
+ # The fields which defines the string or character sets which will
42
+ # make up parts of the String.
43
+ #
44
+ # @raise [ArgumentError]
45
+ # A given character set name was unknown.
46
+ #
47
+ # @raise [TypeError]
48
+ # A given string set was not a String, Symbol or Enumerable.
49
+ # A given string set length was not an Integer or Enumerable.
50
+ #
51
+ def initialize(fields)
52
+ @enumerators = []
53
+
54
+ fields.each do |(set,length)|
55
+ enum = case set
56
+ when String
57
+ [set].each
58
+ when Enumerable
59
+ set.each
60
+ when Symbol
61
+ name = set.to_s.upcase
62
+
63
+ unless Chars.const_defined?(name)
64
+ raise(ArgumentError,"unknown charset #{set.inspect}")
65
+ end
66
+
67
+ Chars.const_get(name).each_char
68
+ else
69
+ raise(TypeError,"set must be a String, Symbol or Enumerable")
70
+ end
71
+
72
+ case length
73
+ when Integer
74
+ length.times { @enumerators << enum.dup }
75
+ when Array, Range
76
+ @enumerators << Combinatorics::Generator.new do |g|
77
+ length.each do |sublength|
78
+ superset = Array.new(sublength) { enum.dup }
79
+
80
+ superset.comprehension { |strings| g.yield strings.join }
81
+ end
82
+ end
83
+ when nil
84
+ @enumerators << enum
85
+ else
86
+ raise(TypeError,"length must be an Integer, Range or Array")
87
+ end
88
+ end
89
+ end
90
+
91
+ #
92
+ # @see #initialize
93
+ #
94
+ def self.[](*fields)
95
+ new(fields)
96
+ end
97
+
98
+ #
99
+ # Generate permutations of Strings from a format template.
100
+ #
101
+ # @yield [string]
102
+ # The given block will be passed each unique String.
103
+ #
104
+ # @yieldparam [String] string
105
+ # A newly generated String.
106
+ #
107
+ # @return [Enumerator]
108
+ # If no block is given, an Enumerator will be returned.
109
+ #
110
+ def each
111
+ return enum_for(__method__) unless block_given?
112
+
113
+ @enumerators.comprehension do |fields|
114
+ string = ''
115
+
116
+ fields.each do |field|
117
+ string << case field
118
+ when Integer
119
+ field.chr
120
+ else
121
+ field.to_s
122
+ end
123
+ end
124
+
125
+ yield string
126
+ end
127
+
128
+ return nil
129
+ end
130
+
131
+ end
132
+ end
133
+ end
@@ -78,7 +78,7 @@ module Ronin
78
78
  end
79
79
 
80
80
  #
81
- # Connects to the HTTP server.
81
+ # Starts a HTTP connection with the server.
82
82
  #
83
83
  # @param [Hash] options
84
84
  # Additional options
@@ -86,51 +86,46 @@ module Ronin
86
86
  # @option options [String, URI::HTTP] :url
87
87
  # The full URL to request.
88
88
  #
89
- # @option options [String] :user
90
- # The user to authenticate with when connecting to the HTTP
91
- # server.
92
- #
93
- # @option options [String] :password
94
- # The password to authenticate with when connecting to the HTTP
95
- # server.
96
- #
97
89
  # @option options [String] :host
98
90
  # The host the HTTP server is running on.
99
91
  #
100
92
  # @option options [Integer] :port (Net::HTTP.default_port)
101
93
  # The port the HTTP server is listening on.
102
94
  #
103
- # @option options [String] :path
104
- # The path to request from the HTTP server.
95
+ # @option options [String, Hash] :proxy (HTTP.proxy)
96
+ # A Hash of proxy settings to use when connecting to the HTTP server.
97
+ #
98
+ # @option options [String] :user
99
+ # The user to authenticate with when connecting to the HTTP server.
100
+ #
101
+ # @option options [String] :password
102
+ # The password to authenticate with when connecting to the HTTP
103
+ # server.
105
104
  #
106
- # @yield [session]
107
- # If a block is given, it will be passes the new HTTP session
108
- # object.
105
+ # @option options [Boolean, Hash] :ssl
106
+ # Enables SSL for the HTTP connection.
109
107
  #
110
- # @yieldparam [Net::HTTP] session
108
+ # @option :ssl [Symbol] :verify
109
+ # Specifies the SSL certificate verification mode.
110
+ #
111
+ # @yield [http]
112
+ # If a block is given, it will be passed the newly created HTTP
113
+ # session object.
114
+ #
115
+ # @yieldparam [Net::HTTP] http
111
116
  # The newly created HTTP session.
112
117
  #
113
118
  # @return [Net::HTTP]
114
119
  # The HTTP session object.
115
120
  #
116
- # @see Network::HTTP#http_session
121
+ # @see Network::HTTP#http_connect
117
122
  #
118
123
  # @api public
119
124
  #
120
- def http_session(options={},&block)
121
- options = http_merge_options(options)
122
-
123
- super(options) do |http,expanded_options|
124
- print_info "Starting HTTP Session with #{host_port}"
125
-
126
- if block.arity == 2
127
- block.call(http,expanded_options)
128
- else
129
- block.call(http)
130
- end
131
-
132
- print_info "Closing HTTP Session with #{host_port}"
133
- end
125
+ # @since 0.5.0
126
+ #
127
+ def http_connect(options={},&block)
128
+ super(http_merge_options(options),&block)
134
129
  end
135
130
 
136
131
  #
@@ -163,523 +158,32 @@ module Ronin
163
158
  # @api public
164
159
  #
165
160
  def http_request(options={},&block)
166
- options = http_merge_options(options)
167
- print_info "HTTP #{options[:method]} #{http_options_to_s(options)}"
168
-
169
- return super(options,&block)
170
- end
171
-
172
- #
173
- # Returns the Status Code of the Response.
174
- #
175
- # @param [Hash] options
176
- # Additional options.
177
- #
178
- # @option options [Symbol, String] :method (:head)
179
- # The method to use for the request.
180
- #
181
- # @return [Integer]
182
- # The HTTP Response Status.
183
- #
184
- # @see Network::HTTP#http_status
185
- #
186
- # @since 1.1.0
187
- #
188
- # @api public
189
- #
190
- def http_status(options={})
191
- options = http_merge_options(options)
192
-
193
- if (result = super(options))
194
- print_debug "HTTP #{result} #{http_options_to_s(options)}"
195
- end
196
-
197
- return result
198
- end
199
-
200
- #
201
- # Checks if the response has an HTTP OK status code.
202
- #
203
- # @param [Hash] options
204
- # Additional options.
205
- #
206
- # @option options [Symbol, String] :method (:head)
207
- # The method to use for the request.
208
- #
209
- # @return [Boolean]
210
- # Specifies whether the response had an HTTP OK status code or not.
211
- #
212
- # @see Network::HTTP#http_ok?
213
- #
214
- # @since 1.1.0
215
- #
216
- # @api public
217
- #
218
- def http_ok?(options={})
219
- options = http_merge_options(options)
161
+ response = super(options) do |request,expanded_options|
162
+ if block
163
+ if block.arity == 2
164
+ block.call(request,expanded_options)
165
+ else
166
+ block.call(request)
167
+ end
168
+ end
220
169
 
221
- if (result = super(options))
222
- print_debug "HTTP 200 OK #{http_options_to_s(options)}"
223
- end
170
+ host = options.fetch(:host,self.host)
171
+ port = options.fetch(:port,self.port)
224
172
 
225
- return result
226
- end
173
+ print_info "HTTP #{request.method} #{host}:#{port} #{request.path}"
227
174
 
228
- #
229
- # Sends a HTTP Head request and returns the HTTP Server header.
230
- #
231
- # @param [Hash] options
232
- # Additional options.
233
- #
234
- # @option options [Symbol, String] :method (:head)
235
- # The method to use for the request.
236
- #
237
- # @return [String]
238
- # The HTTP `Server` header.
239
- #
240
- # @see Network::HTTP#http_server
241
- #
242
- # @since 1.1.0
243
- #
244
- # @api public
245
- #
246
- def http_server(options={})
247
- options = http_merge_options(options)
248
-
249
- if (result = super(options))
250
- print_debug "HTTP Server: #{result}"
175
+ request.each_capitalized do |name,value|
176
+ print_debug " #{name}: #{value}"
177
+ end
251
178
  end
252
179
 
253
- return result
254
- end
255
-
256
- #
257
- # Sends an HTTP Head request and returns the HTTP X-Powered-By header.
258
- #
259
- # @param [Hash] options
260
- # Additional options.
261
- #
262
- # @option options [Symbol, String] :method (:get)
263
- # The method to use for the request.
264
- #
265
- # @return [String]
266
- # The HTTP `X-Powered-By` header.
267
- #
268
- # @see Network::HTTP#http_powered_by
269
- #
270
- # @since 1.1.0
271
- #
272
- # @api public
273
- #
274
- def http_powered_by(options={})
275
- options = http_merge_options(options)
180
+ print_info "HTTP #{response.code} #{response.message}"
276
181
 
277
- if (result = super(options))
278
- print_debug "HTTP X-Powered-By: #{result}"
182
+ response.each_capitalized do |name,value|
183
+ print_debug " #{name}: #{value}"
279
184
  end
280
185
 
281
- return result
282
- end
283
-
284
- #
285
- # Performs an HTTP Copy request.
286
- #
287
- # @yield [response]
288
- # If a block is given, it will be passed the response received
289
- # from the request.
290
- #
291
- # @yieldparam [Net::HTTP::Response] response
292
- # The HTTP response object.
293
- #
294
- # @return [Net::HTTP::Response]
295
- # The response of the HTTP request.
296
- #
297
- # @see Network::HTTP#http_copy
298
- #
299
- # @api public
300
- #
301
- def http_copy(options={},&block)
302
- options = http_merge_options(options)
303
- print_info "HTTP COPY #{http_options_to_s(options)}"
304
-
305
- return super(options,&block)
306
- end
307
-
308
- #
309
- # Performs an HTTP Delete request.
310
- #
311
- # @yield [response]
312
- # If a block is given, it will be passed the response received
313
- # from the request.
314
- #
315
- # @yieldparam [Net::HTTP::Response] response
316
- # The HTTP response object.
317
- #
318
- # @return [Net::HTTP::Response]
319
- # The response of the HTTP request.
320
- #
321
- # @see Network::HTTP#http_delete
322
- #
323
- # @api public
324
- #
325
- def http_delete(options={},&block)
326
- options = http_merge_options(options)
327
- print_info "HTTP DELETE #{http_options_to_s(options)}"
328
-
329
- return super(options,&block)
330
- end
331
-
332
- #
333
- # Performs an HTTP Get request.
334
- #
335
- # @yield [response]
336
- # If a block is given, it will be passed the response received
337
- # from the request.
338
- #
339
- # @yieldparam [Net::HTTP::Response] response
340
- # The HTTP response object.
341
- #
342
- # @return [Net::HTTP::Response]
343
- # The response of the HTTP request.
344
- #
345
- # @see Network::HTTP#http_get
346
- #
347
- # @api public
348
- #
349
- def http_get(options={},&block)
350
- options = http_merge_options(options)
351
- print_info "HTTP GET #{http_options_to_s(options)}"
352
-
353
- return super(options,&block)
354
- end
355
-
356
- #
357
- # Performs an HTTP Get request.
358
- #
359
- # @yield [response]
360
- # If a block is given, it will be passed the response received
361
- # from the request.
362
- #
363
- # @yieldparam [Net::HTTP::Response] response
364
- # The HTTP response object.
365
- #
366
- # @return [String]
367
- # The body of the HTTP Get request.
368
- #
369
- # @see Network::HTTP#http_get_body
370
- #
371
- # @api public
372
- #
373
- def http_get_body(options={},&block)
374
- options = http_merge_options(options)
375
- print_info "HTTP GET #{http_options_to_s(options)}"
376
-
377
- return super(options,&block)
378
- end
379
-
380
- #
381
- # Performs an HTTP Head request.
382
- #
383
- # @yield [response]
384
- # If a block is given, it will be passed the response received
385
- # from the request.
386
- #
387
- # @yieldparam [Net::HTTP::Response] response
388
- # The HTTP response object.
389
- #
390
- # @return [Net::HTTP::Response]
391
- # The response of the HTTP request.
392
- #
393
- # @see Network::HTTP#http_head
394
- #
395
- # @api public
396
- #
397
- def http_head(options={},&block)
398
- options = http_merge_options(options)
399
- print_info "HTTP HEAD #{http_options_to_s(options)}"
400
-
401
- return super(options,&block)
402
- end
403
-
404
- #
405
- # Performs an HTTP Lock request.
406
- #
407
- # @yield [response]
408
- # If a block is given, it will be passed the response received
409
- # from the request.
410
- #
411
- # @yieldparam [Net::HTTP::Response] response
412
- # The HTTP response object.
413
- #
414
- # @return [Net::HTTP::Response]
415
- # The response of the HTTP request.
416
- #
417
- # @see Network::HTTP#http_lock
418
- #
419
- # @api public
420
- #
421
- def http_lock(options={},&block)
422
- options = http_merge_options(options)
423
- print_info "HTTP LOCK #{http_options_to_s(options)}"
424
-
425
- return super(options,&block)
426
- end
427
-
428
- #
429
- # Performs an HTTP Mkcol request.
430
- #
431
- # @yield [response]
432
- # If a block is given, it will be passed the response received
433
- # from the request.
434
- #
435
- # @yieldparam [Net::HTTP::Response] response
436
- # The HTTP response object.
437
- #
438
- # @return [Net::HTTP::Response]
439
- # The response of the HTTP request.
440
- #
441
- # @see Network::HTTP#http_mkcol
442
- #
443
- # @api public
444
- #
445
- def http_mkcol(options={},&block)
446
- options = http_merge_options(options)
447
- print_info "HTTP MKCOL #{http_options_to_s(options)}"
448
-
449
- return super(options,&block)
450
- end
451
-
452
- #
453
- # Performs an HTTP Move request.
454
- #
455
- # @yield [response]
456
- # If a block is given, it will be passed the response received
457
- # from the request.
458
- #
459
- # @yieldparam [Net::HTTP::Response] response
460
- # The HTTP response object.
461
- #
462
- # @return [Net::HTTP::Response]
463
- # The response of the HTTP request.
464
- #
465
- # @see Network::HTTP#http_move
466
- #
467
- # @api public
468
- #
469
- def http_move(options={},&block)
470
- options = http_merge_options(options)
471
- print_info "HTTP MOVE #{http_options_to_s(options)}"
472
-
473
- return super(options,&block)
474
- end
475
-
476
- #
477
- # Performs an HTTP Options request.
478
- #
479
- # @yield [response]
480
- # If a block is given, it will be passed the response received
481
- # from the request.
482
- #
483
- # @yieldparam [Net::HTTP::Response] response
484
- # The HTTP response object.
485
- #
486
- # @return [Net::HTTP::Response]
487
- # The response of the HTTP request.
488
- #
489
- # @see Network::HTTP#http_options
490
- #
491
- # @api public
492
- #
493
- def http_options(options={},&block)
494
- options = http_merge_options(options)
495
- print_info "HTTP OPTIONS #{http_options_to_s(options)}"
496
-
497
- return super(options,&block)
498
- end
499
-
500
- #
501
- # Performs an HTTP Post request.
502
- #
503
- # @param [Hash] options
504
- # Additional options.
505
- #
506
- # @option options [String] :post_data
507
- # The `POSTDATA` to send with the HTTP Post request.
508
- #
509
- # @yield [response]
510
- # If a block is given, it will be passed the response received
511
- # from the request.
512
- #
513
- # @yieldparam [Net::HTTP::Response] response
514
- # The HTTP response object.
515
- #
516
- # @return [Net::HTTP::Response]
517
- # The response of the HTTP request.
518
- #
519
- # @see Network::HTTP#http_post
520
- #
521
- # @api public
522
- #
523
- def http_post(options={},&block)
524
- options = http_merge_options(options)
525
- print_info "HTTP POST #{http_options_to_s(options)}"
526
-
527
- return super(options,&block)
528
- end
529
-
530
- #
531
- # Performs an HTTP Post request.
532
- #
533
- # @yield [response]
534
- # If a block is given, it will be passed the response received
535
- # from the request.
536
- #
537
- # @yieldparam [Net::HTTP::Response] response
538
- # The HTTP response object.
539
- #
540
- # @return [String]
541
- # The body of the Post request.
542
- #
543
- # @see Network::HTTP#http_post_body
544
- #
545
- # @api public
546
- #
547
- def http_post_body(options={},&block)
548
- options = http_merge_options(options)
549
- print_info "HTTP POST #{http_options_to_s(options)}"
550
-
551
- return super(options,&block)
552
- end
553
-
554
- #
555
- # Performs an HTTP PUT request.
556
- #
557
- # @param [Hash] options
558
- # Additional options.
559
- #
560
- # @option options [String] :body
561
- # The body for the request.
562
- #
563
- # @option options [String] :post_data
564
- # The `POSTDATA` to send with the HTTP PUT request.
565
- #
566
- # @yield [response]
567
- # If a block is given, it will be passed the response received
568
- # from the request.
569
- #
570
- # @yieldparam [Net::HTTP::Response] response
571
- # The HTTP response object.
572
- #
573
- # @return [Net::HTTP::Response]
574
- # The response of the HTTP request.
575
- #
576
- # @see Network::HTTP#http_put
577
- #
578
- # @since 0.4.0
579
- #
580
- # @api public
581
- #
582
- def http_put(options={},&block)
583
- options = http_merge_options(options)
584
- print_info "HTTP PUT #{http_options_to_s(options)}"
585
-
586
- return super(options,&block)
587
- end
588
-
589
- #
590
- # Performs an HTTP Propfind request.
591
- #
592
- # @yield [response]
593
- # If a block is given, it will be passed the response received
594
- # from the request.
595
- #
596
- # @yieldparam [Net::HTTP::Response] response
597
- # The HTTP response object.
598
- #
599
- # @return [Net::HTTP::Response]
600
- # The response of the HTTP request.
601
- #
602
- # @see Network::HTTP#http_prop_find
603
- #
604
- # @api public
605
- #
606
- def http_prop_find(options={},&block)
607
- options = http_merge_options(options)
608
- print_info "HTTP PROPFIND #{http_options_to_s(options)}"
609
-
610
- return super(options,&block)
611
- end
612
-
613
- #
614
- # Performs an HTTP Proppatch request.
615
- #
616
- # @yield [response]
617
- # If a block is given, it will be passed the response received
618
- # from the request.
619
- #
620
- # @yieldparam [Net::HTTP::Response] response
621
- # The HTTP response object.
622
- #
623
- # @return [Net::HTTP::Response]
624
- # The response of the HTTP request.
625
- #
626
- # @see Network::HTTP#http_prop_patch
627
- #
628
- # @api public
629
- #
630
- def http_prop_patch(options={},&block)
631
- options = http_merge_options(options)
632
- print_info "HTTP PROPPATCH #{http_options_to_s(options)}"
633
-
634
- return super(options,&block)
635
- end
636
-
637
- #
638
- # Performs an HTTP Trace request.
639
- #
640
- # @yield [response]
641
- # If a block is given, it will be passed the response received
642
- # from the request.
643
- #
644
- # @yieldparam [Net::HTTP::Response] response
645
- # The HTTP response object.
646
- #
647
- # @return [Net::HTTP::Response]
648
- # The response of the HTTP request.
649
- #
650
- # @see Network::HTTP#http_trace
651
- #
652
- # @api public
653
- #
654
- def http_trace(options={},&block)
655
- options = http_merge_options(options)
656
- print_info "HTTP TRACE #{http_options_to_s(options)}"
657
-
658
- return super(options,&block)
659
- end
660
-
661
- #
662
- # Performs an HTTP Unlock request.
663
- #
664
- # @yield [response]
665
- # If a block is given, it will be passed the response received
666
- # from the request.
667
- #
668
- # @yieldparam [Net::HTTP::Response] response
669
- # The HTTP response object.
670
- #
671
- # @return [Net::HTTP::Response]
672
- # The response of the HTTP request.
673
- #
674
- # @see Network::HTTP#http_unlock
675
- #
676
- # @api public
677
- #
678
- def http_unlock(options={},&block)
679
- options = http_merge_options(options)
680
- print_info "HTTP UNLOCK #{http_options_to_s(options)}"
681
-
682
- return super(options,&block)
186
+ return response
683
187
  end
684
188
 
685
189
  private
@@ -698,58 +202,25 @@ module Ronin
698
202
  # @api private
699
203
  #
700
204
  def http_merge_options(options={})
701
- options[:host] ||= self.host if self.host
702
- options[:port] ||= self.port if self.port
205
+ options = options.dup
206
+
207
+ options[:proxy] ||= self.http_proxy if self.http_proxy
208
+ options[:host] ||= self.host if self.host
209
+ options[:port] ||= self.port if self.port
703
210
 
704
211
  if (self.http_vhost || self.http_user_agent)
705
- headers = options.fetch(:headers,{})
212
+ headers = (options[:headers] ||= {})
706
213
 
707
- headers[:host] ||= self.http_vhost if self.http_vhost
214
+ headers[:host] ||= self.http_vhost if self.http_vhost
708
215
  headers[:user_agent] ||= self.http_user_agent if self.http_user_agent
709
-
710
- options[:headers] = headers
711
216
  end
712
217
 
713
- options[:user] ||= self.http_user if self.http_user
218
+ options[:user] ||= self.http_user if self.http_user
714
219
  options[:password] ||= self.http_password if self.http_password
715
220
 
716
- options[:proxy] ||= self.http_proxy if self.http_proxy
717
-
718
221
  return options
719
222
  end
720
223
 
721
- #
722
- # Converts the HTTP options to a printable String.
723
- #
724
- # @param [Hash] options
725
- # HTTP options.
726
- #
727
- # @return [String]
728
- # The printable String.
729
- #
730
- # @since 1.1.0
731
- #
732
- # @api private
733
- #
734
- def http_options_to_s(options)
735
- fields = ["#{options[:host]}:#{options[:port]}"]
736
-
737
- if (options[:user] || options[:password])
738
- fields << "#{options[:user]}:#{options[:password]}"
739
- end
740
-
741
- path = options[:path]
742
- path += "?#{options[:query]}" if options[:query]
743
-
744
- fields << path
745
-
746
- if options[:headers]
747
- fields << ("%p" % options[:headers])
748
- end
749
-
750
- return fields.join(' ')
751
- end
752
-
753
224
  end
754
225
  end
755
226
  end