packages feed

curlhs 0.1.5 → 0.1.6

raw patch · 17 files changed

+252/−211 lines, 17 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Network.CURL720: CURLOPT_HEADERFUNCTION :: (Maybe CURL_header_callback) -> CURLoption
+ Network.CURL720: CURL_HEADERFUNC_FAIL :: CURL_header_response
+ Network.CURL720: CURL_HEADERFUNC_OK :: CURL_header_response
+ Network.CURL720: data CURL_header_response
+ Network.CURL720: type CURL_header_callback = ByteString -> IO CURL_header_response
+ Network.CURL730: CURLOPT_HEADERFUNCTION :: (Maybe CURL_header_callback) -> CURLoption
+ Network.CURL730: CURL_HEADERFUNC_FAIL :: CURL_header_response
+ Network.CURL730: CURL_HEADERFUNC_OK :: CURL_header_response
+ Network.CURL730: data CURL_header_response
+ Network.CURL730: type CURL_header_callback = ByteString -> IO CURL_header_response

Files

+ CHANGELOG.md view
@@ -0,0 +1,91 @@+# Change Log (curlhs)+++## [Release 0.1.6][0.1.6] 2015-05-20++### Added+- Support for `CURLOPT_HEADERFUNCTION` added ([Issue #5]).+- Change log added.++### Changed+- Requirement to explicit use of `loadlib`/`freelib` removed.+The process of loading and initializing *libcurl* is automatically+performed when *curlhs* is loaded/linked, and the process of cleanup+and unloading is performed when *curlhs* is unloaded/unlinked.+Indirectly inspired by the discussion on [Issue #3].++- Tests, examples and documentation updated accordingly.++### Deprecated+- Module `Network.CURL000` and its contents (`loadlib`/`freelib` etc.)+will be removed in the future versions.++### Fixed+- Fixed bug which caused segfaults when more than one *callback type*+or *slist type* option was used on the same handle.++++## [Release 0.1.5][0.1.5] 2015-04-27++### Fixed+- Tests updated for newer `hspec` package version ([Issue #4]).++++## [Release 0.1.4][0.1.4] 2015-04-23++### Fixed+- Building errors on OS X platform fixed ([Issue #2]).+- Large negative literals warning fixed.+- GHC 7.10 warnings fixed.++++## [Release 0.1.3][0.1.3] 2014-10-03++### Fixed+- Documentation links fixed.++++## [Release 0.1.2][0.1.2] 2014-10-02++### Added+- Documentation browser added (simple markdown viewer).+- Short tutorial and few simple examples added.+- Basic test suite added.++### Changed+- `CURLOPT_SSL_VERIFYHOST` option type changed to `Bool`.++++## [Release 0.1.1][0.1.1] 2014-08-14++### Fixed+- Version boundaries for `base` package added.++++## [Release 0.1.0][0.1.0] 2014-08-14++- Almost complete rewrite. All before is a dark history.+++++[HEAD]:  https://github.com/kkardzis/curlhs/compare/curlhs-0.1.6...HEAD+[0.1.6]: https://github.com/kkardzis/curlhs/compare/curlhs-0.1.5...curlhs-0.1.6+[0.1.5]: https://github.com/kkardzis/curlhs/compare/curlhs-0.1.4...curlhs-0.1.5+[0.1.4]: https://github.com/kkardzis/curlhs/compare/curlhs-0.1.3...curlhs-0.1.4+[0.1.3]: https://github.com/kkardzis/curlhs/compare/curlhs-0.1.2...curlhs-0.1.3+[0.1.2]: https://github.com/kkardzis/curlhs/compare/curlhs-0.1.1...curlhs-0.1.2+[0.1.1]: https://github.com/kkardzis/curlhs/compare/curlhs-0.1.0...curlhs-0.1.1+[0.1.0]: https://github.com/kkardzis/curlhs/compare/curlhs-0.0.2...curlhs-0.1.0++[Issue #2]: https://github.com/kkardzis/curlhs/issues/2+[Issue #3]: https://github.com/kkardzis/curlhs/issues/3+[Issue #4]: https://github.com/kkardzis/curlhs/issues/4+[Issue #5]: https://github.com/kkardzis/curlhs/issues/5+
Network/CURL000/LibC0.c view
@@ -22,6 +22,7 @@  #define CURLXXX CURL730 #define SYMTAB curlSYMTAB+#define ADRTAB curlADRTAB  SYMTABENTRY curlSYMTAB[] =   { {CURL720, CURLXXX, "curl_easy_cleanup"}@@ -132,4 +133,79 @@       printf("   %s -> %lu\n", x, vs[i++]);           \     };                                                \   };                                                  \++++/* ------------------------------------------------------------------------- */+/* ######################################################################### */+/* ------------------------------------------------------------------------- */+#ifndef hsc_const++/* ------------------------------------------------------------------------- */+#if defined(OSXRTLD) || defined(UNIRTLD)++#include <dlfcn.h>+#define DYNLOAD(lib) dlopen(lib,RTLD_LAZY)+#define DYNFREE(lib) dlclose(lib)+#define DYNFUNC(h,n) dlsym(h,n)++static void dyninit(void) __attribute__((constructor));+static void dynfini(void) __attribute__((destructor));++#elif defined(WINRTLD)++#include <windows.h>+#define DYNLOAD(lib) LoadLibrary(lib)+#define DYNFREE(lib) FreeLibrary(lib)+#define DYNFUNC(h,f) GetProcAddress(h,f)++static void dyninit(void) __attribute__((constructor));++#else++#error "Platform not Supported"++#define DYNLOAD(lib) NULL+#define DYNFREE(lib) NULL+#define DYNFUNC(h,f) NULL++#endif /* RTLD */+++/* ------------------------------------------------------------------------- */+static void *dynlib = NULL;++static void dyninit(void) {+#if defined(SONAME0) && defined(SONAME)+  if ((dynlib = DYNLOAD(SONAME0)) || (dynlib = DYNLOAD(SONAME))) {+#elif defined(SONAME)+  if (dynlib = DYNLOAD(SONAME)) {+#else+  if (0) {+#endif+    typedef CURLcode (*INIT)(long flags);+    typedef curl_version_info_data *(*VTAG)(CURLversion type);+    INIT init = (INIT) DYNFUNC(dynlib, "curl_global_init");+    VTAG vtag = (VTAG) DYNFUNC(dynlib, "curl_version_info");+    if (vtag && init && !(init(CURL_GLOBAL_ALL))) {+      curl_version_info_data *dt = vtag(CURLVERSION_FIRST);+      if ((dt->version_num >= 0x071400) && (dt->version_num < 0x080000)) {+        int i; for (i=0; i<TABLEN; i++) {+          ADRTAB[i] = DYNFUNC(dynlib, SYMTAB[i].name);+        }+      }+    }+  }+}++static void dynfini(void) {+  if (dynlib) {+    typedef void (*EXIT)(void);+    EXIT exit = (EXIT) DYNFUNC(dynlib, "curl_global_cleanup");+    if (exit) { exit(); };+    DYNFREE(dynlib);+  }+}++#endif /* hsc_const */ 
Network/CURL000/LibCC.hsc view
@@ -81,8 +81,9 @@   , curl_version   , curl_version_info -  , CURL_write_callback, wrapCURL_write_callback-  , CURL_read_callback , wrapCURL_read_callback+  , CURL_write_callback , wrapCURL_write_callback+  , CURL_read_callback  , wrapCURL_read_callback+  , CURL_header_callback, wrapCURL_header_callback    , CURL_lock_function  , wrapCURL_lock_function   , CURL_unlock_function, wrapCURL_unlock_function@@ -439,8 +440,9 @@ ------------------------------------------------------------------------------- -- Callbacks --------------------------------------------------------------------------------#{WRAP CURL_write_callback, Ptr CChar -> CSize -> CSize -> Ptr () -> IO CSize}-#{WRAP CURL_read_callback , Ptr CChar -> CSize -> CSize -> Ptr () -> IO CSize}+#{WRAP CURL_write_callback , Ptr CChar -> CSize -> CSize -> Ptr () -> IO CSize}+#{WRAP CURL_read_callback  , Ptr CChar -> CSize -> CSize -> Ptr () -> IO CSize}+#{WRAP CURL_header_callback, Ptr CChar -> CSize -> CSize -> Ptr () -> IO CSize}   #{WRAP CURL_lock_function                                          \
Network/CURL000/LibHS.hsc view
@@ -371,8 +371,9 @@   #define hsc_setopt(opt, foo) printf(#opt " x -> " #foo " ccurl %d x", opt)    ---- CALLBACK OPTIONS --------------------------------------------------------  #{setopt CURLOPT_WRITEFUNCTION          , curlcb FWRITE}-  #{setopt CURLOPT_READFUNCTION           , curlcb FREAD }+  #{setopt CURLOPT_WRITEFUNCTION          , curlcb FWRITE }+  #{setopt CURLOPT_READFUNCTION           , curlcb FREAD  }+  #{setopt CURLOPT_HEADERFUNCTION         , curlcb FHEADER}    ---- BEHAVIOR OPTIONS -------------------------------------------------------   #{setopt CURLOPT_VERBOSE                , bool     }@@ -614,7 +615,7 @@ makeSL :: IORef [CURLSL] -> Ptr C.CURL -> CInt -> [String] -> IO CInt makeSL slref ccurl copt xs =   let cons sl (tokeep, tofree) = ((copt,sl):tokeep, tofree)-      keep 0 sl sls = cons sl $ partition ((==copt) . fst) sls+      keep 0 sl sls = cons sl $ partition ((/=copt) . fst) sls       keep _ sl sls = cons sl $ (sls,[])   in  wrapSL xs >>= \msl -> case msl of         Nothing -> return #{const CURLE_OUT_OF_MEMORY}@@ -627,8 +628,9 @@ ------------------------------------------------------------------------------- wrapCB :: CURLCBT a -> a -> IO (FunPtr ()) wrapCB cbt = case cbt of-  FWRITE -> fmap castFunPtr . C.wrapCURL_write_callback . write_callback-  FREAD  -> fmap castFunPtr . C.wrapCURL_read_callback  . read_callback+  FWRITE  -> fmap castFunPtr . C.wrapCURL_write_callback  . write_callback+  FREAD   -> fmap castFunPtr . C.wrapCURL_read_callback   . read_callback+  FHEADER -> fmap castFunPtr . C.wrapCURL_header_callback . header_callback  freeCB :: CURLCB -> IO () freeCB (CURLCB _ fp) = when (fp/=nullFunPtr) (freeHaskellFunPtr fp)@@ -637,8 +639,9 @@   :: IORef [CURLCB] -> CURLCBT a -> Ptr C.CURL -> CInt -> Maybe a -> IO CInt makeCB cbref cbt ccurl copt mcb =   let comp :: CURLCBT a -> CURLCB -> Bool-      comp FWRITE (CURLCB FWRITE _) = True; comp FWRITE _ = False-      comp FREAD  (CURLCB FREAD  _) = True; comp FREAD  _ = False+      comp FWRITE  (CURLCB FWRITE  _) = False; comp FWRITE  _ = True+      comp FREAD   (CURLCB FREAD   _) = False; comp FREAD   _ = True+      comp FHEADER (CURLCB FHEADER _) = False; comp FHEADER _ = True       cons fp (tokeep, tofree) = ((CURLCB cbt fp):tokeep, tofree)       keep 0 fp cbs = cons fp $ partition (comp cbt) cbs       keep _ fp cbs = cons fp $ (cbs,[])@@ -668,6 +671,15 @@     CURL_READFUNC_ABORT -> return #{const CURL_READFUNC_ABORT}     CURL_READFUNC_OK bs -> unsafeUseAsCStringLen (BS.take buffLen bs)       (\(cs, cl) -> copyBytes buff cs cl >> return (fromIntegral cl))+++-------------------------------------------------------------------------------+header_callback :: CURL_header_callback -> C.CURL_header_callback+header_callback fheader ptr size nmemb _ = do+  stat <- packCStringLen (ptr, fromIntegral (size * nmemb)) >>= fheader+  return $ case stat of+    CURL_HEADERFUNC_OK   -> (size * nmemb)+    CURL_HEADERFUNC_FAIL -> 0   -------------------------------------------------------------------------------
Network/CURL000/LibLD.hs view
@@ -14,17 +14,6 @@   ( RTLD(..), LIBCURL(..)   ) where -import Network.CURL000.LibCC (curlADRTAB, curlSYMTAB, curlTABLEN)-import Network.CURL000.LibHS (curl_global_init, curl_global_cleanup)-import Network.CURL000.LibHS (curl_version)--import Text.ParserCombinators.ReadP (ReadP, readP_to_S, string)-import Text.Read.Lex (readDecP)--import Control.Concurrent (MVar, newMVar)-import System.IO.Unsafe (unsafePerformIO)--import System.Info (os) import System.RTLD  @@ -33,64 +22,6 @@   deriving (Eq, Ord, Enum, Bounded)  instance RTLD LIBCURL where-  loadlib x = rtload curlRTSO x-  freelib _ = rtfree curlRTSO-----------------------------------------------------------------------------------curlGlobalState :: MVar (Maybe (LIBCURL, LIBH, Int))-curlGlobalState = unsafePerformIO (newMVar Nothing)-{-# NOINLINE curlGlobalState #-}--curlRTSO :: RTSO LIBCURL-curlRTSO = RTSO-  { rtPKGMVAR = curlGlobalState-  , rtPKGNAME = "<curlhs>"-  , rtLIBNAME = libname-  , rtSONAMES = sonames-  , rtONLOAD  = const curl_global_init-  , rtONFREE  = const curl_global_cleanup-  , rtGETAPI  = const (fmap readapi curl_version)-  , rtSYMTAB  = curlSYMTAB-  , rtADRTAB  = curlADRTAB-  , rtTABLEN  = curlTABLEN-  }-----------------------------------------------------------------------------------libname :: LIBCURL -> String-libname CURL720 = "libcurl/7.20"-libname CURL730 = "libcurl/7.30"--readapi :: String -> Maybe LIBCURL-readapi xs = parse >>= check-  where-  readP = readP_to_S (string "libcurl/7." >> (readDecP :: ReadP Int))-  parse = case (readP xs) of [(v,_)] -> Just v; _ -> Nothing-  check v-    | v>=20 && v<30 = Just CURL720-    | v>=30         = Just CURL730-    | otherwise     = Nothing-----------------------------------------------------------------------------------sonames :: LIBCURL -> [String]-sonames-  | os == "mingw32" = winsonames-  | os == "darwin"  = osxsonames-  | os == "linux"   = gnusonames-  | os == "freebsd" = bsdsonames-  | otherwise = const []--winsonames :: LIBCURL -> [String]-winsonames _ = ["libcurl.dll"]--osxsonames :: LIBCURL -> [String]-osxsonames _ = ["libcurl.dylib"]--gnusonames :: LIBCURL -> [String]-gnusonames _ = ["libcurl.so.4", "libcurl.so"]--bsdsonames :: LIBCURL -> [String]-bsdsonames _ = ["libcurl.so"]+  loadlib _ = return ()+  freelib _ = return () 
Network/CURL000/Types.hsc view
@@ -449,7 +449,7 @@  -- CURLOPT_CLOSESOCKETDATA  -- CURLOPT_PROGRESSFUNCTION  -- CURLOPT_PROGRESSDATA- -- CURLOPT_HEADERFUNCTION+  | CURLOPT_HEADERFUNCTION          (Maybe CURL_header_callback)  -- CURLOPT_HEADERDATA  -- CURLOPT_DEBUGFUNCTION  -- CURLOPT_DEBUGDATA@@ -676,7 +676,15 @@   deriving (Eq)  +type CURL_header_callback = ByteString -> IO CURL_header_response +data CURL_header_response+  = CURL_HEADERFUNC_OK+  | CURL_HEADERFUNC_FAIL+  deriving (Eq)+++ ------------------------------------------------------------------------------- data CURLC   = CURLE_UNSUPPORTED_PROTOCOL@@ -848,8 +856,9 @@   CURLCB :: CURLCBT a -> FunPtr () -> CURLCB  data CURLCBT a where-  FWRITE :: CURLCBT CURL_write_callback-  FREAD  :: CURLCBT CURL_read_callback+  FWRITE  :: CURLCBT CURL_write_callback+  FREAD   :: CURLCBT CURL_read_callback+  FHEADER :: CURLCBT CURL_header_callback  type CURLSL = (CInt, Ptr C.CURLslist) 
Network/CURL720.hs view
@@ -15,13 +15,8 @@   ( module Network.CURL000    -- |-  -- Using functions from this module requires an explicit linking-  -- with @libcurl\/7.20@ or newer at program runtime:-  ---  -- > main = withlib CURL720 $ do-  -- >   ...-  ---  -- Without that, any foreign call to @libcurl@ will fail.+  -- This module exports __libcurl 7.20 API__. Version 7.20 or higher+  -- of the @libcurl[.dll|.so|.dylib]@ is required at program runtime.   --   -- More info may be found in the <docs/#/README.md docs>. @@ -135,7 +130,7 @@      -- CURLOPT_OPENSOCKETDATA      -- CURLOPT_PROGRESSFUNCTION      -- CURLOPT_PROGRESSDATA-     -- CURLOPT_HEADERFUNCTION+      , CURLOPT_HEADERFUNCTION      -- CURLOPT_HEADERDATA      -- CURLOPT_DEBUGFUNCTION      -- CURLOPT_DEBUGDATA@@ -326,8 +321,9 @@       )    -- *** Callbacks-  , CURL_write_callback, CURL_write_response (..)-  , CURL_read_callback , CURL_read_response  (..)+  , CURL_write_callback , CURL_write_response  (..)+  , CURL_read_callback  , CURL_read_response   (..)+  , CURL_header_callback, CURL_header_response (..)    -- *** Constants   , CURLproto
Network/CURL730.hs view
@@ -15,13 +15,8 @@   ( module Network.CURL000    -- |-  -- Using functions from this module requires an explicit linking-  -- with @libcurl\/7.30@ or newer at program runtime:-  ---  -- > main = withlib CURL730 $ do-  -- >   ...-  ---  -- Without that, any foreign call to @libcurl@ will fail.+  -- This module exports __libcurl 7.30 API__. Version 7.30 or higher+  -- of the @libcurl[.dll|.so|.dylib]@ is required at program runtime.   --   -- More info may be found in the <docs/#/README.md docs>. @@ -143,7 +138,7 @@      -- CURLOPT_CLOSESOCKETDATA      -- CURLOPT_PROGRESSFUNCTION      -- CURLOPT_PROGRESSDATA-     -- CURLOPT_HEADERFUNCTION+      , CURLOPT_HEADERFUNCTION      -- CURLOPT_HEADERDATA      -- CURLOPT_DEBUGFUNCTION      -- CURLOPT_DEBUGDATA@@ -352,8 +347,9 @@       )    -- *** Callbacks-  , CURL_write_callback, CURL_write_response (..)-  , CURL_read_callback , CURL_read_response  (..)+  , CURL_write_callback , CURL_write_response  (..)+  , CURL_read_callback  , CURL_read_response   (..)+  , CURL_header_callback, CURL_header_response (..)    -- *** Constants   , CURLproto
curlhs.cabal view
@@ -1,5 +1,5 @@ name:          curlhs-version:       0.1.5+version:       0.1.6 synopsis:      bindings to libcurl, the multiprotocol file transfer library homepage:      https://github.com/kkardzis/curlhs category:      Network@@ -63,6 +63,7 @@   docs/index.html   docs/*.md   README.md+  CHANGELOG.md   LICENSE  -------------------------------------------------------------------------------@@ -90,7 +91,16 @@   include-dirs:     Network/CURL000 +  if os(windows)+    cc-options: -DWINRTLD -DSONAME="libcurl.dll" +  if os(osx)+    cc-options: -DOSXRTLD -DSONAME="libcurl.dylib"++  if os(linux) || os(freebsd)+    cc-options: -DUNIRTLD -DSONAME="libcurl.so" -DSONAME0="libcurl.so.4"++ ------------------------------------------------------------------------------- test-suite hspec   type:           exitcode-stdio-1.0@@ -100,7 +110,6 @@   hs-source-dirs: test    other-modules:-    Network.CURL000Spec     Network.CURL720Spec     Network.CURL730Spec 
docs/examples/GetInMemory.hs view
@@ -16,9 +16,7 @@ import Network.CURL720  -main = withlib CURL720 $ do-  lbs <- curlGET "http://httpbin.org/get"-  BL.putStrLn lbs+main = curlGET "http://httpbin.org/get" >>= BL.putStrLn   curlGET :: String -> IO BL.ByteString@@ -28,10 +26,10 @@     curl_easy_setopt curl       [ CURLOPT_URL url       -- specify URL to get- +       , CURLOPT_WRITEFUNCTION $ Just (memwrite ref)       -- send all data to this function- +       , CURLOPT_USERAGENT "libcurl-agent/1.0"       -- some servers don't like requests that are made without a user-agent       -- field, so we provide one
docs/examples/Https.hs view
@@ -8,7 +8,7 @@ import Network.CURL720  -main = withlib CURL720 $ do+main = do   curl <- curl_easy_init   curl_easy_setopt curl     [ CURLOPT_URL "https://httpbin.org/get"
docs/examples/Simple.hs view
@@ -8,7 +8,7 @@ import Network.CURL720  -main = withlib CURL720 $ do+main = do   curl <- curl_easy_init   curl_easy_setopt curl     [ CURLOPT_URL "http://httpbin.org/get"
docs/index.html view
@@ -35,7 +35,7 @@   $http.get('https://cors-anywhere.herokuapp.com/https://github.com').     error(function(raw) { $scope.ready = true; }).     success(function(raw) {-      var reg = /href="([^"]+github2?-[^"]+\.css)"/g;+      var reg = /href="([^"]+github2?[^"]+\.css)"/g;       var cs1; if (cs1=reg.exec(raw)) {$scope.github1css = cs1[1];};       var cs2; if (cs2=reg.exec(raw)) {$scope.github2css = cs2[1];};       var css = getComputedStyle(document.getElementById('readme'));
docs/tutorial.md view
@@ -46,13 +46,9 @@  # Does it work? -To see if *curlhs* works, let's try to check *libcurl* version. Run GHCi:--```sh-$ ghci-```--The simple call to `curl_version` should return the *libcurl* version string:+To see if *curlhs* works, let's try to check *libcurl* version. The simple+call to `curl_version` should return the *libcurl* version string, but...+let's assume we are on Windows, where *libcurl* is not installed by default:  ```hs ghci> :m Network.CURL720@@ -60,20 +56,16 @@ *** Exception: <curlhs> failed to call 'curl_version' (NULL) ``` -Obviously that's not what was expected. But what's wrong? The short answer-is that *libcurl* was not loaded before use. *curlhs* depends on *libcurl*,-but does not link with *libcurl* at compile/build time like most libraries-would. Instead, it is necessary to explicitly load *libcurl* at runtime.-So let's try:+Obviously that's not what was expected. But what's wrong? *curlhs* depends+on *libcurl*, but does not link with *libcurl* at compile/build time like most+libraries would. Instead, it uses dynamic loader mechanisms to explicitly load+*libcurl* at runtime. This may fail when loaded *libcurl* is not compatible+with *curlhs* or when there is no *libcurl* at all. -```hs-ghci> loadlib CURL720-*** Exception: <curlhs> failed to load libcurl/7.20 ["libcurl.dll"]-```+In the above example the dynamic loader searchs for "libcurl.dll", but it+cannot find it in the default search path. -What now? Let's assume we are on Windows, where *libcurl* is not installed-by default. The dynamic loader searchs for "libcurl.dll", but it cannot find-it in the default search path. It's time to install *libcurl*.+It's time to install *libcurl*.   # Where is *libcurl*?@@ -167,36 +159,26 @@  # It works? Really? -Now, when *libcurl* is in the scope, let's try again. Let's assume we-are on Windows with "libcurl/7.34" like in the example above. Run GHCi,-import one of the *curlhs* modules, load *libcurl*, and finally check-its version:+Now, when *libcurl* is in the scope, let's try again. Let's assume we are+on Windows with "libcurl/7.34" like in the example above. Run GHCi, import+one of the *curlhs* modules and finally check the *libcurl* version:  ```hs ghci> :m Network.CURL720-ghci> loadlib CURL720 ghci> curl_version "libcurl/7.34.0 OpenSSL/1.0.0k zlib/1.2.8 libidn/1.18 libssh2/1.4.3 librtmp/2.3" ``` -Excellent! But what if...+Excellent! -```hs-ghci> freelib CURL720-ghci> curl_version-*** Exception: <curlhs> failed to call 'curl_version' (NULL)-``` -Nice. - # Hello World!  This is about the file transfer library, so let's try to download something:  ```hs ghci> :m Network.CURL720-ghci> loadlib CURL720 ghci> c <- curl_easy_init ghci> curl_easy_setopt c [CURLOPT_URL "http://httpbin.org/get"] ghci> curl_easy_perform c
− test/Network/CURL000Spec.hs
@@ -1,17 +0,0 @@-module Network.CURL000Spec where----import Network.CURL000--import Test.Hspec---main :: IO ()-main = hspec spec--spec :: Spec-spec = do--  describe "RTLD LIBCURL" $ do-    it "load/free libcurl" $ do-      pending-
test/Network/CURL720Spec.hs view
@@ -1,38 +1,16 @@ module Network.CURL720Spec where  import Network.CURL720--import Control.Exception (tryJust, ErrorCall (..))--import Text.ParserCombinators.ReadP (ReadP, readP_to_S, string)-import Text.Read.Lex (readDecP)--import Data.List (isPrefixOf)- import Test.Hspec --testlib :: LIBCURL -> IO (Either String ())-testlib lib =-  let maybeEx s = if (isPrefixOf "<curlhs>" s) then Just s else Nothing-  in  tryJust (\(ErrorCall s) -> maybeEx s) (withlib lib (return ()))-- main :: IO () main = hspec spec  spec :: Spec-spec = runIO (testlib CURL720) >>= \x -> case x of-  Left  xs -> it "cannot test this module" (pendingWith xs)-  Right () -> before_ (loadlib CURL720) $ after_ (freelib CURL720) $ do+spec = do    ----------------------------   describe "curl_version" $ do     it "returns libcurl version string: \"libcurl/7.x.x ...\"" $ do       curl_version >>= (`shouldContain` "libcurl/7.")--    it "returns libcurl version 7.20 or higher compatible" $ do-      let readP = readP_to_S (string "libcurl/7." >> (readDecP :: ReadP Int))-      let check s = case (readP s) of [(v,_)] -> Just (v>=20); _ -> Nothing-      curl_version >>= (`shouldSatisfy` (\s -> maybe False id (check s))) 
test/Network/CURL730Spec.hs view
@@ -1,38 +1,16 @@ module Network.CURL730Spec where  import Network.CURL730--import Control.Exception (tryJust, ErrorCall (..))--import Text.ParserCombinators.ReadP (ReadP, readP_to_S, string)-import Text.Read.Lex (readDecP)--import Data.List (isPrefixOf)- import Test.Hspec --testlib :: LIBCURL -> IO (Either String ())-testlib lib =-  let maybeEx s = if (isPrefixOf "<curlhs>" s) then Just s else Nothing-  in  tryJust (\(ErrorCall s) -> maybeEx s) (withlib lib (return ()))-- main :: IO () main = hspec spec  spec :: Spec-spec = runIO (testlib CURL730) >>= \x -> case x of-  Left  xs -> it "cannot test this module" (pendingWith xs)-  Right () -> before_ (loadlib CURL730) $ after_ (freelib CURL730) $ do+spec = do    ----------------------------   describe "curl_version" $ do     it "returns libcurl version string: \"libcurl/7.x.x ...\"" $ do       curl_version >>= (`shouldContain` "libcurl/7.")--    it "returns libcurl version 7.30 or higher compatible" $ do-      let readP = readP_to_S (string "libcurl/7." >> (readDecP :: ReadP Int))-      let check s = case (readP s) of [(v,_)] -> Just (v>=30); _ -> Nothing-      curl_version >>= (`shouldSatisfy` (\s -> maybe False id (check s)))