hi, i am not familiear with any procedures for submitting changes to a ruby lib, so fogive me if I have not done this correctly. please email me if i need to do something differnetly. thanks.

i have made a small modification to open-uri to allow it to execute a proc in the data fetching loops. this has proved very useful to me in providing a progress reported download. (i used Ruby/ProgressBar). Note that in the future it might be nice to get open-uri to work more like a real IO.

- T. Onoma

here is the diff -u (let me know if i need to prove in different way):

--- open-uri.rb	2003-05-15 20:19:09.000000000 +0200
+++ /usr/lib/ruby/1.8/open-uri.rb	2003-11-14 09:18:36.000000000 +0100
@@ -54,6 +54,9 @@
 #
 #Author:: Tanaka Akira <akr / m17n.org>

+#ChangeLog
+#  2003-11-14 Added pogress_proc hook.  (T. Onoma <transami / runbox.com>)
+
 require 'uri'
 require 'stringio'
 require 'time'
@@ -63,7 +66,7 @@
   alias open_uri_original_open open # :nodoc:

   # makes possible to open URIs.
-  # If the first argument is URI::HTTP, URI::FTP or
+  # If the first argument is URI::HTTP, URI::FTP or
   # String beginning with http:// or ftp://,
   # the URI is opened.
   # The opened file object is extended by OpenURI::Meta.
@@ -93,6 +96,7 @@
   def OpenURI.open_uri(name, *rest) # :nodoc:
     uri = URI::Generic === name ? name : URI.parse(name)
     mode, perm, rest = OpenURI.scan_open_optional_arguments(*rest)
+    progress_proc = rest.shift if !rest.empty? && Proc === rest.first
     options = rest.shift if !rest.empty? && Hash === rest.first
     raise ArgumentError.new("extra arguments") if !rest.empty?

@@ -102,7 +106,7 @@
       raise ArgumentError.new("invalid access mode #{mode} (#{uri.class} resource is read only.)")
     end

-    io = open_loop(uri, options || {})
+    io = open_loop(uri, options || {}, progress_proc)
     if block_given?
       begin
         yield io
@@ -114,7 +118,7 @@
     end
   end

-  def OpenURI.open_loop(uri, options) # :nodoc:
+  def OpenURI.open_loop(uri, options, progress_proc=nil) # :nodoc:
     header = {}
     options.each {|k, v|
       if String === k
@@ -140,9 +144,9 @@
     begin
       buf = Buffer.new
       if proxy_uri = find_proxy.call(uri)
-        proxy_uri.proxy_open(buf, uri, header)
+        proxy_uri.proxy_open(buf, uri, header, progress_proc)
       else
-        uri.direct_open(buf, header)
+        uri.direct_open(buf, header, progress_proc)
       end
     rescue Redirect
       loc = $!.uri
@@ -353,15 +357,18 @@
   end

   class HTTP
-    def direct_open(buf, header) # :nodoc:
-      proxy_open(buf, request_uri, header)
+    def direct_open(buf, header, progress_proc) # :nodoc:
+      proxy_open(buf, request_uri, header, progress_proc)
     end

-    def proxy_open(buf, uri, header) # :nodoc:
+    def proxy_open(buf, uri, header, progress_proc=nil) # :nodoc:
       require 'net/http'
-      resp = Net::HTTP.start(self.host, self.port) {|http|
-               http.get(uri.to_s, header) {|str| buf << str}
-             }
+      resp = Net::HTTP.start(self.host, self.port) { |http|
+        http.get(uri.to_s, header) { |str|
+          buf << str
+          progress_proc.call(buf.io.pos) if progress_proc
+        }
+      }
       io = buf.io
       io.rewind
       io.status = [resp.code, resp.message]
@@ -382,9 +389,9 @@
   end

   class FTP
-    def direct_open(buf, header) # :nodoc:
+    def direct_open(buf, header, progress_proc=nil) # :nodoc:
       require 'net/ftp'
-      # xxx: header is discarded.
+      # xxx: header is discarded.
       # todo: extract user/passwd from .netrc.
       user = 'anonymous'
       passwd = nil
@@ -392,7 +399,10 @@

       ftp = Net::FTP.open(self.host)
       ftp.login(user, passwd)
-      ftp.getbinaryfile(self.path, '/dev/null', Net::FTP::DEFAULT_BLOCKSIZE) {|str| buf << str}
+      ftp.getbinaryfile(self.path, '/dev/null', Net::FTP::DEFAULT_BLOCKSIZE) { |str|
+         buf << str
+         progress_proc.call(buf.io.pos) if progress_proc
+      }
       ftp.close
       buf.io.rewind
     end