rubysl-open-uri 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +5 -6
- data/lib/rubysl/open-uri/open-uri.rb +245 -150
- data/lib/rubysl/open-uri/version.rb +1 -1
- data/rubysl-open-uri.gemspec +0 -1
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 127129b8cbce12aae8aff4c5c7e4d7a6d6b69905
|
4
|
+
data.tar.gz: ee23740d2028f77cf902ea7d3ec4f4e7c33b78be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4abdc2787c5f514addfc4ac183e7c51b0f1a89e4b4cb69fdd7fff3f12e5ebda55f02c15ab0322d27852143a92dcadc7b18dec41e7f059cd8538aa8b1f5f759c0
|
7
|
+
data.tar.gz: e36dede11c0ec90c2d57a9a0555f18c7f6c7308e2333169a6563e5432120c4fe02e2b4a1bed95c9313d8abe86d6c06603c480b4918a19324b8e83e0c71ba2753
|
data/.travis.yml
CHANGED
@@ -5,22 +5,26 @@ require 'time'
|
|
5
5
|
module Kernel
|
6
6
|
private
|
7
7
|
alias open_uri_original_open open # :nodoc:
|
8
|
+
class << self
|
9
|
+
alias open_uri_original_open open # :nodoc:
|
10
|
+
end
|
8
11
|
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# the
|
12
|
+
# Allows the opening of various resources including URIs.
|
13
|
+
#
|
14
|
+
# If the first argument responds to the 'open' method, 'open' is called on
|
15
|
+
# it with the rest of the arguments.
|
16
|
+
#
|
17
|
+
# If the first argument is a string that begins with xxx://, it is parsed by
|
18
|
+
# URI.parse. If the parsed object responds to the 'open' method,
|
19
|
+
# 'open' is called on it with the rest of the arguments.
|
12
20
|
#
|
13
|
-
#
|
14
|
-
# it is parsed by URI.parse. If the parsed object respond to `open' method,
|
15
|
-
# the method is called with the rest arguments.
|
21
|
+
# Otherwise, the original Kernel#open is called.
|
16
22
|
#
|
17
|
-
#
|
23
|
+
# OpenURI::OpenRead#open provides URI::HTTP#open, URI::HTTPS#open and
|
24
|
+
# URI::FTP#open, Kernel#open.
|
18
25
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
# Kernel[#.]open can accepts such URIs and strings which begins with
|
22
|
-
# http://, https:// and ftp://.
|
23
|
-
# In these case, the opened file object is extended by OpenURI::Meta.
|
26
|
+
# We can accept URIs and strings that begin with http://, https:// and
|
27
|
+
# ftp://. In these cases, the opened file object is extended by OpenURI::Meta.
|
24
28
|
def open(name, *rest, &block) # :doc:
|
25
29
|
if name.respond_to?(:open)
|
26
30
|
name.open(*rest, &block)
|
@@ -35,18 +39,18 @@ module Kernel
|
|
35
39
|
module_function :open
|
36
40
|
end
|
37
41
|
|
38
|
-
# OpenURI is an easy-to-use wrapper for
|
42
|
+
# OpenURI is an easy-to-use wrapper for Net::HTTP, Net::HTTPS and Net::FTP.
|
39
43
|
#
|
40
|
-
|
44
|
+
# == Example
|
41
45
|
#
|
42
|
-
# It is possible to open http
|
46
|
+
# It is possible to open an http, https or ftp URL as though it were a file:
|
43
47
|
#
|
44
48
|
# open("http://www.ruby-lang.org/") {|f|
|
45
49
|
# f.each_line {|line| p line}
|
46
50
|
# }
|
47
51
|
#
|
48
|
-
# The opened file has several methods for meta
|
49
|
-
# it is extended by OpenURI::Meta.
|
52
|
+
# The opened file has several getter methods for its meta-information, as
|
53
|
+
# follows, since it is extended by OpenURI::Meta.
|
50
54
|
#
|
51
55
|
# open("http://www.ruby-lang.org/en") {|f|
|
52
56
|
# f.each_line {|line| p line}
|
@@ -67,12 +71,14 @@ end
|
|
67
71
|
# }
|
68
72
|
#
|
69
73
|
# The environment variables such as http_proxy, https_proxy and ftp_proxy
|
70
|
-
# are in effect by default.
|
74
|
+
# are in effect by default. Here we disable proxy:
|
71
75
|
#
|
72
76
|
# open("http://www.ruby-lang.org/en/raa.html", :proxy => nil) {|f|
|
73
77
|
# # ...
|
74
78
|
# }
|
75
79
|
#
|
80
|
+
# See OpenURI::OpenRead.open and Kernel#open for more on available options.
|
81
|
+
#
|
76
82
|
# URI objects can be opened in a similar way.
|
77
83
|
#
|
78
84
|
# uri = URI.parse("http://www.ruby-lang.org/en/")
|
@@ -91,9 +97,15 @@ end
|
|
91
97
|
module OpenURI
|
92
98
|
Options = {
|
93
99
|
:proxy => true,
|
100
|
+
:proxy_http_basic_authentication => true,
|
94
101
|
:progress_proc => true,
|
95
102
|
:content_length_proc => true,
|
96
103
|
:http_basic_authentication => true,
|
104
|
+
:read_timeout => true,
|
105
|
+
:ssl_ca_cert => nil,
|
106
|
+
:ssl_verify_mode => nil,
|
107
|
+
:ftp_active_mode => false,
|
108
|
+
:redirect => true,
|
97
109
|
}
|
98
110
|
|
99
111
|
def OpenURI.check_options(options) # :nodoc:
|
@@ -117,12 +129,17 @@ module OpenURI
|
|
117
129
|
|
118
130
|
def OpenURI.open_uri(name, *rest) # :nodoc:
|
119
131
|
uri = URI::Generic === name ? name : URI.parse(name)
|
120
|
-
mode,
|
132
|
+
mode, _, rest = OpenURI.scan_open_optional_arguments(*rest)
|
121
133
|
options = rest.shift if !rest.empty? && Hash === rest.first
|
122
134
|
raise ArgumentError.new("extra arguments") if !rest.empty?
|
123
135
|
options ||= {}
|
124
136
|
OpenURI.check_options(options)
|
125
137
|
|
138
|
+
if /\Arb?(?:\Z|:([^:]+))/ =~ mode
|
139
|
+
encoding, = $1,Encoding.find($1) if $1
|
140
|
+
mode = nil
|
141
|
+
end
|
142
|
+
|
126
143
|
unless mode == nil ||
|
127
144
|
mode == 'r' || mode == 'rb' ||
|
128
145
|
mode == File::RDONLY
|
@@ -130,11 +147,16 @@ module OpenURI
|
|
130
147
|
end
|
131
148
|
|
132
149
|
io = open_loop(uri, options)
|
150
|
+
io.set_encoding(encoding) if encoding
|
133
151
|
if block_given?
|
134
152
|
begin
|
135
153
|
yield io
|
136
154
|
ensure
|
137
|
-
io.close
|
155
|
+
if io.respond_to? :close!
|
156
|
+
io.close! # Tempfile
|
157
|
+
else
|
158
|
+
io.close
|
159
|
+
end
|
138
160
|
end
|
139
161
|
else
|
140
162
|
io
|
@@ -142,16 +164,40 @@ module OpenURI
|
|
142
164
|
end
|
143
165
|
|
144
166
|
def OpenURI.open_loop(uri, options) # :nodoc:
|
145
|
-
|
167
|
+
proxy_opts = []
|
168
|
+
proxy_opts << :proxy_http_basic_authentication if options.include? :proxy_http_basic_authentication
|
169
|
+
proxy_opts << :proxy if options.include? :proxy
|
170
|
+
proxy_opts.compact!
|
171
|
+
if 1 < proxy_opts.length
|
172
|
+
raise ArgumentError, "multiple proxy options specified"
|
173
|
+
end
|
174
|
+
case proxy_opts.first
|
175
|
+
when :proxy_http_basic_authentication
|
176
|
+
opt_proxy, proxy_user, proxy_pass = options.fetch(:proxy_http_basic_authentication)
|
177
|
+
proxy_user = proxy_user.to_str
|
178
|
+
proxy_pass = proxy_pass.to_str
|
179
|
+
if opt_proxy == true
|
180
|
+
raise ArgumentError.new("Invalid authenticated proxy option: #{options[:proxy_http_basic_authentication].inspect}")
|
181
|
+
end
|
182
|
+
when :proxy
|
183
|
+
opt_proxy = options.fetch(:proxy)
|
184
|
+
proxy_user = nil
|
185
|
+
proxy_pass = nil
|
186
|
+
when nil
|
187
|
+
opt_proxy = true
|
188
|
+
proxy_user = nil
|
189
|
+
proxy_pass = nil
|
190
|
+
end
|
191
|
+
case opt_proxy
|
146
192
|
when true
|
147
|
-
find_proxy = lambda {|u| u.find_proxy}
|
193
|
+
find_proxy = lambda {|u| pxy = u.find_proxy; pxy ? [pxy, nil, nil] : nil}
|
148
194
|
when nil, false
|
149
195
|
find_proxy = lambda {|u| nil}
|
150
196
|
when String
|
151
197
|
opt_proxy = URI.parse(opt_proxy)
|
152
|
-
find_proxy = lambda {|u| opt_proxy}
|
198
|
+
find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
|
153
199
|
when URI::Generic
|
154
|
-
find_proxy = lambda {|u| opt_proxy}
|
200
|
+
find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
|
155
201
|
else
|
156
202
|
raise ArgumentError.new("Invalid proxy option: #{opt_proxy}")
|
157
203
|
end
|
@@ -170,6 +216,9 @@ module OpenURI
|
|
170
216
|
# URI. It is converted to absolute URI using uri as a base URI.
|
171
217
|
redirect = uri + redirect
|
172
218
|
end
|
219
|
+
if !options.fetch(:redirect, true)
|
220
|
+
raise HTTPRedirect.new(buf.io.status.join(' '), buf.io, redirect)
|
221
|
+
end
|
173
222
|
unless OpenURI.redirectable?(uri, redirect)
|
174
223
|
raise "redirection forbidden: #{uri} -> #{redirect}"
|
175
224
|
end
|
@@ -192,7 +241,10 @@ module OpenURI
|
|
192
241
|
|
193
242
|
def OpenURI.redirectable?(uri1, uri2) # :nodoc:
|
194
243
|
# This test is intended to forbid a redirection from http://... to
|
195
|
-
# file:///etc/passwd.
|
244
|
+
# file:///etc/passwd, file:///dev/zero, etc. CVE-2011-1521
|
245
|
+
# https to http redirect is also forbidden intentionally.
|
246
|
+
# It avoids sending secure cookie or referer by non-secure HTTP protocol.
|
247
|
+
# (RFC 2109 4.3.1, RFC 2965 3.3, RFC 2616 15.1.3)
|
196
248
|
# However this is ad hoc. It should be extensible/configurable.
|
197
249
|
uri1.scheme.downcase == uri2.scheme.downcase ||
|
198
250
|
(/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
|
@@ -200,7 +252,8 @@ module OpenURI
|
|
200
252
|
|
201
253
|
def OpenURI.open_http(buf, target, proxy, options) # :nodoc:
|
202
254
|
if proxy
|
203
|
-
|
255
|
+
proxy_uri, proxy_user, proxy_pass = proxy
|
256
|
+
raise "Non-HTTP proxy URI: #{proxy_uri}" if proxy_uri.class != URI::HTTP
|
204
257
|
end
|
205
258
|
|
206
259
|
if target.userinfo && "1.9.0" <= RUBY_VERSION
|
@@ -208,35 +261,53 @@ module OpenURI
|
|
208
261
|
raise ArgumentError, "userinfo not supported. [RFC3986]"
|
209
262
|
end
|
210
263
|
|
264
|
+
header = {}
|
265
|
+
options.each {|k, v| header[k] = v if String === k }
|
266
|
+
|
211
267
|
require 'net/http'
|
212
268
|
klass = Net::HTTP
|
213
269
|
if URI::HTTP === target
|
214
270
|
# HTTP or HTTPS
|
215
271
|
if proxy
|
216
|
-
|
272
|
+
if proxy_user && proxy_pass
|
273
|
+
klass = Net::HTTP::Proxy(proxy_uri.hostname, proxy_uri.port, proxy_user, proxy_pass)
|
274
|
+
else
|
275
|
+
klass = Net::HTTP::Proxy(proxy_uri.hostname, proxy_uri.port)
|
276
|
+
end
|
217
277
|
end
|
218
|
-
target_host = target.
|
278
|
+
target_host = target.hostname
|
219
279
|
target_port = target.port
|
220
280
|
request_uri = target.request_uri
|
221
281
|
else
|
222
282
|
# FTP over HTTP proxy
|
223
|
-
target_host =
|
224
|
-
target_port =
|
283
|
+
target_host = proxy_uri.hostname
|
284
|
+
target_port = proxy_uri.port
|
225
285
|
request_uri = target.to_s
|
286
|
+
if proxy_user && proxy_pass
|
287
|
+
header["Proxy-Authorization"] = 'Basic ' + ["#{proxy_user}:#{proxy_pass}"].pack('m').delete("\r\n")
|
288
|
+
end
|
226
289
|
end
|
227
290
|
|
228
291
|
http = klass.new(target_host, target_port)
|
229
292
|
if target.class == URI::HTTPS
|
230
293
|
require 'net/https'
|
231
294
|
http.use_ssl = true
|
232
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
295
|
+
http.verify_mode = options[:ssl_verify_mode] || OpenSSL::SSL::VERIFY_PEER
|
233
296
|
store = OpenSSL::X509::Store.new
|
234
|
-
|
297
|
+
if options[:ssl_ca_cert]
|
298
|
+
if File.directory? options[:ssl_ca_cert]
|
299
|
+
store.add_path options[:ssl_ca_cert]
|
300
|
+
else
|
301
|
+
store.add_file options[:ssl_ca_cert]
|
302
|
+
end
|
303
|
+
else
|
304
|
+
store.set_default_paths
|
305
|
+
end
|
235
306
|
http.cert_store = store
|
236
307
|
end
|
237
|
-
|
238
|
-
|
239
|
-
|
308
|
+
if options.include? :read_timeout
|
309
|
+
http.read_timeout = options[:read_timeout]
|
310
|
+
end
|
240
311
|
|
241
312
|
resp = nil
|
242
313
|
http.start {
|
@@ -272,7 +343,12 @@ module OpenURI
|
|
272
343
|
Net::HTTPFound, # 302
|
273
344
|
Net::HTTPSeeOther, # 303
|
274
345
|
Net::HTTPTemporaryRedirect # 307
|
275
|
-
|
346
|
+
begin
|
347
|
+
loc_uri = URI.parse(resp['location'])
|
348
|
+
rescue URI::InvalidURIError
|
349
|
+
raise OpenURI::HTTPError.new(io.status.join(' ') + ' (Invalid Location URI)', io)
|
350
|
+
end
|
351
|
+
throw :open_uri_redirect, loc_uri
|
276
352
|
else
|
277
353
|
raise OpenURI::HTTPError.new(io.status.join(' '), io)
|
278
354
|
end
|
@@ -286,7 +362,17 @@ module OpenURI
|
|
286
362
|
attr_reader :io
|
287
363
|
end
|
288
364
|
|
289
|
-
|
365
|
+
# Raised on redirection,
|
366
|
+
# only occurs when +redirect+ option for HTTP is +false+.
|
367
|
+
class HTTPRedirect < HTTPError
|
368
|
+
def initialize(message, io, uri)
|
369
|
+
super(message, io)
|
370
|
+
@uri = uri
|
371
|
+
end
|
372
|
+
attr_reader :uri
|
373
|
+
end
|
374
|
+
|
375
|
+
class Buffer # :nodoc: all
|
290
376
|
def initialize
|
291
377
|
@io = StringIO.new
|
292
378
|
@size = 0
|
@@ -301,14 +387,14 @@ module OpenURI
|
|
301
387
|
require 'tempfile'
|
302
388
|
io = Tempfile.new('open-uri')
|
303
389
|
io.binmode
|
304
|
-
Meta.init io, @io if @io
|
390
|
+
Meta.init io, @io if Meta === @io
|
305
391
|
io << @io.string
|
306
392
|
@io = io
|
307
393
|
end
|
308
394
|
end
|
309
395
|
|
310
396
|
def io
|
311
|
-
Meta.init @io unless @io
|
397
|
+
Meta.init @io unless Meta === @io
|
312
398
|
@io
|
313
399
|
end
|
314
400
|
end
|
@@ -330,22 +416,43 @@ module OpenURI
|
|
330
416
|
end
|
331
417
|
end
|
332
418
|
|
333
|
-
# returns an Array
|
419
|
+
# returns an Array that consists of status code and message.
|
334
420
|
attr_accessor :status
|
335
421
|
|
336
|
-
# returns a URI
|
337
|
-
# It may differ from the URI supplied by a user
|
422
|
+
# returns a URI that is the base of relative URIs in the data.
|
423
|
+
# It may differ from the URI supplied by a user due to redirection.
|
338
424
|
attr_accessor :base_uri
|
339
425
|
|
340
|
-
# returns a Hash
|
426
|
+
# returns a Hash that represents header fields.
|
341
427
|
# The Hash keys are downcased for canonicalization.
|
342
428
|
attr_reader :meta
|
343
429
|
|
430
|
+
def meta_setup_encoding # :nodoc:
|
431
|
+
charset = self.charset
|
432
|
+
enc = nil
|
433
|
+
if charset
|
434
|
+
begin
|
435
|
+
enc = Encoding.find(charset)
|
436
|
+
rescue ArgumentError
|
437
|
+
end
|
438
|
+
end
|
439
|
+
enc = Encoding::ASCII_8BIT unless enc
|
440
|
+
if self.respond_to? :force_encoding
|
441
|
+
self.force_encoding(enc)
|
442
|
+
elsif self.respond_to? :string
|
443
|
+
self.string.force_encoding(enc)
|
444
|
+
else # Tempfile
|
445
|
+
self.set_encoding enc
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
344
449
|
def meta_add_field(name, value) # :nodoc:
|
345
|
-
|
450
|
+
name = name.downcase
|
451
|
+
@meta[name] = value
|
452
|
+
meta_setup_encoding if name == 'content-type'
|
346
453
|
end
|
347
454
|
|
348
|
-
# returns a Time
|
455
|
+
# returns a Time that represents the Last-Modified field.
|
349
456
|
def last_modified
|
350
457
|
if v = @meta['last-modified']
|
351
458
|
Time.httpdate(v)
|
@@ -354,10 +461,12 @@ module OpenURI
|
|
354
461
|
end
|
355
462
|
end
|
356
463
|
|
464
|
+
# :stopdoc:
|
357
465
|
RE_LWS = /[\r\n\t ]+/n
|
358
466
|
RE_TOKEN = %r{[^\x00- ()<>@,;:\\"/\[\]?={}\x7f]+}n
|
359
467
|
RE_QUOTED_STRING = %r{"(?:[\r\n\t !#-\[\]-~\x80-\xff]|\\[\x00-\x7f])*"}n
|
360
468
|
RE_PARAMETERS = %r{(?:;#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?=#{RE_LWS}?(?:#{RE_TOKEN}|#{RE_QUOTED_STRING})#{RE_LWS}?)*}n
|
469
|
+
# :startdoc:
|
361
470
|
|
362
471
|
def content_type_parse # :nodoc:
|
363
472
|
v = @meta['content-type']
|
@@ -367,7 +476,9 @@ module OpenURI
|
|
367
476
|
subtype = $2.downcase
|
368
477
|
parameters = []
|
369
478
|
$3.scan(/;#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?=#{RE_LWS}?(?:(#{RE_TOKEN})|(#{RE_QUOTED_STRING}))/no) {|att, val, qval|
|
370
|
-
|
479
|
+
if qval
|
480
|
+
val = qval[1...-1].gsub(/[\r\n\t !#-\[\]-~\x80-\xff]+|(\\[\x00-\x7f])/n) { $1 ? $1[1,1] : $& }
|
481
|
+
end
|
371
482
|
parameters << [att.downcase, val]
|
372
483
|
}
|
373
484
|
["#{type}/#{subtype}", *parameters]
|
@@ -380,7 +491,7 @@ module OpenURI
|
|
380
491
|
# It is downcased for canonicalization.
|
381
492
|
# Content-Type parameters are stripped.
|
382
493
|
def content_type
|
383
|
-
type, *
|
494
|
+
type, *_ = content_type_parse
|
384
495
|
type || 'application/octet-stream'
|
385
496
|
end
|
386
497
|
|
@@ -426,22 +537,25 @@ module OpenURI
|
|
426
537
|
# OpenURI::OpenRead#open provides `open' for URI::HTTP and URI::FTP.
|
427
538
|
#
|
428
539
|
# OpenURI::OpenRead#open takes optional 3 arguments as:
|
429
|
-
# OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }]
|
430
540
|
#
|
431
|
-
#
|
541
|
+
# OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }]
|
542
|
+
#
|
543
|
+
# OpenURI::OpenRead#open returns an IO-like object if block is not given.
|
544
|
+
# Otherwise it yields the IO object and return the value of the block.
|
545
|
+
# The IO object is extended with OpenURI::Meta.
|
546
|
+
#
|
547
|
+
# +mode+ and +perm+ are the same as Kernel#open.
|
432
548
|
#
|
433
|
-
# However,
|
549
|
+
# However, +mode+ must be read mode because OpenURI::OpenRead#open doesn't
|
434
550
|
# support write mode (yet).
|
435
|
-
# Also
|
436
|
-
# creation.
|
551
|
+
# Also +perm+ is ignored because it is meaningful only for file creation.
|
437
552
|
#
|
438
|
-
#
|
553
|
+
# +options+ must be a hash.
|
439
554
|
#
|
440
|
-
# Each
|
441
|
-
#
|
442
|
-
# I.e. it is ignored for FTP without HTTP proxy.
|
555
|
+
# Each option with a string key specifies an extra header field for HTTP.
|
556
|
+
# I.e., it is ignored for FTP without HTTP proxy.
|
443
557
|
#
|
444
|
-
# The hash may include other options
|
558
|
+
# The hash may include other options, where keys are symbols:
|
445
559
|
#
|
446
560
|
# [:proxy]
|
447
561
|
# Synopsis:
|
@@ -450,16 +564,37 @@ module OpenURI
|
|
450
564
|
# :proxy => true
|
451
565
|
# :proxy => false
|
452
566
|
# :proxy => nil
|
453
|
-
#
|
567
|
+
#
|
454
568
|
# If :proxy option is specified, the value should be String, URI,
|
455
569
|
# boolean or nil.
|
570
|
+
#
|
456
571
|
# When String or URI is given, it is treated as proxy URI.
|
572
|
+
#
|
457
573
|
# When true is given or the option itself is not specified,
|
458
574
|
# environment variable `scheme_proxy' is examined.
|
459
575
|
# `scheme' is replaced by `http', `https' or `ftp'.
|
576
|
+
#
|
460
577
|
# When false or nil is given, the environment variables are ignored and
|
461
578
|
# connection will be made to a server directly.
|
462
579
|
#
|
580
|
+
# [:proxy_http_basic_authentication]
|
581
|
+
# Synopsis:
|
582
|
+
# :proxy_http_basic_authentication =>
|
583
|
+
# ["http://proxy.foo.com:8000/", "proxy-user", "proxy-password"]
|
584
|
+
# :proxy_http_basic_authentication =>
|
585
|
+
# [URI.parse("http://proxy.foo.com:8000/"),
|
586
|
+
# "proxy-user", "proxy-password"]
|
587
|
+
#
|
588
|
+
# If :proxy option is specified, the value should be an Array with 3
|
589
|
+
# elements. It should contain a proxy URI, a proxy user name and a proxy
|
590
|
+
# password. The proxy URI should be a String, an URI or nil. The proxy
|
591
|
+
# user name and password should be a String.
|
592
|
+
#
|
593
|
+
# If nil is given for the proxy URI, this option is just ignored.
|
594
|
+
#
|
595
|
+
# If :proxy and :proxy_http_basic_authentication is specified,
|
596
|
+
# ArgumentError is raised.
|
597
|
+
#
|
463
598
|
# [:http_basic_authentication]
|
464
599
|
# Synopsis:
|
465
600
|
# :http_basic_authentication=>[user, password]
|
@@ -472,17 +607,16 @@ module OpenURI
|
|
472
607
|
# [:content_length_proc]
|
473
608
|
# Synopsis:
|
474
609
|
# :content_length_proc => lambda {|content_length| ... }
|
475
|
-
#
|
610
|
+
#
|
476
611
|
# If :content_length_proc option is specified, the option value procedure
|
477
612
|
# is called before actual transfer is started.
|
478
|
-
# It takes one argument which is expected content length in bytes.
|
479
|
-
#
|
613
|
+
# It takes one argument, which is expected content length in bytes.
|
614
|
+
#
|
480
615
|
# If two or more transfer is done by HTTP redirection, the procedure
|
481
616
|
# is called only one for a last transfer.
|
482
|
-
#
|
617
|
+
#
|
483
618
|
# When expected content length is unknown, the procedure is called with
|
484
|
-
# nil.
|
485
|
-
# It is happen when HTTP response has no Content-Length header.
|
619
|
+
# nil. This happens when the HTTP response has no Content-Length header.
|
486
620
|
#
|
487
621
|
# [:progress_proc]
|
488
622
|
# Synopsis:
|
@@ -490,7 +624,7 @@ module OpenURI
|
|
490
624
|
#
|
491
625
|
# If :progress_proc option is specified, the proc is called with one
|
492
626
|
# argument each time when `open' gets content fragment from network.
|
493
|
-
# The argument
|
627
|
+
# The argument +size+ is the accumulated transferred size in bytes.
|
494
628
|
#
|
495
629
|
# If two or more transfer is done by HTTP redirection, the procedure
|
496
630
|
# is called only one for a last transfer.
|
@@ -511,9 +645,45 @@ module OpenURI
|
|
511
645
|
# pbar.set s if pbar
|
512
646
|
# }) {|f| ... }
|
513
647
|
#
|
514
|
-
#
|
515
|
-
#
|
516
|
-
#
|
648
|
+
# [:read_timeout]
|
649
|
+
# Synopsis:
|
650
|
+
# :read_timeout=>nil (no timeout)
|
651
|
+
# :read_timeout=>10 (10 second)
|
652
|
+
#
|
653
|
+
# :read_timeout option specifies a timeout of read for http connections.
|
654
|
+
#
|
655
|
+
# [:ssl_ca_cert]
|
656
|
+
# Synopsis:
|
657
|
+
# :ssl_ca_cert=>filename
|
658
|
+
#
|
659
|
+
# :ssl_ca_cert is used to specify CA certificate for SSL.
|
660
|
+
# If it is given, default certificates are not used.
|
661
|
+
#
|
662
|
+
# [:ssl_verify_mode]
|
663
|
+
# Synopsis:
|
664
|
+
# :ssl_verify_mode=>mode
|
665
|
+
#
|
666
|
+
# :ssl_verify_mode is used to specify openssl verify mode.
|
667
|
+
#
|
668
|
+
# [:ftp_active_mode]
|
669
|
+
# Synopsis:
|
670
|
+
# :ftp_active_mode=>bool
|
671
|
+
#
|
672
|
+
# <tt>:ftp_active_mode => true</tt> is used to make ftp active mode.
|
673
|
+
# Ruby 1.9 uses passive mode by default.
|
674
|
+
# Note that the active mode is default in Ruby 1.8 or prior.
|
675
|
+
#
|
676
|
+
# [:redirect]
|
677
|
+
# Synopsis:
|
678
|
+
# :redirect=>bool
|
679
|
+
#
|
680
|
+
# +:redirect+ is true by default. <tt>:redirect => false</tt> is used to
|
681
|
+
# disable all HTTP redirects.
|
682
|
+
#
|
683
|
+
# OpenURI::HTTPRedirect exception raised on redirection.
|
684
|
+
# Using +true+ also means that redirections between http and ftp are
|
685
|
+
# permitted.
|
686
|
+
#
|
517
687
|
def open(*rest, &block)
|
518
688
|
OpenURI.open_uri(self, *rest, &block)
|
519
689
|
end
|
@@ -521,7 +691,7 @@ module OpenURI
|
|
521
691
|
# OpenURI::OpenRead#read([options]) reads a content referenced by self and
|
522
692
|
# returns the content as string.
|
523
693
|
# The string is extended with OpenURI::Meta.
|
524
|
-
# The argument
|
694
|
+
# The argument +options+ is same as OpenURI::OpenRead#open.
|
525
695
|
def read(options={})
|
526
696
|
self.open(options) {|f|
|
527
697
|
str = f.read
|
@@ -533,84 +703,6 @@ module OpenURI
|
|
533
703
|
end
|
534
704
|
|
535
705
|
module URI
|
536
|
-
class Generic
|
537
|
-
# returns a proxy URI.
|
538
|
-
# The proxy URI is obtained from environment variables such as http_proxy,
|
539
|
-
# ftp_proxy, no_proxy, etc.
|
540
|
-
# If there is no proper proxy, nil is returned.
|
541
|
-
#
|
542
|
-
# Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)
|
543
|
-
# are examined too.
|
544
|
-
#
|
545
|
-
# But http_proxy and HTTP_PROXY is treated specially under CGI environment.
|
546
|
-
# It's because HTTP_PROXY may be set by Proxy: header.
|
547
|
-
# So HTTP_PROXY is not used.
|
548
|
-
# http_proxy is not used too if the variable is case insensitive.
|
549
|
-
# CGI_HTTP_PROXY can be used instead.
|
550
|
-
def find_proxy
|
551
|
-
name = self.scheme.downcase + '_proxy'
|
552
|
-
proxy_uri = nil
|
553
|
-
if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?
|
554
|
-
# HTTP_PROXY conflicts with *_proxy for proxy settings and
|
555
|
-
# HTTP_* for header information in CGI.
|
556
|
-
# So it should be careful to use it.
|
557
|
-
pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
|
558
|
-
case pairs.length
|
559
|
-
when 0 # no proxy setting anyway.
|
560
|
-
proxy_uri = nil
|
561
|
-
when 1
|
562
|
-
k, v = pairs.shift
|
563
|
-
if k == 'http_proxy' && ENV[k.upcase] == nil
|
564
|
-
# http_proxy is safe to use because ENV is case sensitive.
|
565
|
-
proxy_uri = ENV[name]
|
566
|
-
else
|
567
|
-
proxy_uri = nil
|
568
|
-
end
|
569
|
-
else # http_proxy is safe to use because ENV is case sensitive.
|
570
|
-
proxy_uri = ENV.to_hash[name]
|
571
|
-
end
|
572
|
-
if !proxy_uri
|
573
|
-
# Use CGI_HTTP_PROXY. cf. libwww-perl.
|
574
|
-
proxy_uri = ENV["CGI_#{name.upcase}"]
|
575
|
-
end
|
576
|
-
elsif name == 'http_proxy'
|
577
|
-
unless proxy_uri = ENV[name]
|
578
|
-
if proxy_uri = ENV[name.upcase]
|
579
|
-
warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.'
|
580
|
-
end
|
581
|
-
end
|
582
|
-
else
|
583
|
-
proxy_uri = ENV[name] || ENV[name.upcase]
|
584
|
-
end
|
585
|
-
|
586
|
-
if proxy_uri && self.host
|
587
|
-
require 'socket'
|
588
|
-
begin
|
589
|
-
addr = IPSocket.getaddress(self.host)
|
590
|
-
proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr
|
591
|
-
rescue SocketError
|
592
|
-
end
|
593
|
-
end
|
594
|
-
|
595
|
-
if proxy_uri
|
596
|
-
proxy_uri = URI.parse(proxy_uri)
|
597
|
-
name = 'no_proxy'
|
598
|
-
if no_proxy = ENV[name] || ENV[name.upcase]
|
599
|
-
no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
|
600
|
-
if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host &&
|
601
|
-
(!port || self.port == port.to_i)
|
602
|
-
proxy_uri = nil
|
603
|
-
break
|
604
|
-
end
|
605
|
-
}
|
606
|
-
end
|
607
|
-
proxy_uri
|
608
|
-
else
|
609
|
-
nil
|
610
|
-
end
|
611
|
-
end
|
612
|
-
end
|
613
|
-
|
614
706
|
class HTTP
|
615
707
|
def buffer_open(buf, proxy, options) # :nodoc:
|
616
708
|
OpenURI.open_http(buf, self, proxy, options)
|
@@ -627,8 +719,9 @@ module URI
|
|
627
719
|
end
|
628
720
|
require 'net/ftp'
|
629
721
|
|
630
|
-
|
631
|
-
|
722
|
+
path = self.path
|
723
|
+
path = path.sub(%r{\A/}, '%2F') # re-encode the beginning slash because uri library decodes it.
|
724
|
+
directories = path.split(%r{/}, -1)
|
632
725
|
directories.each {|d|
|
633
726
|
d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
|
634
727
|
}
|
@@ -649,7 +742,9 @@ module URI
|
|
649
742
|
end
|
650
743
|
|
651
744
|
# The access sequence is defined by RFC 1738
|
652
|
-
ftp = Net::FTP.
|
745
|
+
ftp = Net::FTP.new
|
746
|
+
ftp.connect(self.hostname, self.port)
|
747
|
+
ftp.passive = true if !options[:ftp_active_mode]
|
653
748
|
# todo: extract user/passwd from .netrc.
|
654
749
|
user = 'anonymous'
|
655
750
|
passwd = nil
|
data/rubysl-open-uri.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubysl-open-uri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Shirai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.5'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rubysl-prettyprint
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ~>
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.0'
|
69
55
|
description: Ruby standard library uri.
|
70
56
|
email:
|
71
57
|
- brixen@gmail.com
|