1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
{-# LANGUAGE OverloadedStrings, FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies, DeriveDataTypeable #-}
module Network.HTTP.Types.Header
(
-- ** Types
Header
, HeaderName
, RequestHeaders
, ResponseHeaders
-- ** Common headers
, hAccept
, hAcceptLanguage
, hAuthorization
, hCacheControl
, hCookie
, hConnection
, hContentEncoding
, hContentLength
, hContentMD5
, hContentType
, hDate
, hIfModifiedSince
, hIfRange
, hLastModified
, hLocation
, hRange
, hReferer
, hServer
, hUserAgent
-- ** Byte ranges
, ByteRange(..)
, renderByteRangeBuilder
, renderByteRange
, ByteRanges
, renderByteRangesBuilder
, renderByteRanges
)
where
import Data.List
import Data.Monoid
import qualified Blaze.ByteString.Builder as Blaze
import qualified Blaze.ByteString.Builder.Char8 as Blaze
import qualified Data.ByteString as B
import qualified Data.CaseInsensitive as CI
import Data.ByteString.Char8 () {-IsString-}
import Data.Typeable (Typeable)
import Data.Data (Data)
-- | Header
type Header = (HeaderName, B.ByteString)
-- | Header name
type HeaderName = CI.CI B.ByteString
-- | Request Headers
type RequestHeaders = [Header]
-- | Response Headers
type ResponseHeaders = [Header]
-- | HTTP Header names
hAccept, hAcceptLanguage, hAuthorization, hCacheControl, hConnection, hContentEncoding, hContentLength, hContentMD5, hContentType, hCookie, hDate, hIfModifiedSince, hIfRange, hLastModified, hLocation, hRange, hReferer, hServer, hUserAgent :: HeaderName
hAccept = "Accept"
hAcceptLanguage = "Accept-Language"
hAuthorization = "Authorization"
hCacheControl = "Cache-Control"
hConnection = "Connection"
hContentEncoding = "Content-Encoding"
hContentLength = "Content-Length"
hContentMD5 = "Content-MD5"
hContentType = "Content-Type"
hCookie = "Cookie"
hDate = "Date"
hIfModifiedSince = "If-Modified-Since"
hIfRange = "If-Range"
hLastModified = "Last-Modified"
hLocation = "Location"
hRange = "Range"
hReferer = "Referer"
hServer = "Server"
hUserAgent = "User-Agent"
-- | RFC 2616 Byte range (individual).
--
-- Negative indices are not allowed!
data ByteRange
= ByteRangeFrom !Integer
| ByteRangeFromTo !Integer !Integer
| ByteRangeSuffix !Integer
deriving (Show, Eq, Ord, Typeable, Data)
renderByteRangeBuilder :: ByteRange -> Blaze.Builder
renderByteRangeBuilder (ByteRangeFrom from) = Blaze.fromShow from `mappend` Blaze.fromChar '-'
renderByteRangeBuilder (ByteRangeFromTo from to) = Blaze.fromShow from `mappend` Blaze.fromChar '-' `mappend` Blaze.fromShow to
renderByteRangeBuilder (ByteRangeSuffix suffix) = Blaze.fromChar '-' `mappend` Blaze.fromShow suffix
renderByteRange :: ByteRange -> B.ByteString
renderByteRange = Blaze.toByteString . renderByteRangeBuilder
-- | RFC 2616 Byte ranges (set).
type ByteRanges = [ByteRange]
renderByteRangesBuilder :: ByteRanges -> Blaze.Builder
renderByteRangesBuilder xs = Blaze.copyByteString "bytes=" `mappend`
mconcat (intersperse (Blaze.fromChar ',') (map renderByteRangeBuilder xs))
renderByteRanges :: ByteRanges -> B.ByteString
renderByteRanges = Blaze.toByteString . renderByteRangesBuilder
|