rubysl-open-uri 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|