Hello community,

here is the log from the commit of package ghc-http-client for openSUSE:Factory 
checked in at 2015-07-08 06:59:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-http-client (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-http-client.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-http-client"

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-http-client/ghc-http-client.changes  
2015-06-23 11:59:28.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.ghc-http-client.new/ghc-http-client.changes     
2015-07-08 06:59:49.000000000 +0200
@@ -1,0 +2,8 @@
+Mon Jul  6 12:25:51 UTC 2015 - [email protected]
+
+- update to 0.4.15
+* Support proxy authentication in environment variables
+* Ignore empty http_proxy
+* Support for auth via url
+
+-------------------------------------------------------------------

Old:
----
  http-client-0.4.12.tar.gz

New:
----
  http-client-0.4.15.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-http-client.spec ++++++
--- /var/tmp/diff_new_pack.LGOsfx/_old  2015-07-08 06:59:50.000000000 +0200
+++ /var/tmp/diff_new_pack.LGOsfx/_new  2015-07-08 06:59:50.000000000 +0200
@@ -21,7 +21,7 @@
 %bcond_with tests
 
 Name:           ghc-http-client
-Version:        0.4.12
+Version:        0.4.15
 Release:        0
 Summary:        HTTP client engine, intended as a base layer 
 License:        MIT

++++++ http-client-0.4.12.tar.gz -> http-client-0.4.15.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/http-client-0.4.12/ChangeLog.md 
new/http-client-0.4.15/ChangeLog.md
--- old/http-client-0.4.12/ChangeLog.md 2015-06-17 21:28:00.000000000 +0200
+++ new/http-client-0.4.15/ChangeLog.md 2015-07-02 17:35:06.000000000 +0200
@@ -1,3 +1,15 @@
+## 0.4.15
+
+* Support proxy authentication in environment variables 
[#129](https://github.com/snoyberg/http-client/issues/129)
+
+## 0.4.14
+
+* Ignore empty `http_proxy` 
[#128](https://github.com/snoyberg/http-client/pull/128)
+
+## 0.4.13
+
+* Support for auth via url 
[#124](https://github.com/snoyberg/http-client/pull/124)
+
 ## 0.4.12
 
 * Added `IsString RequestBody` instance 
[#126](https://github.com/snoyberg/http-client/pull/126)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/http-client-0.4.12/Network/HTTP/Client/Manager.hs 
new/http-client-0.4.15/Network/HTTP/Client/Manager.hs
--- old/http-client-0.4.12/Network/HTTP/Client/Manager.hs       2015-06-17 
21:28:00.000000000 +0200
+++ new/http-client-0.4.15/Network/HTTP/Client/Manager.hs       2015-07-02 
17:35:06.000000000 +0200
@@ -54,6 +54,7 @@
 import Network.HTTP.Client.Types
 import Network.HTTP.Client.Connection
 import Network.HTTP.Client.Headers (parseStatusHeaders)
+import Network.HTTP.Client.Request (username, password, applyBasicProxyAuth)
 import Control.Concurrent.MVar (MVar, takeMVar, tryPutMVar, newEmptyMVar)
 import System.Environment (getEnvironment)
 import qualified Network.URI as U
@@ -486,14 +487,11 @@
 envHelper name eh = do
     env <- getEnvironment
     case lookup (T.unpack name) env of
-        Nothing -> return $
-            case eh of
-                EHFromRequest -> id
-                EHNoProxy     -> \req -> req { proxy = Nothing }
-                EHUseProxy p  -> \req -> req { proxy = Just p  }
+        Nothing  -> return noEnvProxy
+        Just ""  -> return noEnvProxy
         Just str -> do
             let invalid = throwIO $ InvalidProxyEnvironmentVariable name 
(T.pack str)
-            p <- maybe invalid return $ do
+            (p, muserpass) <- maybe invalid return $ do
                 uri <- case U.parseURI str of
                     Just u | U.uriScheme u == "http:" -> return u
                     _ -> U.parseURI $ "http://"; ++ str
@@ -504,7 +502,13 @@
                 guard $ null $ U.uriFragment uri
 
                 auth <- U.uriAuthority uri
-                guard $ null $ U.uriUserInfo auth
+                let muserpass =
+                        if null authInfo
+                            then Nothing
+                            else Just ( S8.pack $ username authInfo
+                                      , S8.pack $ password authInfo
+                                      )
+                    authInfo = U.uriUserInfo auth
 
                 port <-
                     case U.uriPort auth of
@@ -515,5 +519,11 @@
                                 _ -> Nothing
                         _ -> Nothing
 
-                Just $ Proxy (S8.pack $ U.uriRegName auth) port
-            return $ \req -> req { proxy = Just p }
+                Just $ (Proxy (S8.pack $ U.uriRegName auth) port, muserpass)
+            return $ \req ->
+                maybe id (uncurry applyBasicProxyAuth) muserpass
+                req { proxy = Just p }
+    where noEnvProxy = case eh of
+            EHFromRequest -> id
+            EHNoProxy     -> \req -> req { proxy = Nothing }
+            EHUseProxy p  -> \req -> req { proxy = Just p  }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/http-client-0.4.12/Network/HTTP/Client/Request.hs 
new/http-client-0.4.15/Network/HTTP/Client/Request.hs
--- old/http-client-0.4.12/Network/HTTP/Client/Request.hs       2015-06-17 
21:28:00.000000000 +0200
+++ new/http-client-0.4.15/Network/HTTP/Client/Request.hs       2015-07-02 
17:35:06.000000000 +0200
@@ -23,6 +23,8 @@
     , setQueryString
     , streamFile
     , observedStreamFile
+    , username
+    , password
     ) where
 
 import Data.Int (Int64)
@@ -45,7 +47,7 @@
 import Data.ByteString.Lazy.Internal (defaultChunkSize)
 
 import qualified Network.HTTP.Types as W
-import Network.URI (URI (..), URIAuth (..), parseURI, relativeTo, 
escapeURIString, isAllowedInURI)
+import Network.URI (URI (..), URIAuth (..), parseURI, relativeTo, 
escapeURIString, isAllowedInURI, isReserved)
 
 import Control.Monad.IO.Class (liftIO)
 import Control.Exception (Exception, toException, throw, throwIO, IOException)
@@ -114,16 +116,37 @@
     , uriFragment = ""
     }
 
+applyAnyUriBasedAuth :: URI -> Request -> Request
+applyAnyUriBasedAuth uri req =
+    if hasAuth
+      then applyBasicAuth (S8.pack theuser) (S8.pack thepass) req
+      else req
+  where
+    hasAuth = (notEmpty theuser) && (notEmpty thepass)
+    notEmpty = not . null
+    theuser = username authInfo
+    thepass = password authInfo
+    authInfo = maybe "" uriUserInfo $ uriAuthority uri
+
+username :: String -> String
+username = encode . takeWhile (/=':') . authPrefix
+
+password :: String -> String
+password = encode . takeWhile (/='@') . drop 1 . dropWhile (/=':')
+
+encode :: String -> String
+encode = escapeURIString (not . isReserved)
+
+authPrefix :: String -> String
+authPrefix u = if '@' `elem` u then takeWhile (/= '@') u else ""
+
 -- | Validate a 'URI', then add it to the request.
 setUri :: MonadThrow m => Request -> URI -> m Request
 setUri req uri = do
     sec <- parseScheme uri
     auth <- maybe (failUri "URL must be absolute") return $ uriAuthority uri
-    if not . null $ uriUserInfo auth
-        then failUri "URL auth not supported; use applyBasicAuth instead"
-        else return ()
     port' <- parsePort sec auth
-    return req
+    return $ applyAnyUriBasedAuth uri req
         { host = S8.pack $ uriRegName auth
         , port = port'
         , secure = sec
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/http-client-0.4.12/http-client.cabal 
new/http-client-0.4.15/http-client.cabal
--- old/http-client-0.4.12/http-client.cabal    2015-06-17 21:28:00.000000000 
+0200
+++ new/http-client-0.4.15/http-client.cabal    2015-07-02 17:35:06.000000000 
+0200
@@ -1,5 +1,5 @@
 name:                http-client
-version:             0.4.12
+version:             0.4.15
 synopsis:            An HTTP client engine, intended as a base layer for more 
user-friendly packages.
 description:         Hackage documentation generation is not reliable. For up 
to date documentation, please see: 
<http://www.stackage.org/package/http-client>.
 homepage:            https://github.com/snoyberg/http-client
@@ -109,6 +109,7 @@
                      , blaze-builder
                      , time
                      , network
+                     , network-uri
                      , containers
                      , transformers
                      , deepseq
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/http-client-0.4.12/test-nonet/Network/HTTP/Client/RequestSpec.hs 
new/http-client-0.4.15/test-nonet/Network/HTTP/Client/RequestSpec.hs
--- old/http-client-0.4.12/test-nonet/Network/HTTP/Client/RequestSpec.hs        
2015-06-17 21:28:00.000000000 +0200
+++ new/http-client-0.4.15/test-nonet/Network/HTTP/Client/RequestSpec.hs        
2015-07-02 17:35:06.000000000 +0200
@@ -5,9 +5,10 @@
 import Control.Applicative ((<$>))
 import Control.Monad (join, forM_)
 import Data.IORef
-import Data.Maybe (isJust, fromMaybe)
+import Data.Maybe (isJust, fromMaybe, fromJust)
 import Network.HTTP.Client (parseUrl, requestHeaders, applyBasicProxyAuth)
 import Network.HTTP.Client.Internal
+import Network.URI (URI(..), URIAuth(..)) --(parseURI, relativeTo, 
escapeURIString, isAllowedInURI)
 import Test.Hspec
 
 spec :: Spec
@@ -22,6 +23,20 @@
                 Nothing -> return () :: IO ()
                 Just req -> error $ show req
 
+    describe "authentication in url" $ do
+      it "passes validation" $ do
+        case parseUrl "http://agent:[email protected]"; of
+          Nothing -> error "failed"
+          Just _ -> return () :: IO ()
+
+      it "add username/password to headers section" $ do
+        let request = parseUrl "http://user:[email protected]";
+            field = join $ lookup "Authorization" . requestHeaders <$> request
+            requestHostnameWithoutAuth = "example.com"
+        (uriRegName $ fromJust $ uriAuthority $ getUri $ fromJust request) 
`shouldBe` requestHostnameWithoutAuth
+        field `shouldSatisfy` isJust
+        field `shouldBe` Just "Basic dXNlcjpwYXNz"
+
     describe "applyBasicProxyAuth" $ do
         let request = applyBasicProxyAuth "user" "pass" <$> parseUrl 
"http://example.org";
             field   = join $ lookup "Proxy-Authorization" . requestHeaders <$> 
request
@@ -30,6 +45,26 @@
         it "Should add a proxy-authorization header with the specified 
username and password." $ do
             field `shouldBe` Just "Basic dXNlcjpwYXNz"
 
+    describe "extract credentials from a URI" $ do
+        it "fetches non-empty username before the first ':'" $ do
+            username "agent:[email protected]" `shouldBe` "agent"
+
+        it "extra colons do not delimit username" $ do
+            username "agent:006:[email protected]" `shouldBe` "agent"
+
+        it "after ':' is considered password" $ do
+            password "agent007:[email protected]" `shouldBe` 
"shakenNotStirred"
+
+        it "encodes username special characters per RFC3986" $ do
+            username "/?#[]!$&'()*+,;=:[email protected]" `shouldBe` 
"%2F%3F%23%5B%5D%21%24%26%27%28%29%2A%2B%2C%3B%3D"
+
+        it "encodes password special characters per RFC3986" $ do
+            password "therealusername:?#[]!$&'()*+,;=/@example.com" `shouldBe` 
"%3F%23%5B%5D%21%24%26%27%28%29%2A%2B%2C%3B%3D%2F"
+
+        it "no auth is empty" $ do
+            username "example.com" `shouldBe` ""
+            password "example.com" `shouldBe` ""
+
     describe "requestBuilder" $ do
         it "sends the full request, combining headers and body in the 
non-streaming case" $ do
             let Just req  = parseUrl "http://localhost";
@@ -83,3 +118,4 @@
                 case xs of
                     (x:xs') -> (xs', x)
                     [] -> ([], "")
+ 


Reply via email to