snap-cors 1.0.1 → 1.1.0
raw patch · 3 files changed
+33/−4 lines, 3 filesdep +bytestringdep +case-insensitive
Dependencies added: bytestring, case-insensitive
Files
- Changelog.md +4/−0
- snap-cors.cabal +7/−1
- src/Snap/CORS.hs +22/−3
Changelog.md view
@@ -1,3 +1,7 @@+# 1.1++* It is now possible to specify `Access-Control-Expose-Headers`+ # 1.0.1 * Allow `hashable` 1.2
snap-cors.cabal view
@@ -1,5 +1,5 @@ name: snap-cors-version: 1.0.1+version: 1.1.0 synopsis: Add CORS headers to Snap applications description: Add CORS (cross-origin resource sharing) headers to Snap applications. This@@ -23,12 +23,18 @@ extra-source-files: Changelog.md +source-repository head+ type: git+ location: git://github.com/ocharles/snap-cors.git+ library hs-source-dirs: src exposed-modules: Snap.CORS build-depends: base >= 4.5 && < 5,+ bytestring >= 0.10 && < 0.11,+ case-insensitive >= 1.0 && <1.1, hashable >= 1.1 && <1.3, network >= 2.4 && < 2.5, snap >= 0.13 && < 0.14,
src/Snap/CORS.hs view
@@ -27,10 +27,13 @@ import Control.Monad (guard, mzero, void, when) import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Maybe (MaybeT(..))+import Data.CaseInsensitive (CI) import Data.Hashable (Hashable(..)) import Data.Text.Encoding (decodeUtf8, encodeUtf8) import Network.URI (URI (..), URIAuth (..), parseURI) +import qualified Data.ByteString.Char8 as Char8+import qualified Data.CaseInsensitive as CI import qualified Data.HashSet as HashSet import qualified Data.Text as Text import qualified Snap@@ -59,15 +62,25 @@ , corsAllowCredentials :: m Bool -- ^ Whether or not to allow exposing the response when the omit credentials- -- flag is unset. + -- flag is unset.++ , corsExposeHeaders :: m (HashSet.HashSet (CI Char8.ByteString))+ -- ^ A list of headers that are exposed to clients. This allows clients to+ -- read the values of these headers, if the response includes them. } --- | Liberal default options. Specifies that all origins may make cross-origin--- requests, allow-credentials is true. Headers are determined unconditionally.+-- | Liberal default options. Specifies that:+--+-- * All origins may make cross-origin requests+-- * @allow-credentials@ is true.+-- * No extra headers beyond simple headers are exposed+--+-- All options are determined unconditionally. defaultOptions :: Monad m => CORSOptions m defaultOptions = CORSOptions { corsAllowOrigin = return Everywhere , corsAllowCredentials = return True+ , corsExposeHeaders = return HashSet.empty } -- | Apply CORS for every request, unconditionally.@@ -98,11 +111,17 @@ guard (HashableURI originUri `HashSet.member` xs) lift $ do+ exposeHeaders <- corsExposeHeaders options+ addHeader "Access-Control-Allow-Origin" (encodeUtf8 $ Text.pack $ show originUri) allowCredentials <- corsAllowCredentials options when (allowCredentials) $ addHeader "Access-Control-Allow-Credentials" "true"++ when (not $ HashSet.null exposeHeaders) $+ addHeader "Access-Control-Expose-Headers" $+ Char8.intercalate ", " (map CI.original $ HashSet.toList exposeHeaders) where addHeader k v = Snap.modifyResponse (Snap.addHeader k v)