Repository : ssh://darcs.haskell.org//srv/darcs/packages/Cabal

On branch  : master

http://hackage.haskell.org/trac/ghc/changeset/7a230b03bb557a0dbf0502d9906660aad014ed24

>---------------------------------------------------------------

commit 7a230b03bb557a0dbf0502d9906660aad014ed24
Author: Duncan Coutts <[email protected]>
Date:   Mon Jun 16 17:03:12 2008 +0000

    Try and pick up the http proxy on windows correctly
    Takes account of the ProxyEnabled reg key
    Allow proxy uris that lack the http:// uri schema.
    This should really be moved into the HTTP package.

>---------------------------------------------------------------

 cabal-install/Hackage/HttpUtils.hs |   80 +++++++++++++++++++++++++++---------
 1 files changed, 60 insertions(+), 20 deletions(-)

diff --git a/cabal-install/Hackage/HttpUtils.hs 
b/cabal-install/Hackage/HttpUtils.hs
index 1fd95c5..ed8f02e 100644
--- a/cabal-install/Hackage/HttpUtils.hs
+++ b/cabal-install/Hackage/HttpUtils.hs
@@ -4,17 +4,29 @@
 -----------------------------------------------------------------------------
 module Hackage.HttpUtils (getHTTP, proxy) where
 
-import Network.HTTP (Request (..), Response (..), RequestMethod (..), 
Header(..), HeaderName(..))
-import Network.URI (URI (..), URIAuth (..), parseURI)
+import Network.HTTP
+         ( Request (..), Response (..), RequestMethod (..)
+         , Header(..), HeaderName(..) )
+import Network.URI
+         ( URI (..), URIAuth (..), parseAbsoluteURI )
 import Network.Stream (Result)
 import Network.Browser (Proxy (..), Authority (..), browse,
                         setOutHandler, setErrHandler, setProxy, request)
-import Control.Monad (mplus)
+import Control.Monad
+         ( mplus, join )
 #ifdef WIN32
-import System.Win32.Registry (hKEY_CURRENT_USER, regOpenKey, regQueryValue, 
regCloseKey)
-import Control.Exception (try, bracket)
-#endif
+import System.Win32.Types
+         ( DWORD, HKEY )
+import System.Win32.Registry
+         ( hKEY_CURRENT_USER, regOpenKey, regCloseKey
+         , regQueryValue, regQueryValueEx )
+import Control.Exception
+         ( handle, bracket )
+import Foreign
+         ( toBool, Storable(peek, sizeOf), castPtr, alloca )
+#else
 import System.Environment (getEnvironment)
+#endif
 
 import qualified Paths_cabal_install (version)
 import Distribution.Verbosity (Verbosity)
@@ -22,13 +34,20 @@ import Distribution.Simple.Utils (warn, debug)
 import Distribution.Text
          ( display )
 
+-- FIXME: all this proxy stuff is far too complicated, especially parsing
+-- the proxy strings. Network.Browser should have a way to pick up the
+-- proxy settings hiding all this system-dependent stuff below.
+
 -- try to read the system proxy settings on windows or unix
 proxyString :: IO (Maybe String)
 #ifdef WIN32
 -- read proxy settings from the windows registry
-proxyString = fmap (either (const Nothing) Just) $ try $
-                bracket (regOpenKey hive path) regCloseKey
-                  (\hkey -> regQueryValue hkey (Just "ProxyServer"))
+proxyString = handle (\_ -> return Nothing) $
+  bracket (regOpenKey hive path) regCloseKey $ \hkey -> do
+    enable <- fmap toBool $ regQueryValueDWORD hkey "ProxyEnable"
+    if enable
+        then fmap Just $ regQueryValue hkey (Just "ProxyServer")
+        else return Nothing
   where
     -- some sources say proxy settings should be at 
     -- HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows
@@ -37,6 +56,11 @@ proxyString = fmap (either (const Nothing) Just) $ try $
     -- end up in the following place:
     hive  = hKEY_CURRENT_USER
     path = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
+
+    regQueryValueDWORD :: HKEY -> String -> IO DWORD
+    regQueryValueDWORD hkey name = alloca $ \ptr -> do
+      regQueryValueEx hkey name (castPtr ptr) (sizeOf (undefined :: DWORD))
+      peek ptr
 #else
 -- read proxy settings by looking for an env var
 proxyString = do
@@ -49,17 +73,33 @@ proxy :: Verbosity -> IO Proxy
 proxy verbosity = do
   mstr <- proxyString
   case mstr of
-    Nothing     -> return NoProxy
-    Just str    -> case parseURI str of
-      Nothing   -> do warn verbosity $ "invalid proxy uri: " ++ show str
-                      warn verbosity $ "ignoring http proxy, trying a direct 
connection"
-                      return NoProxy
-      Just uri  -> case uri2proxy uri of
-        Nothing -> do warn verbosity $ "invalid http proxy uri: " ++ show str
-                      warn verbosity $ "proxy uri must be http with a hostname"
-                      warn verbosity $ "ignoring http proxy, trying a direct 
connection"
-                      return NoProxy
-        Just p  -> return p
+    Nothing   -> return NoProxy
+    Just str  -> case parseHttpProxy str of
+      Nothing -> do
+        warn verbosity $ "invalid http proxy uri: " ++ show str
+        warn verbosity $ "proxy uri must be http with a hostname"
+        warn verbosity $ "ignoring http proxy, trying a direct connection"
+        return NoProxy
+      Just p  -> return p
+
+-- | We need to be able to parse non-URIs like @\"wwwcache.example.com:80\"@
+-- which lack the @\"http://\"@ URI scheme. The problem is that
+-- @\"wwwcache.example.com:80\"@ is in fact a valid URI but with scheme
+-- @\"wwwcache.example.com:\"@, no authority part and a path of @\"80\"@.
+--
+-- So our strategy is to try parsing as normal uri first and if it lacks the
+-- 'uriAuthority' then we try parsing again with a @\"http://\"@ prefix.
+--
+parseHttpProxy :: String -> Maybe Proxy
+parseHttpProxy str = join
+                   . fmap uri2proxy
+                   $ parseHttpURI str
+             `mplus` parseHttpURI ("http://"; ++ str)
+  where
+    parseHttpURI str' = case parseAbsoluteURI str' of
+      Just uri@URI { uriAuthority = Just _ }
+         -> Just uri
+      _  -> Nothing
 
 uri2proxy :: URI -> Maybe Proxy
 uri2proxy uri@URI{ uriScheme = "http:"



_______________________________________________
Cvs-libraries mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-libraries

Reply via email to