athlite_open-uri 0.0.1

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.
File without changes
@@ -0,0 +1,3 @@
1
+ === 0.0.1 2011-11-08
2
+
3
+ * Ripped from standard lib, and added the possibility to add option :ssl_verify
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ lib/open-uri.rb
6
+ test/test_helper.rb
7
+ test/test_open-uri.rb
@@ -0,0 +1,13 @@
1
+ = open-uri
2
+
3
+ * http://github.com/athlite/open-uri
4
+
5
+ == DESCRIPTION:
6
+
7
+ OpenURI ripped from 1.8.7's standard lib. Added option, :ssl_verify, which makes it possible to skip certificate verification.
8
+
9
+ == SYNOPSIS:
10
+
11
+ open(url, :ssl_verify => false|true)
12
+
13
+
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+ require './lib/open-uri'
6
+
7
+ Hoe.plugin :newgem
8
+
9
+ $hoe = Hoe.spec 'athlite_open-uri' do
10
+ self.version = "0.0.1"
11
+ self.developer 'Thomas Tinnesand Eng', 'thomas.tinnesand.eng@gmail.com'
12
+ self.rubyforge_name = self.name
13
+ end
14
+
15
+ require 'newgem/tasks'
16
+ Dir['tasks/**/*.rake'].each { |t| load t }
@@ -0,0 +1,686 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'uri'
5
+ require 'stringio'
6
+ require 'time'
7
+
8
+ module Kernel
9
+ private
10
+ alias open_uri_original_open open # :nodoc:
11
+
12
+ # makes possible to open various resources including URIs.
13
+ # If the first argument respond to `open' method,
14
+ # the method is called with the rest arguments.
15
+ #
16
+ # If the first argument is a string which begins with xxx://,
17
+ # it is parsed by URI.parse. If the parsed object respond to `open' method,
18
+ # the method is called with the rest arguments.
19
+ #
20
+ # Otherwise original open is called.
21
+ #
22
+ # Since open-uri.rb provides URI::HTTP#open, URI::HTTPS#open and
23
+ # URI::FTP#open,
24
+ # Kernel[#.]open can accepts such URIs and strings which begins with
25
+ # http://, https:// and ftp://.
26
+ # In these case, the opened file object is extended by OpenURI::Meta.
27
+ def open(name, *rest, &block) # :doc:
28
+ if name.respond_to?(:open)
29
+ name.open(*rest, &block)
30
+ elsif name.respond_to?(:to_str) &&
31
+ %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ name &&
32
+ (uri = URI.parse(name)).respond_to?(:open)
33
+ uri.open(*rest, &block)
34
+ else
35
+ open_uri_original_open(name, *rest, &block)
36
+ end
37
+ end
38
+ module_function :open
39
+ end
40
+
41
+ # OpenURI is an easy-to-use wrapper for net/http, net/https and net/ftp.
42
+ #
43
+ #== Example
44
+ #
45
+ # It is possible to open http/https/ftp URL as usual like opening a file:
46
+ #
47
+ # open("http://www.ruby-lang.org/") {|f|
48
+ # f.each_line {|line| p line}
49
+ # }
50
+ #
51
+ # The opened file has several methods for meta information as follows since
52
+ # it is extended by OpenURI::Meta.
53
+ #
54
+ # open("http://www.ruby-lang.org/en") {|f|
55
+ # f.each_line {|line| p line}
56
+ # p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
57
+ # p f.content_type # "text/html"
58
+ # p f.charset # "iso-8859-1"
59
+ # p f.content_encoding # []
60
+ # p f.last_modified # Thu Dec 05 02:45:02 UTC 2002
61
+ # }
62
+ #
63
+ # Additional header fields can be specified by an optional hash argument.
64
+ #
65
+ # open("http://www.ruby-lang.org/en/",
66
+ # "User-Agent" => "Ruby/#{RUBY_VERSION}",
67
+ # "From" => "foo@bar.invalid",
68
+ # "Referer" => "http://www.ruby-lang.org/") {|f|
69
+ # # ...
70
+ # }
71
+ #
72
+ # The environment variables such as http_proxy, https_proxy and ftp_proxy
73
+ # are in effect by default. :proxy => nil disables proxy.
74
+ #
75
+ # open("http://www.ruby-lang.org/en/raa.html", :proxy => nil) {|f|
76
+ # # ...
77
+ # }
78
+ #
79
+ # URI objects can be opened in a similar way.
80
+ #
81
+ # uri = URI.parse("http://www.ruby-lang.org/en/")
82
+ # uri.open {|f|
83
+ # # ...
84
+ # }
85
+ #
86
+ # URI objects can be read directly. The returned string is also extended by
87
+ # OpenURI::Meta.
88
+ #
89
+ # str = uri.read
90
+ # p str.base_uri
91
+ #
92
+ # Author:: Tanaka Akira <akr@m17n.org>
93
+
94
+ module OpenURI
95
+ Options = {
96
+ :proxy => true,
97
+ :progress_proc => true,
98
+ :content_length_proc => true,
99
+ :http_basic_authentication => true,
100
+ :ssl_verify => true
101
+ }
102
+
103
+ def OpenURI.check_options(options) # :nodoc:
104
+ options.each {|k, v|
105
+ next unless Symbol === k
106
+ unless Options.include? k
107
+ raise ArgumentError, "unrecognized option: #{k}"
108
+ end
109
+ }
110
+ end
111
+
112
+ def OpenURI.scan_open_optional_arguments(*rest) # :nodoc:
113
+ if !rest.empty? && (String === rest.first || Integer === rest.first)
114
+ mode = rest.shift
115
+ if !rest.empty? && Integer === rest.first
116
+ perm = rest.shift
117
+ end
118
+ end
119
+ return mode, perm, rest
120
+ end
121
+
122
+ def OpenURI.open_uri(name, *rest) # :nodoc:
123
+ uri = URI::Generic === name ? name : URI.parse(name)
124
+ mode, perm, rest = OpenURI.scan_open_optional_arguments(*rest)
125
+ options = rest.shift if !rest.empty? && Hash === rest.first
126
+ raise ArgumentError.new("extra arguments") if !rest.empty?
127
+ options ||= {}
128
+ OpenURI.check_options(options)
129
+
130
+ unless mode == nil ||
131
+ mode == 'r' || mode == 'rb' ||
132
+ mode == File::RDONLY
133
+ raise ArgumentError.new("invalid access mode #{mode} (#{uri.class} resource is read only.)")
134
+ end
135
+
136
+ io = open_loop(uri, options)
137
+ if block_given?
138
+ begin
139
+ yield io
140
+ ensure
141
+ io.close
142
+ end
143
+ else
144
+ io
145
+ end
146
+ end
147
+
148
+ def OpenURI.open_loop(uri, options) # :nodoc:
149
+ case opt_proxy = options.fetch(:proxy, true)
150
+ when true
151
+ find_proxy = lambda {|u| u.find_proxy}
152
+ when nil, false
153
+ find_proxy = lambda {|u| nil}
154
+ when String
155
+ opt_proxy = URI.parse(opt_proxy)
156
+ find_proxy = lambda {|u| opt_proxy}
157
+ when URI::Generic
158
+ find_proxy = lambda {|u| opt_proxy}
159
+ else
160
+ raise ArgumentError.new("Invalid proxy option: #{opt_proxy}")
161
+ end
162
+
163
+ uri_set = {}
164
+ buf = nil
165
+ while true
166
+ redirect = catch(:open_uri_redirect) {
167
+ buf = Buffer.new
168
+ uri.buffer_open(buf, find_proxy.call(uri), options)
169
+ nil
170
+ }
171
+ if redirect
172
+ if redirect.relative?
173
+ # Although it violates RFC2616, Location: field may have relative
174
+ # URI. It is converted to absolute URI using uri as a base URI.
175
+ redirect = uri + redirect
176
+ end
177
+ unless OpenURI.redirectable?(uri, redirect)
178
+ raise "redirection forbidden: #{uri} -> #{redirect}"
179
+ end
180
+ if options.include? :http_basic_authentication
181
+ # send authentication only for the URI directly specified.
182
+ options = options.dup
183
+ options.delete :http_basic_authentication
184
+ end
185
+ uri = redirect
186
+ raise "HTTP redirection loop: #{uri}" if uri_set.include? uri.to_s
187
+ uri_set[uri.to_s] = true
188
+ else
189
+ break
190
+ end
191
+ end
192
+ io = buf.io
193
+ io.base_uri = uri
194
+ io
195
+ end
196
+
197
+ def OpenURI.redirectable?(uri1, uri2) # :nodoc:
198
+ # This test is intended to forbid a redirection from http://... to
199
+ # file:///etc/passwd.
200
+ # However this is ad hoc. It should be extensible/configurable.
201
+ uri1.scheme.downcase == uri2.scheme.downcase ||
202
+ (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
203
+ end
204
+
205
+ def OpenURI.open_http(buf, target, proxy, options) # :nodoc:
206
+ if proxy
207
+ raise "Non-HTTP proxy URI: #{proxy}" if proxy.class != URI::HTTP
208
+ end
209
+
210
+ if target.userinfo && "1.9.0" <= RUBY_VERSION
211
+ # don't raise for 1.8 because compatibility.
212
+ raise ArgumentError, "userinfo not supported. [RFC3986]"
213
+ end
214
+
215
+ require 'net/http'
216
+ klass = Net::HTTP
217
+ if URI::HTTP === target
218
+ # HTTP or HTTPS
219
+ if proxy
220
+ klass = Net::HTTP::Proxy(proxy.host, proxy.port)
221
+ end
222
+ target_host = target.host
223
+ target_port = target.port
224
+ request_uri = target.request_uri
225
+ else
226
+ # FTP over HTTP proxy
227
+ target_host = proxy.host
228
+ target_port = proxy.port
229
+ request_uri = target.to_s
230
+ end
231
+
232
+ http = klass.new(target_host, target_port)
233
+ if target.class == URI::HTTPS
234
+ require 'net/https'
235
+ http.use_ssl = true
236
+ if options[:ssl_verify]
237
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
238
+ else
239
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
240
+ end
241
+ store = OpenSSL::X509::Store.new
242
+ store.set_default_paths
243
+ http.cert_store = store
244
+ end
245
+
246
+ header = {}
247
+ options.each {|k, v| header[k] = v if String === k }
248
+
249
+ resp = nil
250
+ http.start {
251
+ req = Net::HTTP::Get.new(request_uri, header)
252
+ if options.include? :http_basic_authentication
253
+ user, pass = options[:http_basic_authentication]
254
+ req.basic_auth user, pass
255
+ end
256
+ http.request(req) {|response|
257
+ resp = response
258
+ if options[:content_length_proc] && Net::HTTPSuccess === resp
259
+ if resp.key?('Content-Length')
260
+ options[:content_length_proc].call(resp['Content-Length'].to_i)
261
+ else
262
+ options[:content_length_proc].call(nil)
263
+ end
264
+ end
265
+ resp.read_body {|str|
266
+ buf << str
267
+ if options[:progress_proc] && Net::HTTPSuccess === resp
268
+ options[:progress_proc].call(buf.size)
269
+ end
270
+ }
271
+ }
272
+ }
273
+ io = buf.io
274
+ io.rewind
275
+ io.status = [resp.code, resp.message]
276
+ resp.each {|name,value| buf.io.meta_add_field name, value }
277
+ case resp
278
+ when Net::HTTPSuccess
279
+ when Net::HTTPMovedPermanently, # 301
280
+ Net::HTTPFound, # 302
281
+ Net::HTTPSeeOther, # 303
282
+ Net::HTTPTemporaryRedirect # 307
283
+ throw :open_uri_redirect, URI.parse(resp['location'])
284
+ else
285
+ raise OpenURI::HTTPError.new(io.status.join(' '), io)
286
+ end
287
+ end
288
+
289
+ class HTTPError < StandardError
290
+ def initialize(message, io)
291
+ super(message)
292
+ @io = io
293
+ end
294
+ attr_reader :io
295
+ end
296
+
297
+ class Buffer # :nodoc:
298
+ def initialize
299
+ @io = StringIO.new
300
+ @size = 0
301
+ end
302
+ attr_reader :size
303
+
304
+ StringMax = 10240
305
+ def <<(str)
306
+ @io << str
307
+ @size += str.length
308
+ if StringIO === @io && StringMax < @size
309
+ require 'tempfile'
310
+ io = Tempfile.new('open-uri')
311
+ io.binmode
312
+ Meta.init io, @io if @io.respond_to? :meta
313
+ io << @io.string
314
+ @io = io
315
+ end
316
+ end
317
+
318
+ def io
319
+ Meta.init @io unless @io.respond_to? :meta
320
+ @io
321
+ end
322
+ end
323
+
324
+ # Mixin for holding meta-information.
325
+ module Meta
326
+ def Meta.init(obj, src=nil) # :nodoc:
327
+ obj.extend Meta
328
+ obj.instance_eval {
329
+ @base_uri = nil
330
+ @meta = {}
331
+ }
332
+ if src
333
+ obj.status = src.status
334
+ obj.base_uri = src.base_uri
335
+ src.meta.each {|name, value|
336
+ obj.meta_add_field(name, value)
337
+ }
338
+ end
339
+ end
340
+
341
+ # returns an Array which consists status code and message.
342
+ attr_accessor :status
343
+
344
+ # returns a URI which is base of relative URIs in the data.
345
+ # It may differ from the URI supplied by a user because redirection.
346
+ attr_accessor :base_uri
347
+
348
+ # returns a Hash which represents header fields.
349
+ # The Hash keys are downcased for canonicalization.
350
+ attr_reader :meta
351
+
352
+ def meta_add_field(name, value) # :nodoc:
353
+ @meta[name.downcase] = value
354
+ end
355
+
356
+ # returns a Time which represents Last-Modified field.
357
+ def last_modified
358
+ if v = @meta['last-modified']
359
+ Time.httpdate(v)
360
+ else
361
+ nil
362
+ end
363
+ end
364
+
365
+ RE_LWS = /[\r\n\t ]+/n
366
+ RE_TOKEN = %r{[^\x00- ()<>@,;:\\"/\[\]?={}\x7f]+}n
367
+ RE_QUOTED_STRING = %r{"(?:[\r\n\t !#-\[\]-~\x80-\xff]|\\[\x00-\x7f])*"}n
368
+ RE_PARAMETERS = %r{(?:;#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?=#{RE_LWS}?(?:#{RE_TOKEN}|#{RE_QUOTED_STRING})#{RE_LWS}?)*}n
369
+
370
+ def content_type_parse # :nodoc:
371
+ v = @meta['content-type']
372
+ # The last (?:;#{RE_LWS}?)? matches extra ";" which violates RFC2045.
373
+ if v && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ v
374
+ type = $1.downcase
375
+ subtype = $2.downcase
376
+ parameters = []
377
+ $3.scan(/;#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?=#{RE_LWS}?(?:(#{RE_TOKEN})|(#{RE_QUOTED_STRING}))/no) {|att, val, qval|
378
+ val = qval.gsub(/[\r\n\t !#-\[\]-~\x80-\xff]+|(\\[\x00-\x7f])/) { $1 ? $1[1,1] : $& } if qval
379
+ parameters << [att.downcase, val]
380
+ }
381
+ ["#{type}/#{subtype}", *parameters]
382
+ else
383
+ nil
384
+ end
385
+ end
386
+
387
+ # returns "type/subtype" which is MIME Content-Type.
388
+ # It is downcased for canonicalization.
389
+ # Content-Type parameters are stripped.
390
+ def content_type
391
+ type, *parameters = content_type_parse
392
+ type || 'application/octet-stream'
393
+ end
394
+
395
+ # returns a charset parameter in Content-Type field.
396
+ # It is downcased for canonicalization.
397
+ #
398
+ # If charset parameter is not given but a block is given,
399
+ # the block is called and its result is returned.
400
+ # It can be used to guess charset.
401
+ #
402
+ # If charset parameter and block is not given,
403
+ # nil is returned except text type in HTTP.
404
+ # In that case, "iso-8859-1" is returned as defined by RFC2616 3.7.1.
405
+ def charset
406
+ type, *parameters = content_type_parse
407
+ if pair = parameters.assoc('charset')
408
+ pair.last.downcase
409
+ elsif block_given?
410
+ yield
411
+ elsif type && %r{\Atext/} =~ type &&
412
+ @base_uri && /\Ahttp\z/i =~ @base_uri.scheme
413
+ "iso-8859-1" # RFC2616 3.7.1
414
+ else
415
+ nil
416
+ end
417
+ end
418
+
419
+ # returns a list of encodings in Content-Encoding field
420
+ # as an Array of String.
421
+ # The encodings are downcased for canonicalization.
422
+ def content_encoding
423
+ v = @meta['content-encoding']
424
+ if v && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ v
425
+ v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase}
426
+ else
427
+ []
428
+ end
429
+ end
430
+ end
431
+
432
+ # Mixin for HTTP and FTP URIs.
433
+ module OpenRead
434
+ # OpenURI::OpenRead#open provides `open' for URI::HTTP and URI::FTP.
435
+ #
436
+ # OpenURI::OpenRead#open takes optional 3 arguments as:
437
+ # OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }]
438
+ #
439
+ # `mode', `perm' is same as Kernel#open.
440
+ #
441
+ # However, `mode' must be read mode because OpenURI::OpenRead#open doesn't
442
+ # support write mode (yet).
443
+ # Also `perm' is just ignored because it is meaningful only for file
444
+ # creation.
445
+ #
446
+ # `options' must be a hash.
447
+ #
448
+ # Each pairs which key is a string in the hash specify a extra header
449
+ # field for HTTP.
450
+ # I.e. it is ignored for FTP without HTTP proxy.
451
+ #
452
+ # The hash may include other options which key is a symbol:
453
+ #
454
+ # [:proxy]
455
+ # Synopsis:
456
+ # :proxy => "http://proxy.foo.com:8000/"
457
+ # :proxy => URI.parse("http://proxy.foo.com:8000/")
458
+ # :proxy => true
459
+ # :proxy => false
460
+ # :proxy => nil
461
+ #
462
+ # If :proxy option is specified, the value should be String, URI,
463
+ # boolean or nil.
464
+ # When String or URI is given, it is treated as proxy URI.
465
+ # When true is given or the option itself is not specified,
466
+ # environment variable `scheme_proxy' is examined.
467
+ # `scheme' is replaced by `http', `https' or `ftp'.
468
+ # When false or nil is given, the environment variables are ignored and
469
+ # connection will be made to a server directly.
470
+ #
471
+ # [:http_basic_authentication]
472
+ # Synopsis:
473
+ # :http_basic_authentication=>[user, password]
474
+ #
475
+ # If :http_basic_authentication is specified,
476
+ # the value should be an array which contains 2 strings:
477
+ # username and password.
478
+ # It is used for HTTP Basic authentication defined by RFC 2617.
479
+ #
480
+ # [:content_length_proc]
481
+ # Synopsis:
482
+ # :content_length_proc => lambda {|content_length| ... }
483
+ #
484
+ # If :content_length_proc option is specified, the option value procedure
485
+ # is called before actual transfer is started.
486
+ # It takes one argument which is expected content length in bytes.
487
+ #
488
+ # If two or more transfer is done by HTTP redirection, the procedure
489
+ # is called only one for a last transfer.
490
+ #
491
+ # When expected content length is unknown, the procedure is called with
492
+ # nil.
493
+ # It is happen when HTTP response has no Content-Length header.
494
+ #
495
+ # [:progress_proc]
496
+ # Synopsis:
497
+ # :progress_proc => lambda {|size| ...}
498
+ #
499
+ # If :progress_proc option is specified, the proc is called with one
500
+ # argument each time when `open' gets content fragment from network.
501
+ # The argument `size' `size' is a accumulated transfered size in bytes.
502
+ #
503
+ # If two or more transfer is done by HTTP redirection, the procedure
504
+ # is called only one for a last transfer.
505
+ #
506
+ # :progress_proc and :content_length_proc are intended to be used for
507
+ # progress bar.
508
+ # For example, it can be implemented as follows using Ruby/ProgressBar.
509
+ #
510
+ # pbar = nil
511
+ # open("http://...",
512
+ # :content_length_proc => lambda {|t|
513
+ # if t && 0 < t
514
+ # pbar = ProgressBar.new("...", t)
515
+ # pbar.file_transfer_mode
516
+ # end
517
+ # },
518
+ # :progress_proc => lambda {|s|
519
+ # pbar.set s if pbar
520
+ # }) {|f| ... }
521
+ #
522
+ # OpenURI::OpenRead#open returns an IO like object if block is not given.
523
+ # Otherwise it yields the IO object and return the value of the block.
524
+ # The IO object is extended with OpenURI::Meta.
525
+ def open(*rest, &block)
526
+ OpenURI.open_uri(self, *rest, &block)
527
+ end
528
+
529
+ # OpenURI::OpenRead#read([options]) reads a content referenced by self and
530
+ # returns the content as string.
531
+ # The string is extended with OpenURI::Meta.
532
+ # The argument `options' is same as OpenURI::OpenRead#open.
533
+ def read(options={})
534
+ self.open(options) {|f|
535
+ str = f.read
536
+ Meta.init str, f
537
+ str
538
+ }
539
+ end
540
+ end
541
+ end
542
+
543
+ module URI
544
+ class Generic
545
+ # returns a proxy URI.
546
+ # The proxy URI is obtained from environment variables such as http_proxy,
547
+ # ftp_proxy, no_proxy, etc.
548
+ # If there is no proper proxy, nil is returned.
549
+ #
550
+ # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)
551
+ # are examined too.
552
+ #
553
+ # But http_proxy and HTTP_PROXY is treated specially under CGI environment.
554
+ # It's because HTTP_PROXY may be set by Proxy: header.
555
+ # So HTTP_PROXY is not used.
556
+ # http_proxy is not used too if the variable is case insensitive.
557
+ # CGI_HTTP_PROXY can be used instead.
558
+ def find_proxy
559
+ name = self.scheme.downcase + '_proxy'
560
+ proxy_uri = nil
561
+ if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?
562
+ # HTTP_PROXY conflicts with *_proxy for proxy settings and
563
+ # HTTP_* for header information in CGI.
564
+ # So it should be careful to use it.
565
+ pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
566
+ case pairs.length
567
+ when 0 # no proxy setting anyway.
568
+ proxy_uri = nil
569
+ when 1
570
+ k, v = pairs.shift
571
+ if k == 'http_proxy' && ENV[k.upcase] == nil
572
+ # http_proxy is safe to use because ENV is case sensitive.
573
+ proxy_uri = ENV[name]
574
+ else
575
+ proxy_uri = nil
576
+ end
577
+ else # http_proxy is safe to use because ENV is case sensitive.
578
+ proxy_uri = ENV.to_hash[name]
579
+ end
580
+ if !proxy_uri
581
+ # Use CGI_HTTP_PROXY. cf. libwww-perl.
582
+ proxy_uri = ENV["CGI_#{name.upcase}"]
583
+ end
584
+ elsif name == 'http_proxy'
585
+ unless proxy_uri = ENV[name]
586
+ if proxy_uri = ENV[name.upcase]
587
+ warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.'
588
+ end
589
+ end
590
+ else
591
+ proxy_uri = ENV[name] || ENV[name.upcase]
592
+ end
593
+
594
+ if proxy_uri && self.host
595
+ require 'socket'
596
+ begin
597
+ addr = IPSocket.getaddress(self.host)
598
+ proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr
599
+ rescue SocketError
600
+ end
601
+ end
602
+
603
+ if proxy_uri
604
+ proxy_uri = URI.parse(proxy_uri)
605
+ name = 'no_proxy'
606
+ if no_proxy = ENV[name] || ENV[name.upcase]
607
+ no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
608
+ if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host &&
609
+ (!port || self.port == port.to_i)
610
+ proxy_uri = nil
611
+ break
612
+ end
613
+ }
614
+ end
615
+ proxy_uri
616
+ else
617
+ nil
618
+ end
619
+ end
620
+ end
621
+
622
+ class HTTP
623
+ def buffer_open(buf, proxy, options) # :nodoc:
624
+ OpenURI.open_http(buf, self, proxy, options)
625
+ end
626
+
627
+ include OpenURI::OpenRead
628
+ end
629
+
630
+ class FTP
631
+ def buffer_open(buf, proxy, options) # :nodoc:
632
+ if proxy
633
+ OpenURI.open_http(buf, self, proxy, options)
634
+ return
635
+ end
636
+ require 'net/ftp'
637
+
638
+ directories = self.path.split(%r{/}, -1)
639
+ directories.shift if directories[0] == '' # strip a field before leading slash
640
+ directories.each {|d|
641
+ d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
642
+ }
643
+ unless filename = directories.pop
644
+ raise ArgumentError, "no filename: #{self.inspect}"
645
+ end
646
+ directories.each {|d|
647
+ if /[\r\n]/ =~ d
648
+ raise ArgumentError, "invalid directory: #{d.inspect}"
649
+ end
650
+ }
651
+ if /[\r\n]/ =~ filename
652
+ raise ArgumentError, "invalid filename: #{filename.inspect}"
653
+ end
654
+ typecode = self.typecode
655
+ if typecode && /\A[aid]\z/ !~ typecode
656
+ raise ArgumentError, "invalid typecode: #{typecode.inspect}"
657
+ end
658
+
659
+ # The access sequence is defined by RFC 1738
660
+ ftp = Net::FTP.open(self.host)
661
+ # todo: extract user/passwd from .netrc.
662
+ user = 'anonymous'
663
+ passwd = nil
664
+ user, passwd = self.userinfo.split(/:/) if self.userinfo
665
+ ftp.login(user, passwd)
666
+ directories.each {|cwd|
667
+ ftp.voidcmd("CWD #{cwd}")
668
+ }
669
+ if typecode
670
+ # xxx: typecode D is not handled.
671
+ ftp.voidcmd("TYPE #{typecode.upcase}")
672
+ end
673
+ if options[:content_length_proc]
674
+ options[:content_length_proc].call(ftp.size(filename))
675
+ end
676
+ ftp.retrbinary("RETR #{filename}", 4096) { |str|
677
+ buf << str
678
+ options[:progress_proc].call(buf.size) if options[:progress_proc]
679
+ }
680
+ ftp.close
681
+ buf.io.rewind
682
+ end
683
+
684
+ include OpenURI::OpenRead
685
+ end
686
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/open-uri'
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestOpenUri < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ url = "https://assl.site.com"
10
+ file = open(url,:ssl_verify => false)
11
+ content = file.read
12
+ assert content.length > 0
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: athlite_open-uri
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Thomas Tinnesand Eng
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-08 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: hoe
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 27
30
+ segments:
31
+ - 2
32
+ - 12
33
+ version: "2.12"
34
+ type: :development
35
+ version_requirements: *id001
36
+ description: OpenURI ripped from 1.8.7's standard lib. Added option, :ssl_verify, which makes it possible to skip certificate verification.
37
+ email:
38
+ - thomas.tinnesand.eng@gmail.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - History.txt
45
+ - Manifest.txt
46
+ files:
47
+ - History.txt
48
+ - Manifest.txt
49
+ - README.rdoc
50
+ - Rakefile
51
+ - lib/open-uri.rb
52
+ - test/test_helper.rb
53
+ - test/test_open-uri.rb
54
+ - .gemtest
55
+ has_rdoc: true
56
+ homepage: http://github.com/athlite/open-uri
57
+ licenses: []
58
+
59
+ post_install_message:
60
+ rdoc_options:
61
+ - --main
62
+ - README.rdoc
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 3
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project: athlite_open-uri
86
+ rubygems_version: 1.6.2
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: OpenURI ripped from 1.8.7's standard lib
90
+ test_files:
91
+ - test/test_helper.rb
92
+ - test/test_open-uri.rb