
C:\work\opensource\ruby\rubygems>C:\Progra~1\Subversion\bin\svn.exe di -x -b 
Index: test/test_remote_fetcher.rb
===================================================================
--- test/test_remote_fetcher.rb	(revision 1065)
+++ test/test_remote_fetcher.rb	(working copy)
@@ -26,9 +26,12 @@
     self.class.enable_zip = false
     ENV['http_proxy'] = nil
     ENV['HTTP_PROXY'] = nil
+    ENV['http_proxy_user'] = nil
+    ENV['HTTP_PROXY_USER'] = nil
+    ENV['http_proxy_pass'] = nil
+    ENV['HTTP_PROXY_PASS'] = nil
   end
 
-
   def test_no_proxy
     use_ui(MockGemUi.new) do
       fetcher = Gem::RemoteSourceFetcher.new("http://localhost:12344", nil)
@@ -63,8 +66,24 @@
       assert_equal 'bar', proxy.password
       assert_equal PROXY_DATA, fetcher.fetch_path("/yaml")
     end
+
+    use_ui(MockGemUi.new) do
+      fetcher = Gem::RemoteSourceFetcher.new("http://localhost:12344", "http://domain%5Cuser:bar@localhost:12345")
+      proxy = fetcher.instance_variable_get("@proxy_uri")
+      assert_equal 'domain\user', URI.unescape(proxy.user)
+      assert_equal 'bar', proxy.password
+      assert_equal PROXY_DATA, fetcher.fetch_path("/yaml")
   end
 
+    use_ui(MockGemUi.new) do
+      fetcher = Gem::RemoteSourceFetcher.new("http://localhost:12344", "http://user:my%20pass@localhost:12345")
+      proxy = fetcher.instance_variable_get("@proxy_uri")
+      assert_equal 'user', proxy.user
+      assert_equal 'my pass', URI.unescape(proxy.password)
+      assert_equal PROXY_DATA, fetcher.fetch_path("/yaml")
+    end
+  end
+
   def test_explicit_proxy_with_user_auth_in_env
     use_ui(MockGemUi.new) do
       ENV['http_proxy'] = 'http://localhost:12345'
@@ -76,7 +95,18 @@
       assert_equal 'bar', proxy.password
       assert_equal PROXY_DATA, fetcher.fetch_path("/yaml")
     end
+
+    use_ui(MockGemUi.new) do
+      ENV['http_proxy'] = 'http://localhost:12345'
+      ENV['http_proxy_user'] = 'foo\user'
+      ENV['http_proxy_pass'] = 'my bar'
+      fetcher = Gem::RemoteSourceFetcher.new("http://localhost:12344", nil)
+      proxy = fetcher.instance_variable_get("@proxy_uri")
+      assert_equal 'foo\user', URI.unescape(proxy.user)
+      assert_equal 'my bar', URI.unescape(proxy.password)
+      assert_equal PROXY_DATA, fetcher.fetch_path("/yaml")
   end
+  end
 
   def test_implicit_no_proxy
     use_ui(MockGemUi.new) do
Index: lib/rubygems/remote_installer.rb
===================================================================
--- lib/rubygems/remote_installer.rb	(revision 1065)
+++ lib/rubygems/remote_installer.rb	(working copy)
@@ -39,8 +39,8 @@
         uri = env_proxy ? URI.parse(env_proxy) : nil
         if uri and uri.user.nil? and uri.password.nil?
           #Probably we have http_proxy_* variables?
-          uri.user = ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER']
-          uri.password = ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS']
+          uri.user = escape(ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER'])
+          uri.password = escape(ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS'])
         end
         uri
       else
@@ -85,7 +85,16 @@
     end
 
     private
+    def escape(str)
+      return unless str
+      URI.escape(str)
+    end
 
+    def unescape(str)
+      return unless str
+      URI.unescape(str)
+    end
+
     # Normalize the URI by adding "http://" if it is missing.
     def normalize_uri(uri)
       (uri =~ /^(https?|ftp|file):/) ? uri : "http://#{uri}"
@@ -94,7 +103,7 @@
     # Connect to the source host/port, using a proxy if needed.
     def connect_to(host, port)
       if @proxy_uri
-        Net::HTTP::Proxy(@proxy_uri.host, @proxy_uri.port, @proxy_uri.user, @proxy_uri.password).new(host, port)
+        Net::HTTP::Proxy(@proxy_uri.host, @proxy_uri.port, unescape(@proxy_uri.user), unescape(@proxy_uri.password)).new(host, port)
       else
 	Net::HTTP.new(host, port)
       end
@@ -144,7 +153,7 @@
         connection_options = {"User-Agent" => "RubyGems/#{Gem::RubyGemsVersion}"}
         if @proxy_uri
           http_proxy_url = "#{@proxy_uri.scheme}://#{@proxy_uri.host}:#{@proxy_uri.port}"  
-          connection_options[:proxy_http_basic_authentication] = [http_proxy_url, @proxy_uri.user||'', @proxy_uri.password||'']
+          connection_options[:proxy_http_basic_authentication] = [http_proxy_url, unescape(@proxy_uri.user)||'', unescape(@proxy_uri.password)||'']
         end
         
         open(uri, connection_options, &block)
