packages feed

wai-cors 0.2.3 → 0.2.4

raw patch · 10 files changed

+423/−57 lines, 10 filesdep +tastydep +tasty-hunitdep +wai-extradep ~base-unicode-symbolsdep ~http-typesdep ~wai

Dependencies added: tasty, tasty-hunit, wai-extra

Dependency ranges changed: base-unicode-symbols, http-types, wai

Files

CHANGELOG.md view
@@ -1,3 +1,10 @@+0.2.4+=====++*   Fix [bug #1](https://github.com/larskuhtz/wai-cors/issues/1).+    Response header `Vary: Origin` is now included when `corsVaryOrigin`+    is `True` and `corsOrigins` does not equal `Nothing`.+ 0.2.3 ===== 
LICENSE view
@@ -1,3 +1,4 @@+Copyright (c) 2015 Lars Kuhtz <lakuhtz@gmail.com> Copyright (c) 2014 AlephCloud Systems, Inc.  Permission is hereby granted, free of charge, to any person obtaining
constraints view
@@ -1,30 +1,82 @@-constraints: array ==0.5.1.0,+constraints: SHA ==1.6.4.2,+             ansi-terminal ==0.6.2.1,+             ansi-wl-pprint ==0.6.7.2,+             appar ==0.1.4,+             array ==0.5.1.0,+             async ==2.0.2,              attoparsec ==0.13.0.0,+             auto-update ==0.1.2.1,              base ==4.8.0.0,              base-unicode-symbols ==0.2.2.4,+             base64-bytestring ==1.0.0.1,              binary ==0.7.3.0,              blaze-builder ==0.4.0.1,+             byteorder ==1.0.4,              bytestring ==0.10.6.0,+             bytestring-builder ==0.10.6.0.0,              case-insensitive ==1.2.0.4,              charset ==0.3.7.1,              containers ==0.5.6.2,+             cookie ==0.4.1.5,+             data-default-class ==0.0.1,              deepseq ==1.4.1.1,+             directory ==1.2.2.0,+             easy-file ==0.2.1,+             entropy ==0.3.6,+             exceptions ==0.8.0.2,+             fast-logger ==2.3.1,+             filepath ==1.4.0.0,              ghc-prim ==0.4.0.0,              hashable ==1.2.3.2,+             http-date ==0.0.6.1,              http-types ==0.8.6,              integer-gmp ==1.0.0.0,+             iproute ==1.4.0,+             lifted-base ==0.2.3.6,+             mmorph ==1.0.4,+             monad-control ==1.0.0.4,              mtl ==2.2.1,              nats ==1,              network ==2.6.1.0,+             old-locale ==1.0.0.7,+             old-time ==1.1.0.3,+             optparse-applicative ==0.11.0.2,              parsec ==3.1.9,              parsers ==0.12.2.1,+             pretty ==1.1.2.0,+             process ==1.2.3.0,+             random ==1.1,+             regex-base ==0.93.2,+             regex-tdfa-rc ==1.1.8.3,+             resourcet ==1.1.5,              rts ==1.0,              scientific ==0.3.3.8,              semigroups ==0.16.2.2,+             simple-sendfile ==0.2.20,+             stm ==2.4.4,+             streaming-commons ==0.1.12.1,+             stringsearch ==0.3.6.6,+             tagged ==0.8.0.1,+             tasty ==0.10.1.2,+             tasty-hunit ==0.9.2,+             template-haskell ==2.10.0.0,              text ==1.2.1.0,              time ==1.5.0.1,              transformers ==0.4.2.0,+             transformers-base ==0.4.4,+             transformers-compat ==0.4.0.4,+             unbounded-delays ==0.1.0.9,              unix ==2.7.1.0,+             unix-compat ==0.4.1.4,+             unix-time ==0.3.5,              unordered-containers ==0.2.5.1,              vault ==0.3.0.4,-             wai ==3.0.2.3+             void ==0.7,+             wai ==3.0.2.3,+             wai-extra ==3.0.7.1,+             wai-logger ==2.2.4,+             wai-websockets ==3.0.0.5,+             warp ==3.0.13.1,+             websockets ==0.9.5.0,+             word8 ==0.1.2,+             zlib ==0.5.4.2
src/Network/Wai/Middleware/Cors.hs view
@@ -1,8 +1,3 @@--- ------------------------------------------------------ ----- Copyright © 2015 Lars Kuhtz <lakuhtz@gmail.com>--- Copyright © 2014 AlephCloud Systems, Inc.--- ------------------------------------------------------ --- {-# LANGUAGE UnicodeSyntax #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-}@@ -12,7 +7,17 @@ {-# LANGUAGE PatternGuards #-} {-# LANGUAGE CPP #-} --- | An implemenation of Cross-Origin resource sharing (CORS) for WAI that+-- |+-- Module: Network.Wai.Middleware.Cors+-- Description: Cross-Origin resource sharing (CORS) for WAI+-- Copyright:+--     © 2015 Lars Kuhtz <lkuhtz@gmail.com,+--     © 2014 AlephCloud Systems, Inc.+-- License: MIT+-- Maintainer: Lars Kuhtz <lakuhtz@gmail.com>+-- Stability: stable+--+-- An implemenation of Cross-Origin resource sharing (CORS) for WAI that -- aims to be compliant with <http://www.w3.org/TR/cors>. -- -- The function 'simpleCors' enables support of simple cross-origin requests. More@@ -100,6 +105,9 @@ import qualified Data.CharSet as CS import Data.List (intersect, (\\), union) import Data.Maybe (catMaybes)+#if ! MIN_VERSION_base(4,8,0)+import Data.Monoid (mempty)+#endif import Data.Monoid.Unicode import Data.String @@ -111,14 +119,17 @@ import qualified Text.Parser.Char as P import qualified Text.Parser.Combinators as P +{- #if MIN_VERSION_wai(2,0,0) type ReqMonad = IO #else type ReqMonad = ResourceT IO #endif+-} --- | Origins are expected to be formated as described in RFC 6454 (section--- 6.2). In particular the string @*@ is not a valid origin (but the string+-- | Origins are expected to be formated as described in+-- <https://www.ietf.org/rfc/rfc6454.txt RFC6454> (section 6.2).+-- In particular the string @*@ is not a valid origin (but the string -- @null@ is). -- type Origin = B8.ByteString@@ -136,7 +147,8 @@     -- origins each with a Boolean flag that indicates if credentials are used     -- to access the resource via CORS.     ---    -- Origins must be formated as described in RFC6454 (section 6.2). In+    -- Origins must be formated as described in+    -- <https://www.ietf.org/rfc/rfc6454.txt RFC6454> (section 6.2). In     -- particular the string @*@ is not a valid origin (but the string @null@     -- is).     --@@ -162,7 +174,11 @@      -- | If the resource is shared by multiple origins but     -- @Access-Control-Allow-Origin@ is not set to @*@ this may be set to-    -- 'True'.+    -- 'True' to cause the server to include a @Vary: Origin@ header in the+    -- response, thus indicating that the value of the+    -- @Access-Control-Allow-Origin@ header may vary between different requests+    -- for the same resource. This prevents caching of the responses which may+    -- not apply accross different origins.     --     , corsVaryOrigin ∷ !Bool @@ -337,13 +353,13 @@             else res $ corsFailure (B8.pack e)          -- Match request origin with corsOrigins from policy-        let respOrigin = case corsOrigins policy of+        let respOriginOrErr = case corsOrigins policy of                 Nothing → return Nothing                 Just (originList, withCreds) → if origin `elem` originList                     then Right $ Just (origin, withCreds)                     else Left $ "Unsupported origin: " ⊕ B8.unpack origin -        case respOrigin of+        case respOriginOrErr of             Left e → err e             Right respOrigin → do @@ -413,10 +429,13 @@     -- HTTP response headers that are common to normal and preflight CORS responses     --     commonCorsHeaders ∷ Maybe (Origin, Bool) → Bool → HTTP.ResponseHeaders-    commonCorsHeaders Nothing True = [("Access-Control-Allow-Origin", "*"), ("Vary", "Origin")]-    commonCorsHeaders Nothing False = [("Access-Control-Allow-Origin", "*")]-    commonCorsHeaders (Just (o, False)) _ = [("Access-Control-Allow-Origin", o)]-    commonCorsHeaders (Just (o, True)) _  = [("Access-Control-Allow-Origin", o), ("Access-Control-Allow-Credentials", "true")]+    commonCorsHeaders Nothing _ = [("Access-Control-Allow-Origin", "*")]+    commonCorsHeaders (Just (o, creds)) vary = []+        ⊕ (True ?? ("Access-Control-Allow-Origin", o))+        ⊕ (creds ?? ("Access-Control-Allow-Credentials", "true"))+        ⊕ (vary ?? ("Vary", "Origin"))+      where+        (??) a b = if a then pure b else mempty      -- HTTP response headers that are only used with normal CORS responses     --
test/PhantomJS.hs view
@@ -35,7 +35,7 @@  phantomJsArgs ∷ IsString a ⇒ [a] phantomJsArgs = ["--ignore-ssl-errors=true"]---phantomJsArgs = ["--ignore-ssl-errors=true", "--debug=true"]+-- phantomJsArgs = ["--ignore-ssl-errors=true", "--debug=true"]  phantomJsScriptPath ∷ FilePath phantomJsScriptPath = "test/phantomjs.js"
test/Server.hs view
@@ -35,19 +35,37 @@ import qualified Data.Text as T  main ∷ IO ()-main = withSocketsDo $-    WARP.run 8080 $ simpleCors waiapp+main = withSocketsDo . WARP.run 8080 $ server -waiapp ∷ WAI.Application-waiapp = WS.websocketsOr WS.defaultConnectionOptions wsserver $ \_ → app+-- -------------------------------------------------------------------------- --+-- Server application++server ∷ WAI.Application+server = cors corsPolicy $ \request →+    case WAI.pathInfo request of+        "cors":_ → corsapp request+        _ → testapp   where #if MIN_VERSION_wai(2,0,0)-    app respond = respond $ WAI.responseLBS HTTP.status200 [] "Success"+    testapp respond = respond $ WAI.responseFile HTTP.status200 [] "index.html" Nothing+    corsapp = WS.websocketsOr WS.defaultConnectionOptions wsserver $ \_ respond →+        respond $ WAI.responseLBS HTTP.status200 [] "Success" #else-    app = WAI.responseLBS HTTP.status200 [] "Success"+    testapp = WAI.responseFile HTTP.status200 [] "index.html" Nothing+    corsapp = WS.websocketsOr WS.defaultConnectionOptions wsserver $ \_ →+        WAI.responseLBS HTTP.status200 [] "Success" #endif  -- -------------------------------------------------------------------------- --+-- CORS Policy++corsPolicy ∷ WAI.Request → Maybe CorsResourcePolicy+corsPolicy request = case WAI.pathInfo request of+    "cors" : "non-simple":_ → Just nonSimplePolicy+    "cors" : "simple":_ → Just simpleCorsResourcePolicy+    _ → Nothing++-- -------------------------------------------------------------------------- -- -- Websockets Server  wsserver ∷ WS.ServerApp@@ -60,4 +78,33 @@     go c = do         msg ← WS.receiveDataMessage c         forkIO $ WS.sendDataMessage c msg++-- -------------------------------------------------------------------------- --+-- Non Simple Policy++-- | Perform the following tests the following with this policy:+--+-- * @Variy: Origin@ header is set on responses+-- * @X-cors-test@ header is accepted+-- * @X-cors-test@ header is exposed on response+-- * @Access-Control-Allow-Origin@ header is set on responses to the request host+-- * @DELETE@ requests are not allowed+-- * @PUT@ requests are allowed+-- * Requests that don't include an @Origin@ header result in 400 responses+--   (it's not clear how to test this with a browser client)+--+-- Note that Chrome sends @Origin: null@ when loaded from a "file://..." URL,+-- PhantomJS sends "file://".+--+nonSimplePolicy :: CorsResourcePolicy+nonSimplePolicy = CorsResourcePolicy+    { corsOrigins = Just (["http://localhost:8080", "null", "file://"], False)+    , corsMethods = ["PUT"]+    , corsRequestHeaders = ["X-cors-test"]+    , corsExposedHeaders = Just ["X-cors-test", "Vary"]+    , corsMaxAge = Nothing+    , corsVaryOrigin = True+    , corsRequireOrigin = True+    , corsIgnoreFailures = False+    } 
+ test/UnitTests.hs view
@@ -0,0 +1,154 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UnicodeSyntax #-}++-- |+-- Module: UnitTests+-- Description: Unit Tests for wai-cors+-- Copyright: © 2015 Lars Kuhtz <lakuhtz@gmail.com>.+-- License: MIT+-- Maintainer: Lars Kuhtz <lakuhtz@gmail.com>+-- Stability: experimental+--+module Main+( main++, post+, patch+, delete+, put+, get+, options+, head+) where++#ifndef MIN_VERSION_wai+#define MIN_VERSION_wai(a,b,c) 1+#endif++import Network.Wai.Middleware.Cors+import qualified Network.HTTP.Types as HTTP+import qualified Network.Wai as WAI+import Network.Wai.Test++import Prelude hiding (head)++import Test.Tasty+import Test.Tasty.HUnit++-- -------------------------------------------------------------------------- --+-- Unit tests++main ∷ IO ()+main = defaultMain tests++tests ∷ TestTree+tests = testGroup "unit tests"+    [ testCase "Origins any" test_originsAny+    , testCase "Origins null" test_originsNull+    , testCase "Any Origin" test_anyOrigin+    , testCase "Require Origin" test_requireOrigin+    , testCase "Missing Require Origin" test_missingRequireOrigin+    , testCase "Vary Origin Header" test_varyOriginHeader+    , testCase "Vary Origin No Header" test_varyOriginNoHeader+    ]++test_originsAny ∷ Assertion+test_originsAny = corsSession policy $ do+    resp <- request get+    assertHeader "Access-Control-Allow-Origin" "*" resp+    assertStatus 200 resp+  where+    policy = simpleCorsResourcePolicy+        { corsOrigins = Nothing+        }++test_originsNull ∷ Assertion+test_originsNull = corsSession policy $ do+    resp <- request get+    assertHeader "Access-Control-Allow-Origin" "null" resp+    assertStatus 200 resp+  where+    policy = simpleCorsResourcePolicy+        { corsOrigins = Just (["null"], False)+        }++test_missingRequireOrigin ∷ Assertion+test_missingRequireOrigin = corsSession policy $ do+    resp <- request $ defaultRequest { WAI.requestMethod = "GET" }+    assertStatus 400 resp+  where+    policy = simpleCorsResourcePolicy+        { corsRequireOrigin = True+        }++test_requireOrigin ∷ Assertion+test_requireOrigin = corsSession policy $ do+    resp <- request get+    assertStatus 200 resp+  where+    policy = simpleCorsResourcePolicy+        { corsRequireOrigin = True+        }++test_anyOrigin ∷ Assertion+test_anyOrigin = corsSession policy $ do+    resp <- request get+    assertStatus 200 resp+  where+    policy = simpleCorsResourcePolicy+        { corsOrigins = Nothing+        }++test_varyOriginHeader ∷ Assertion+test_varyOriginHeader = corsSession policy $ do+    resp <- request put+    assertStatus 200 resp+    assertHeader "Vary" "Origin" resp+  where+    policy = simpleCorsResourcePolicy+        { corsOrigins = Just (["null"], False)+        , corsVaryOrigin = True+        }++test_varyOriginNoHeader ∷ Assertion+test_varyOriginNoHeader = corsSession policy $ do+    resp <- request put+    assertStatus 200 resp+    assertNoHeader "Vary" resp+  where+    policy = simpleCorsResourcePolicy+        { corsOrigins = Nothing+        , corsVaryOrigin = True+        }++-- -------------------------------------------------------------------------- --+-- Test Requests++corsSession ∷ CorsResourcePolicy → Session () → Assertion+corsSession policy session = runSession session . cors (const $ Just policy) $ app++corsRequest ∷ WAI.Request+corsRequest = WAI.defaultRequest+    { WAI.pathInfo = ["cors"]+    , WAI.requestHeaders = [("Origin", "null")]+    }++get, post, put, patch, delete, head, options ∷ WAI.Request+get = corsRequest { WAI.requestMethod = "GET" }+post = corsRequest { WAI.requestMethod = "POST" }+put = corsRequest { WAI.requestMethod = "PUT" }+patch = corsRequest { WAI.requestMethod = "PATCH" }+delete = corsRequest { WAI.requestMethod = "DELETE" }+head = corsRequest { WAI.requestMethod = "HEAD" }+options = corsRequest { WAI.requestMethod = "OPTIONS" }++app ∷ WAI.Application+#if MIN_VERSION_wai(2,0,0)+app _ respond = respond $ WAI.responseLBS HTTP.status200 [] "Success"+#else+app _ = WAI.responseLBS HTTP.status200 [] "Success"+#endif+
test/index.html view
@@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- Copyright (c) 2015 Lars Kuhtz <lakuhtz@gmail.coml> --> <html>-    <head> +    <head>     <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>     <script type="text/javascript"> @@ -96,7 +96,7 @@         window.setTimeout(function () { window.callPhantom("timeout"); },3000);     }; -    var phantomJsCb = function (result) { +    var phantomJsCb = function (result) {         if (typeof window.callPhantom === 'function') {             window.callPhantom(result);         };@@ -110,15 +110,28 @@         var test = $.Deferred();         var req = $.ajax(             { 'method': params.method-            , 'url': url+            , 'url': url + "/cors/" + params.path + "/" + encodeURIComponent(params.label)             , 'contentType': params.contentType-            , 'crossDomain': true+            , 'crossDomain': params.cors             , 'headers': params.headers             });          var succ = function () { test.resolve(params); }         var fail = function () { test.reject(params); }-        req.done(params.expectedResult ? succ : fail);+        var check = function () {+            /* check if the response matches our expectations */+            for (var i in params.expectedHeaders) {+                if (params.expectedHeaders.hasOwnProperty(i)) {+                    var hdr = req.getResponseHeader(i);+                    // console.log(req.getAllResponseHeaders());+                    if ( ! hdr || hdr != params.expectedHeaders.i) {+                        return false;+                    }+                }+            }+            return true;+        }+        req.done(check() === params.expectedResult ? succ : fail);         req.fail(params.expectedResult ? fail : succ);          return test.promise();@@ -155,7 +168,7 @@         var timeout = timeout ? timeout : 1000;         var curMsgId = 0;         var ready = $.Deferred();-        var websocket = new WebSocket(url);+        var websocket = new WebSocket(url + "/cors");         var newMsgId = function () { return ++curMsgId; };          // maps message ids data to promise objects@@ -229,43 +242,80 @@ /* ************************************************************************** */ /* Test Vectors */ -    var mkTest = function (label, expectedResult, method, credentials, contentType, headers) {+    var mkTest = function (label, expectedResult, method, path, credentials, contentType, headers, cors) {         return {             label: label,             expectedResult: expectedResult,             method: method,+            path: path,             credentials: credentials,             contentType: contentType,-            headers: headers+            headers: headers,         };     } -    var tests = [-        mkTest("simple GET 1", true, "GET", false, 'text/plain', []),-        mkTest("simple GET 2", true, "GET", false, 'application/x-www-form-urlencoded', []),-        mkTest("simple GET 3", true, "GET", false, 'multipart/form-data', []),-        mkTest("simple GET 4", false, "GET", false, 'application/json', []),-        mkTest("simple GET 5", false, "GET", false, 'text/plain', {'abc': 'abc'}),+    var simpleTests = [+        mkTest("simple GET 1", true, "GET", "simple", false, 'text/plain', []),+        mkTest("simple GET 2", true, "GET", "simple", false, 'application/x-www-form-urlencoded', []),+        mkTest("simple GET 3", true, "GET", "simple", false, 'multipart/form-data', []),+        mkTest("simple GET 4", false, "GET", "simple", false, 'application/json', []),+        mkTest("simple GET 5", false, "GET", "simple", false, 'text/plain', {'abc': 'abc'}), -        mkTest("simple HEAD 1", true, "HEAD", false, 'text/plain', []),-        mkTest("simple HEAD 2", true, "HEAD", false, 'application/x-www-form-urlencoded', []),-        mkTest("simple HEAD 3", true, "HEAD", false, 'multipart/form-data', []),-        mkTest("simple HEAD 4", false, "HEAD", false, 'application/json', []),-        mkTest("simple HEAD 5", false, "HEAD", false, 'text/plain', {'abc': 'abc'}),+        mkTest("simple HEAD 1", true, "HEAD", "simple", false, 'text/plain', []),+        mkTest("simple HEAD 2", true, "HEAD", "simple", false, 'application/x-www-form-urlencoded', []),+        mkTest("simple HEAD 3", true, "HEAD", "simple", false, 'multipart/form-data', []),+        mkTest("simple HEAD 4", false, "HEAD", "simple", false, 'application/json', []),+        mkTest("simple HEAD 5", false, "HEAD", "simple", false, 'text/plain', {'abc': 'abc'}), -        mkTest("simple POST 1", true, "POST", false, 'text/plain', []),-        mkTest("simple POST 2", true, "POST", false, 'application/x-www-form-urlencoded', []),-        mkTest("simple POST 3", true, "POST", false, 'multipart/form-data', []),-        mkTest("simple POST 4", false, "POST", false, 'application/json', []),-        mkTest("simple POST 5", false, "POST", false, 'test/plain', {'abc':'abc'}),+        mkTest("simple POST 1", true, "POST", "simple", false, 'text/plain', []),+        mkTest("simple POST 2", true, "POST", "simple", false, 'application/x-www-form-urlencoded', []),+        mkTest("simple POST 3", true, "POST", "simple", false, 'multipart/form-data', []),+        mkTest("simple POST 4", false, "POST", "simple", false, 'application/json', []),+        mkTest("simple POST 5", false, "POST", "simple", false, 'test/plain', {'abc':'abc'}), -        mkTest("simple PUT 1", false, "PUT", false, 'text/plain', []),-        mkTest("simple DELETE 1", false, "DELETE", false, 'text/plain', []),-        mkTest("simple PATCH 1", false, "PATCH", false, 'text/plain', []),+        mkTest("simple PUT 1", false, "PUT", "simple", false, 'text/plain', []),+        mkTest("simple DELETE 1", false, "DELETE", "simple", false, 'text/plain', []),+        mkTest("simple PATCH 1", false, "PATCH", "simple", false, 'text/plain', []),     ]; +    var nonSimplePolicyTests = [+        /* are the simple requests (GET and POST) expected to succeed? */+        mkTest("nonSimplePolicy GET", true, "GET", "non-simple", false, 'text/plain', []),+        mkTest("nonSimplePolicy POST", true, "POST", "non-simple", false, 'text/plain', []),+        mkTest("nonSimplePolicy PUT", true, "PUT", "non-simple", false, 'text/plain', []),+        mkTest("nonSimplePolicy DELETE", false, "DELETE", "non-simple", false, 'text/plain', []),++        /* check presence of 'Vary: Origin' header */+        /* Currenly disabled. It seems that phantomjs doesn't support it+        {+            label: "nonSimplePolicy vary origin",+            expectedResult: true,+            method: "PUT",+            path: "non-simple",+            credentials: false,+            contentType: 'text/plain',+            headers: {},+            cors: true,+            expectedHeaders: { 'Vary' : 'Origin' }+        },+        */++        /* check that X-cors-test is accepted header */+        {+            label: "nonSimplePolicy request headers",+            expectedResult: true,+            method: "PUT",+            path: "non-simple",+            credentials: false,+            contentType: 'text/plain',+            headers: { 'X-cors-test' : 'cors-test' },+            cors: true,+            expectedHeaders : {}+        }+    ];+     $(document).ready(function() {-        var p = runAllPageTests(tests);+        var p = runAllPageTests(simpleTests.concat(nonSimplePolicyTests));         var q = websocketTest();         var r = asyncMap([p,q], function (x) { return x; });         r.always(function (x) { phantomJsCb(flattenResults(x)); });
test/phantomjs.js view
@@ -37,3 +37,8 @@         phantom.exit(0);     } }++page.onConsoleMessage = function(msg) {+    system.stderr.writeLine('[CONSOLE] ' + msg);+};+
wai-cors.cabal view
@@ -4,7 +4,7 @@ -- ------------------------------------------------------ --  Name: wai-cors-Version: 0.2.3+Version: 0.2.4 Synopsis: CORS for WAI  Description:@@ -19,10 +19,13 @@ License-file: LICENSE Author: Lars Kuhtz <lakuhtz@gmail.com> Maintainer: Lars Kuhtz <lakuhtz@gmail.com>-Copyright: (c) 2015 Lars Kuhtz <lakuhtz@gmail.com>, (c) 2014 AlephCloud Systems, Inc.-Category: Web+Copyright:+    (c) 2015 Lars Kuhtz <lakuhtz@gmail.com>,+    (c) 2014 AlephCloud Systems, Inc.+Category: HTTP, Network, Web, Yesod Build-type: Simple Cabal-version: >= 1.14.0+tested-with: GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3  data-files:     README.md@@ -40,7 +43,7 @@ source-repository this     type: git     location: https://github.com/larskuhtz/wai-cors-    tag: 0.2.3+    tag: 0.2.4  flag transformers-3     description: use transformers<0.3 (this is set automatically)@@ -125,6 +128,34 @@         buildable: False     else         build-depends:+            wai-websockets >= 3.0,+            warp >= 3.0,+            wai >= 3.0,+            websockets >= 0.9++    ghc-options: -threaded -Wall -with-rtsopts=-N++test-suite unit-tests+    type: exitcode-stdio-1.0+    default-language: Haskell2010+    main-is: UnitTests.hs+    hs-source-dirs: test++    build-depends:+        base == 4.*,+        base-unicode-symbols >= 0.2,+        http-types >= 0.8,+        tasty >= 0.10,+        tasty-hunit >= 0.9,+        wai-cors++    -- we only build the tests suite with the most recent wai version+    -- cabal fails to resolves the old dependencies otherwise.+    if flag (wai-1) || flag (wai-2)+        buildable: False+    else+        build-depends:+            wai-extra >= 3.0,             wai-websockets >= 3.0,             warp >= 3.0,             wai >= 3.0,