Hello community, here is the log from the commit of package ghc-HTTP for openSUSE:Factory checked in at 2013-08-06 06:51:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-HTTP (Old) and /work/SRC/openSUSE:Factory/.ghc-HTTP.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-HTTP" Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-HTTP/ghc-HTTP.changes 2013-01-10 15:28:03.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.ghc-HTTP.new/ghc-HTTP.changes 2013-08-06 06:51:14.000000000 +0200 @@ -1,0 +2,9 @@ +Tue May 7 12:02:19 UTC 2013 - [email protected] + +- update to 4000.2.8 from upstream +* fix resource leaks in getHostAddr +* correct cookie format +- part of Haskell Platform 2013.2 +- more transparent packaging (fewer macros) + +------------------------------------------------------------------- Old: ---- HTTP-4000.2.5.tar.gz New: ---- HTTP-4000.2.8.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-HTTP.spec ++++++ --- /var/tmp/diff_new_pack.6A8rC8/_old 2013-08-06 06:51:15.000000000 +0200 +++ /var/tmp/diff_new_pack.6A8rC8/_new 2013-08-06 06:51:15.000000000 +0200 @@ -1,6 +1,7 @@ # -# spec file for ghc-HTTP +# spec file for package ghc-HTTP # +# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. # Copyright (c) 2013 Peter Trommler [email protected] # # All modifications and additions to the file contributed by third parties @@ -15,6 +16,7 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # + %global pkg_name HTTP %global common_summary Haskell library for client-side HTTP @@ -22,52 +24,62 @@ %global common_description The HTTP package supports client-side web programming in Haskell. It lets you set up HTTP connections, transmitting requests and processing the responses coming back, all from within the comforts of Haskell. It is dependent on the network package to operate, but other than that, the implementation is all written in Haskell. Name: ghc-HTTP -Version: 4000.2.5 -Release: 1 +Version: 4000.2.8 +Release: 0 Summary: %{common_summary} - -Group: System/Libraries License: BSD-3-Clause +Group: System/Libraries + BuildRoot: %{_tmppath}/%{name}-%{version}-build # BEGIN cabal2spec -URL: http://hackage.haskell.org/package/%{pkg_name} +Url: http://hackage.haskell.org/package/%{pkg_name} Source0: http://hackage.haskell.org/packages/archive/%{pkg_name}/%{version}/%{pkg_name}-%{version}.tar.gz ExclusiveArch: %{ix86} x86_64 %{ghc_arches} +BuildRequires: %{!?without_hscolour:hscolour} BuildRequires: ghc-Cabal-devel -BuildRequires: ghc-rpm-macros %{!?without_hscolour:hscolour} BuildRequires: ghc-array-devel BuildRequires: ghc-mtl-devel BuildRequires: ghc-network-devel BuildRequires: ghc-old-time-devel BuildRequires: ghc-parsec-devel +BuildRequires: ghc-rpm-macros # END cabal2spec %description %{common_description} +%package devel +Summary: Haskell %{pkg_name} library development files +Group: Development/Languages/Other +Requires: ghc-compiler +Requires(post): ghc-compiler +Requires(postun): ghc-compiler +Requires: %{name} = %{version}-%{release} + +%description devel +%{common_description} +This package contains the development files. %prep %setup -q -n %{pkg_name}-%{version} - %build %ghc_lib_build - %install %ghc_lib_install +%post devel +%ghc_pkg_recache -# devel subpackage -%ghc_devel_package - -%ghc_devel_description - - -%ghc_devel_post_postun - +%postun devel +%ghc_pkg_recache -%ghc_files LICENSE +%files -f %{name}.files +%defattr(-,root,root,-) +%doc LICENSE +%files devel -f %{name}-devel.files +%defattr(-,root,root,-) %changelog ++++++ HTTP-4000.2.5.tar.gz -> HTTP-4000.2.8.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTTP-4000.2.5/HTTP.cabal new/HTTP-4000.2.8/HTTP.cabal --- old/HTTP-4000.2.5/HTTP.cabal 2012-09-16 22:16:09.000000000 +0200 +++ new/HTTP-4000.2.8/HTTP.cabal 2013-02-10 22:51:15.000000000 +0100 @@ -1,5 +1,5 @@ Name: HTTP -Version: 4000.2.5 +Version: 4000.2.8 Cabal-Version: >= 1.8 Build-type: Simple License: BSD3 @@ -85,22 +85,18 @@ Network.HTTP.Utils Paths_HTTP GHC-options: -fwarn-missing-signatures -Wall - Build-depends: base >= 2 && < 4.7, parsec + Build-depends: base >= 2 && < 4.7, network < 2.5, parsec Extensions: FlexibleInstances if flag(old-base) Build-depends: base < 3 else Build-depends: base >= 3, array, old-time, bytestring + if flag(mtl1) Build-depends: mtl >= 1.1 && < 1.2 CPP-Options: -DMTL1 else Build-depends: mtl >= 2.0 && < 2.2 - if flag(network23) - Build-depends: network < 2.4 - CPP-Options: -DNETWORK23 - else - Build-depends: network >= 2.4 && < 2.5 if flag(warn-as-error) ghc-options: -Werror @@ -111,26 +107,27 @@ Test-Suite test type: exitcode-stdio-1.0 - build-tools: ghc >= 6.10 && < 7.6 + build-tools: ghc >= 6.10 && < 7.8 hs-source-dirs: test main-is: httpTests.hs + -- note: version constraints are inherited from HTTP library stanza build-depends: HTTP, HUnit, httpd-shed, mtl >= 2.0 && < 2.2, - bytestring >= 0.9 && < 0.10, + bytestring >= 0.9 && < 0.11, case-insensitive >= 0.4 && < 0.5, deepseq >= 1.3 && < 1.4, - http-types >= 0.6 && < 0.7, - conduit >= 0.4 && < 0.5, - wai >= 1.2 && < 1.3, - warp >= 1.2 && < 1.3, + http-types >= 0.6 && < 0.8, + conduit >= 0.4 && < 0.6, + wai >= 1.2 && < 1.4, + warp >= 1.2 && < 1.4, pureMD5 >= 2.1 && < 2.2, - base >= 2 && < 4.6, - network < 2.5, - split >= 0.1 && < 0.2, + base >= 2 && < 4.7, + network, + split >= 0.1 && < 0.3, test-framework, test-framework-hunit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTTP-4000.2.5/Network/Browser.hs new/HTTP-4000.2.8/Network/Browser.hs --- old/HTTP-4000.2.5/Network/Browser.hs 2012-09-16 22:16:09.000000000 +0200 +++ new/HTTP-4000.2.8/Network/Browser.hs 2013-02-10 22:51:15.000000000 +0100 @@ -1035,10 +1035,10 @@ -- If the second argument is not sufficient context for determining -- a full URI then anarchy reins. uriDefaultTo :: URI -> URI -> URI -#ifdef NETWORK23 -uriDefaultTo a b = maybe a id (a `relativeTo` b) -#else +#if MIN_VERSION_network(2,4,0) uriDefaultTo a b = a `relativeTo` b +#else +uriDefaultTo a b = maybe a id (a `relativeTo` b) #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTTP-4000.2.5/Network/HTTP/Auth.hs new/HTTP-4000.2.8/Network/HTTP/Auth.hs --- old/HTTP-4000.2.5/Network/HTTP/Auth.hs 2012-09-16 22:16:09.000000000 +0200 +++ new/HTTP-4000.2.8/Network/HTTP/Auth.hs 2013-02-10 22:51:15.000000000 +0100 @@ -190,10 +190,10 @@ } annotateURIs :: [Maybe URI] -> [URI] -#ifdef NETWORK23 - annotateURIs = (map (\u -> fromMaybe u (u `relativeTo` baseURI))) . catMaybes -#else +#if MIN_VERSION_network(2,4,0) annotateURIs = map (`relativeTo` baseURI) . catMaybes +#else + annotateURIs = (map (\u -> fromMaybe u (u `relativeTo` baseURI))) . catMaybes #endif -- Change These: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTTP-4000.2.5/Network/HTTP/Base.hs new/HTTP-4000.2.8/Network/HTTP/Base.hs --- old/HTTP-4000.2.5/Network/HTTP/Base.hs 2012-09-16 22:16:09.000000000 +0200 +++ new/HTTP-4000.2.8/Network/HTTP/Base.hs 2013-02-10 22:51:15.000000000 +0100 @@ -108,8 +108,10 @@ import Control.Monad ( guard ) import Control.Monad.Error () +import Data.Bits ( (.&.), (.|.), shiftL, shiftR ) +import Data.Word ( Word8 ) import Data.Char ( digitToInt, intToDigit, toLower, isDigit, - isAscii, isAlphaNum ) + isAscii, isAlphaNum, ord, chr ) import Data.List ( partition, find ) import Data.Maybe ( listToMaybe, fromMaybe ) import Numeric ( readHex ) @@ -590,33 +592,102 @@ Escape method: char -> '%' a b where a, b :: Hex digits -} +replacement_character :: Char +replacement_character = '\xfffd' + +-- | Encode a single Haskell Char to a list of Word8 values, in UTF8 format. +-- +-- Shamelessly stolen from utf-8string-0.3.7 +encodeChar :: Char -> [Word8] +encodeChar = map fromIntegral . go . ord + where + go oc + | oc <= 0x7f = [oc] + + | oc <= 0x7ff = [ 0xc0 + (oc `shiftR` 6) + , 0x80 + oc .&. 0x3f + ] + + | oc <= 0xffff = [ 0xe0 + (oc `shiftR` 12) + , 0x80 + ((oc `shiftR` 6) .&. 0x3f) + , 0x80 + oc .&. 0x3f + ] + | otherwise = [ 0xf0 + (oc `shiftR` 18) + , 0x80 + ((oc `shiftR` 12) .&. 0x3f) + , 0x80 + ((oc `shiftR` 6) .&. 0x3f) + , 0x80 + oc .&. 0x3f + ] + +-- | Decode a UTF8 string packed into a list of Word8 values, directly to String +-- +-- Shamelessly stolen from utf-8string-0.3.7 +decode :: [Word8] -> String +decode [ ] = "" +decode (c:cs) + | c < 0x80 = chr (fromEnum c) : decode cs + | c < 0xc0 = replacement_character : decode cs + | c < 0xe0 = multi1 + | c < 0xf0 = multi_byte 2 0xf 0x800 + | c < 0xf8 = multi_byte 3 0x7 0x10000 + | c < 0xfc = multi_byte 4 0x3 0x200000 + | c < 0xfe = multi_byte 5 0x1 0x4000000 + | otherwise = replacement_character : decode cs + where + multi1 = case cs of + c1 : ds | c1 .&. 0xc0 == 0x80 -> + let d = ((fromEnum c .&. 0x1f) `shiftL` 6) .|. fromEnum (c1 .&. 0x3f) + in if d >= 0x000080 then toEnum d : decode ds + else replacement_character : decode ds + _ -> replacement_character : decode cs + + multi_byte :: Int -> Word8 -> Int -> [Char] + multi_byte i mask overlong = aux i cs (fromEnum (c .&. mask)) + where + aux 0 rs acc + | overlong <= acc && acc <= 0x10ffff && + (acc < 0xd800 || 0xdfff < acc) && + (acc < 0xfffe || 0xffff < acc) = chr acc : decode rs + | otherwise = replacement_character : decode rs + + aux n (r:rs) acc + | r .&. 0xc0 == 0x80 = aux (n-1) rs + $ shiftL acc 6 .|. fromEnum (r .&. 0x3f) + + aux _ rs _ = replacement_character : decode rs + + +-- This function is a bit funny because potentially the input String could contain some actual Unicode +-- characters (though this shouldn't happen for most use cases), so we have to preserve those characters +-- while simultaneously decoding any UTF-8 data urlDecode :: String -> String -urlDecode ('%':a:b:rest) = toEnum (16 * digitToInt a + digitToInt b) - : urlDecode rest -urlDecode (h:t) = h : urlDecode t -urlDecode [] = [] +urlDecode = go [] + where + go bs ('%':a:b:rest) = go (fromIntegral (16 * digitToInt a + digitToInt b) : bs) rest + go bs (h:t) | fromEnum h < 256 = go (fromIntegral (fromEnum h) : bs) t -- Treat ASCII as just another byte of UTF-8 + go [] [] = [] + go [] (h:t) = h : go [] t -- h >= 256, so can't be part of any UTF-8 byte sequence + go bs rest = decode (reverse bs) ++ go [] rest urlEncode :: String -> String urlEncode [] = [] urlEncode (ch:t) | (isAscii ch && isAlphaNum ch) || ch `elem` "-_.~" = ch : urlEncode t - | not (isAscii ch) = foldr escape (urlEncode t) (eightBs [] (fromEnum ch)) - | otherwise = escape (fromEnum ch) (urlEncode t) + | not (isAscii ch) = foldr escape (urlEncode t) (encodeChar ch) + | otherwise = escape (fromIntegral (fromEnum ch)) (urlEncode t) where escape b rs = '%':showH (b `div` 16) (showH (b `mod` 16) rs) - + + showH :: Word8 -> String -> String showH x xs - | x <= 9 = toEnum (o_0 + x) : xs - | otherwise = toEnum (o_A + (x-10)) : xs + | x <= 9 = to (o_0 + x) : xs + | otherwise = to (o_A + (x-10)) : xs where - o_0 = fromEnum '0' - o_A = fromEnum 'A' + to = toEnum . fromIntegral + fro = fromIntegral . fromEnum - eightBs :: [Int] -> Int -> [Int] - eightBs acc x - | x <= 0xff = (x:acc) - | otherwise = eightBs ((x `mod` 256) : acc) (x `div` 256) + o_0 = fro '0' + o_A = fro 'A' -- Encode form variables, useable in either the -- query part of a URI, or the body of a POST request. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTTP-4000.2.5/test/httpTests.hs new/HTTP-4000.2.8/test/httpTests.hs --- old/HTTP-4000.2.5/test/httpTests.hs 2012-09-16 22:16:09.000000000 +0200 +++ new/HTTP-4000.2.8/test/httpTests.hs 2013-02-10 22:51:15.000000000 +0100 @@ -103,6 +103,19 @@ body <- getResponseBody response assertEqual "Receiving expected response" ((2, 0, 0), "Here's the secret") (code, body) +utf8URLEncode :: Assertion +utf8URLEncode = do + assertEqual "Normal URL" (urlEncode "what-a_mess.com") "what-a_mess.com" + assertEqual "Chinese URL" (urlEncode "好") "%E5%A5%BD" + assertEqual "Russian URL" (urlEncode "ололо") "%D0%BE%D0%BB%D0%BE%D0%BB%D0%BE" + +utf8URLDecode :: Assertion +utf8URLDecode = do + assertEqual "Normal URL" (urlDecode "what-a_mess.com") "what-a_mess.com" + assertEqual "Mixed URL" (urlDecode "UTFin进入-wow") "UTFin进入-wow" + assertEqual "Chinese URL" (urlDecode "%E5%A5%BD") "好" + assertEqual "Russian URL" (urlDecode "%D0%BE%D0%BB%D0%BE%D0%BB%D0%BE") "ололо" + browserExample :: (?testUrl :: ServerAddress) => Assertion browserExample = do result <- @@ -513,6 +526,8 @@ , testCase "Basic HEAD request" basicHeadRequest , testCase "Basic Auth failure" basicAuthFailure , testCase "Basic Auth success" basicAuthSuccess + , testCase "UTF-8 urlEncode" utf8URLEncode + , testCase "UTF-8 urlDecode" utf8URLDecode ] browserTests = -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
