OK. Here is patch that contains proxy authorization changes.

But as for me I would just copy open-uri.rb from trunk to 1.8.5 branch,
because of 2 reasons
1) version from trunk is tested much better (we've used it in rubygems-0.9.2
)
2) It does not contained any API changes. Trunk version fixes 2 bugs: with
proxy authorization and with SSL.

Anyway if copying is not possible (but I am still voting for it) I would
like that anyone from you try to test this patch. Just apply patch to your
current open-uri.rb file and remove open-uri lib from rubygems.

I've just tested it. WinXP ruby 1.8.4, rubygems 0.9.2. Works fine.

On 2/15/07, Anatol Pomozov <[EMAIL PROTECTED]> wrote:

Hi, Eric.

Just to clarify. We need to port proxy authorization feature that fixes
our problem from

http://svn.ruby-lang.org/repos/ruby/trunk
to
http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8_5

Am I right?

On 2/14/07, Eric Hodel < [EMAIL PROTECTED] > wrote:
>
> On Feb 12, 2007, at 17:34, Eric Hodel wrote:
> > On Feb 12, 2007, at 15:57, Eric Hodel wrote:
> >
> >> In order to fix proxy with password, rubygems/open-uri.rb was re-
> >> added.
> >>
> >> Requiring both rubygems.rb and open-uri.rb causes inifinite loops
> >> (#open calls itself since it is aliased twice).
> >>
> >> The correct way to fix this is not to continually re-import open-
> >> uri.rb, but to get changes back-ported from 1.9 to 1.8.  There's a
> >> realease coming RSN (freeze in days!).  Can somebody spearhead this?
> >> I don't know enough about proxies to make sure the right change is
> >> made to the 1.8 branch.
> >
> > Note that I really need someone to figure out what the right patch
> > from 1.9 to 1.8 is, and post it to ruby-core.  I can help push this
> > through for 1.8.6.
>
> Really, it would be great if I could get this patched correctly on
> 1.8.6 (and add a workaround for 1.8.5 for the next release of
> RubyGems).  Breaking open-uri this way is uncool :/


Index: lib/open-uri.rb
===================================================================
--- lib/open-uri.rb (revision 11758)
+++ lib/open-uri.rb (working copy)
@@ -91,6 +91,7 @@
 module OpenURI
   Options = {
     :proxy => true,
+    :proxy_http_basic_authentication => true,
     :progress_proc => true,
     :content_length_proc => true,
     :http_basic_authentication => true,
@@ -142,16 +143,40 @@
   end
 
   def OpenURI.open_loop(uri, options) # :nodoc:
-    case opt_proxy = options.fetch(:proxy, true)
+    proxy_opts = []
+    proxy_opts << :proxy_http_basic_authentication if options.include? :proxy_http_basic_authentication
+    proxy_opts << :proxy if options.include? :proxy
+    proxy_opts.compact!
+    if 1 < proxy_opts.length
+      raise ArgumentError, "multiple proxy options specified"
+    end
+    case proxy_opts.first
+    when :proxy_http_basic_authentication
+      opt_proxy, proxy_user, proxy_pass = options.fetch(:proxy_http_basic_authentication)
+      proxy_user = proxy_user.to_str
+      proxy_pass = proxy_pass.to_str
+      if opt_proxy == true
+        raise ArgumentError.new("Invalid authenticated proxy option: #{options[:proxy_http_basic_authentication].inspect}")
+      end
+    when :proxy
+      opt_proxy = options.fetch(:proxy)
+      proxy_user = nil
+      proxy_pass = nil
+    when nil
+      opt_proxy = true
+      proxy_user = nil
+      proxy_pass = nil
+    end
+    case opt_proxy
     when true
-      find_proxy = lambda {|u| u.find_proxy}
+      find_proxy = lambda {|u| pxy = u.find_proxy; pxy ? [pxy, nil, nil] : nil}
     when nil, false
       find_proxy = lambda {|u| nil}
     when String
       opt_proxy = URI.parse(opt_proxy)
-      find_proxy = lambda {|u| opt_proxy}
+      find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
     when URI::Generic
-      find_proxy = lambda {|u| opt_proxy}
+      find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
     else
       raise ArgumentError.new("Invalid proxy option: #{opt_proxy}")
     end
@@ -200,7 +225,8 @@
 
   def OpenURI.open_http(buf, target, proxy, options) # :nodoc:
     if proxy
-      raise "Non-HTTP proxy URI: #{proxy}" if proxy.class != URI::HTTP
+      proxy_uri, proxy_user, proxy_pass = proxy
+      raise "Non-HTTP proxy URI: #{proxy_uri}" if proxy_uri.class != URI::HTTP
     end
 
     if target.userinfo && "1.9.0" <= RUBY_VERSION
@@ -213,16 +239,23 @@
     if URI::HTTP === target
       # HTTP or HTTPS
       if proxy
-        klass = Net::HTTP::Proxy(proxy.host, proxy.port)
+        if proxy_user && proxy_pass
+          klass = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_user, proxy_pass)
+        else
+          klass = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port)
+        end
       end
       target_host = target.host
       target_port = target.port
       request_uri = target.request_uri
     else
       # FTP over HTTP proxy
-      target_host = proxy.host
-      target_port = proxy.port
+      target_host = proxy_uri.host
+      target_port = proxy_uri.port
       request_uri = target.to_s
+      if proxy_user && proxy_pass
+        header["Proxy-Authorization"] = 'Basic ' + ["#{proxy_user}:#{proxy_pass}"].pack('m').delete("\r\n")
+      end
     end
 
     http = klass.new(target_host, target_port)
@@ -470,6 +503,21 @@
     #  When false or nil is given, the environment variables are ignored and
     #  connection will be made to a server directly.
     #
+    # [:proxy_http_basic_authentication]
+    #  Synopsis:
+    #    :proxy_http_basic_authentication => ["http://proxy.foo.com:8000/";, "proxy-user", "proxy-password"]
+    #    :proxy_http_basic_authentication => [URI.parse("http://proxy.foo.com:8000/";), "proxy-user", "proxy-password"]
+    #   
+    #  If :proxy option is specified, the value should be an Array with 3 elements.
+    #  It should contain a proxy URI, a proxy user name and a proxy password.
+    #  The proxy URI should be a String, an URI or nil.
+    #  The proxy user name and password should be a String.
+    #
+    #  If nil is given for the proxy URI, this option is just ignored.
+    #
+    #  If :proxy and :proxy_http_basic_authentication is specified, 
+    #  ArgumentError is raised.
+    #
     # [:http_basic_authentication]
     #  Synopsis:
     #    :http_basic_authentication=>[user, password]
_______________________________________________
Rubygems-developers mailing list
Rubygems-developers@rubyforge.org
http://rubyforge.org/mailman/listinfo/rubygems-developers

Reply via email to