{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
module Network.HTTP.Types.Header (
Header,
HeaderName,
RequestHeaders,
ResponseHeaders,
hAccept,
hAcceptCharset,
hAcceptEncoding,
hAcceptLanguage,
hAcceptRanges,
hAge,
hAllow,
hAuthorization,
hCacheControl,
hConnection,
hContentDisposition,
hContentEncoding,
hContentLanguage,
hContentLength,
hContentLocation,
hContentMD5,
hContentRange,
hContentType,
hCookie,
hDate,
hETag,
hExpect,
hExpires,
hFrom,
hHost,
hIfMatch,
hIfModifiedSince,
hIfNoneMatch,
hIfRange,
hIfUnmodifiedSince,
hLastModified,
hLocation,
hMaxForwards,
hMIMEVersion,
hOrigin,
hPragma,
hPrefer,
hPreferenceApplied,
hProxyAuthenticate,
hProxyAuthorization,
hRange,
hReferer,
hRetryAfter,
hServer,
hSetCookie,
hTE,
hTrailer,
hTransferEncoding,
hUpgrade,
hUserAgent,
hVary,
hVia,
hWWWAuthenticate,
hWarning,
ByteRange (..),
renderByteRangeBuilder,
renderByteRange,
ByteRanges,
renderByteRangesBuilder,
renderByteRanges,
parseByteRanges,
)
where
import qualified Data.ByteString as B
import qualified Data.ByteString.Builder as B
import qualified Data.ByteString.Char8 as B8
import qualified Data.ByteString.Lazy as BL
import qualified Data.CaseInsensitive as CI
import Data.Data (Data)
import Data.List (intersperse)
#if __GLASGOW_HASKELL__ < 710
import Data.Monoid
#endif
import Data.Typeable (Typeable)
import GHC.Generics (Generic)
type = (HeaderName, B.ByteString)
type = CI.CI B.ByteString
type = [Header]
type = [Header]
hAccept :: HeaderName
hAccept :: CI ByteString
hAccept = CI ByteString
"Accept"
hAcceptCharset :: HeaderName
hAcceptCharset :: CI ByteString
hAcceptCharset = CI ByteString
"Accept-Charset"
hAcceptEncoding :: HeaderName
hAcceptEncoding :: CI ByteString
hAcceptEncoding = CI ByteString
"Accept-Encoding"
hAcceptLanguage :: HeaderName
hAcceptLanguage :: CI ByteString
hAcceptLanguage = CI ByteString
"Accept-Language"
hAcceptRanges :: HeaderName
hAcceptRanges :: CI ByteString
hAcceptRanges = CI ByteString
"Accept-Ranges"
hAge :: HeaderName
hAge :: CI ByteString
hAge = CI ByteString
"Age"
hAllow :: HeaderName
hAllow :: CI ByteString
hAllow = CI ByteString
"Allow"
hAuthorization :: HeaderName
hAuthorization :: CI ByteString
hAuthorization = CI ByteString
"Authorization"
hCacheControl :: HeaderName
hCacheControl :: CI ByteString
hCacheControl = CI ByteString
"Cache-Control"
hConnection :: HeaderName
hConnection :: CI ByteString
hConnection = CI ByteString
"Connection"
hContentEncoding :: HeaderName
hContentEncoding :: CI ByteString
hContentEncoding = CI ByteString
"Content-Encoding"
hContentLanguage :: HeaderName
hContentLanguage :: CI ByteString
hContentLanguage = CI ByteString
"Content-Language"
hContentLength :: HeaderName
hContentLength :: CI ByteString
hContentLength = CI ByteString
"Content-Length"
hContentLocation :: HeaderName
hContentLocation :: CI ByteString
hContentLocation = CI ByteString
"Content-Location"
hContentMD5 :: HeaderName
hContentMD5 :: CI ByteString
hContentMD5 = CI ByteString
"Content-MD5"
hContentRange :: HeaderName
hContentRange :: CI ByteString
hContentRange = CI ByteString
"Content-Range"
hContentType :: HeaderName
hContentType :: CI ByteString
hContentType = CI ByteString
"Content-Type"
hDate :: HeaderName
hDate :: CI ByteString
hDate = CI ByteString
"Date"
hETag :: HeaderName
hETag :: CI ByteString
hETag = CI ByteString
"ETag"
hExpect :: HeaderName
hExpect :: CI ByteString
hExpect = CI ByteString
"Expect"
hExpires :: HeaderName
hExpires :: CI ByteString
hExpires = CI ByteString
"Expires"
hFrom :: HeaderName
hFrom :: CI ByteString
hFrom = CI ByteString
"From"
hHost :: HeaderName
hHost :: CI ByteString
hHost = CI ByteString
"Host"
hIfMatch :: HeaderName
hIfMatch :: CI ByteString
hIfMatch = CI ByteString
"If-Match"
hIfModifiedSince :: HeaderName
hIfModifiedSince :: CI ByteString
hIfModifiedSince = CI ByteString
"If-Modified-Since"
hIfNoneMatch :: HeaderName
hIfNoneMatch :: CI ByteString
hIfNoneMatch = CI ByteString
"If-None-Match"
hIfRange :: HeaderName
hIfRange :: CI ByteString
hIfRange = CI ByteString
"If-Range"
hIfUnmodifiedSince :: HeaderName
hIfUnmodifiedSince :: CI ByteString
hIfUnmodifiedSince = CI ByteString
"If-Unmodified-Since"
hLastModified :: HeaderName
hLastModified :: CI ByteString
hLastModified = CI ByteString
"Last-Modified"
hLocation :: HeaderName
hLocation :: CI ByteString
hLocation = CI ByteString
"Location"
hMaxForwards :: HeaderName
hMaxForwards :: CI ByteString
hMaxForwards = CI ByteString
"Max-Forwards"
hPragma :: HeaderName
hPragma :: CI ByteString
hPragma = CI ByteString
"Pragma"
hProxyAuthenticate :: HeaderName
hProxyAuthenticate :: CI ByteString
hProxyAuthenticate = CI ByteString
"Proxy-Authenticate"
hProxyAuthorization :: HeaderName
hProxyAuthorization :: CI ByteString
hProxyAuthorization = CI ByteString
"Proxy-Authorization"
hRange :: HeaderName
hRange :: CI ByteString
hRange = CI ByteString
"Range"
hReferer :: HeaderName
hReferer :: CI ByteString
hReferer = CI ByteString
"Referer"
hRetryAfter :: HeaderName
hRetryAfter :: CI ByteString
hRetryAfter = CI ByteString
"Retry-After"
hServer :: HeaderName
hServer :: CI ByteString
hServer = CI ByteString
"Server"
hTE :: HeaderName
hTE :: CI ByteString
hTE = CI ByteString
"TE"
hTrailer :: HeaderName
hTrailer :: CI ByteString
hTrailer = CI ByteString
"Trailer"
hTransferEncoding :: HeaderName
hTransferEncoding :: CI ByteString
hTransferEncoding = CI ByteString
"Transfer-Encoding"
hUpgrade :: HeaderName
hUpgrade :: CI ByteString
hUpgrade = CI ByteString
"Upgrade"
hUserAgent :: HeaderName
hUserAgent :: CI ByteString
hUserAgent = CI ByteString
"User-Agent"
hVary :: HeaderName
hVary :: CI ByteString
hVary = CI ByteString
"Vary"
hVia :: HeaderName
hVia :: CI ByteString
hVia = CI ByteString
"Via"
hWWWAuthenticate :: HeaderName
hWWWAuthenticate :: CI ByteString
hWWWAuthenticate = CI ByteString
"WWW-Authenticate"
hWarning :: HeaderName
hWarning :: CI ByteString
hWarning = CI ByteString
"Warning"
hContentDisposition :: HeaderName
hContentDisposition :: CI ByteString
hContentDisposition = CI ByteString
"Content-Disposition"
hMIMEVersion :: HeaderName
hMIMEVersion :: CI ByteString
hMIMEVersion = CI ByteString
"MIME-Version"
hCookie :: HeaderName
hCookie :: CI ByteString
hCookie = CI ByteString
"Cookie"
hSetCookie :: HeaderName
hSetCookie :: CI ByteString
hSetCookie = CI ByteString
"Set-Cookie"
hOrigin :: HeaderName
hOrigin :: CI ByteString
hOrigin = CI ByteString
"Origin"
hPrefer :: HeaderName
hPrefer :: CI ByteString
hPrefer = CI ByteString
"Prefer"
hPreferenceApplied :: HeaderName
hPreferenceApplied :: CI ByteString
hPreferenceApplied = CI ByteString
"Preference-Applied"
data ByteRange
= ByteRangeFrom !Integer
| ByteRangeFromTo !Integer !Integer
| ByteRangeSuffix !Integer
deriving
(
Int -> ByteRange -> ShowS
[ByteRange] -> ShowS
ByteRange -> String
(Int -> ByteRange -> ShowS)
-> (ByteRange -> String)
-> ([ByteRange] -> ShowS)
-> Show ByteRange
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ByteRange -> ShowS
showsPrec :: Int -> ByteRange -> ShowS
$cshow :: ByteRange -> String
show :: ByteRange -> String
$cshowList :: [ByteRange] -> ShowS
showList :: [ByteRange] -> ShowS
Show
,
ByteRange -> ByteRange -> Bool
(ByteRange -> ByteRange -> Bool)
-> (ByteRange -> ByteRange -> Bool) -> Eq ByteRange
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ByteRange -> ByteRange -> Bool
== :: ByteRange -> ByteRange -> Bool
$c/= :: ByteRange -> ByteRange -> Bool
/= :: ByteRange -> ByteRange -> Bool
Eq
,
Eq ByteRange
Eq ByteRange =>
(ByteRange -> ByteRange -> Ordering)
-> (ByteRange -> ByteRange -> Bool)
-> (ByteRange -> ByteRange -> Bool)
-> (ByteRange -> ByteRange -> Bool)
-> (ByteRange -> ByteRange -> Bool)
-> (ByteRange -> ByteRange -> ByteRange)
-> (ByteRange -> ByteRange -> ByteRange)
-> Ord ByteRange
ByteRange -> ByteRange -> Bool
ByteRange -> ByteRange -> Ordering
ByteRange -> ByteRange -> ByteRange
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: ByteRange -> ByteRange -> Ordering
compare :: ByteRange -> ByteRange -> Ordering
$c< :: ByteRange -> ByteRange -> Bool
< :: ByteRange -> ByteRange -> Bool
$c<= :: ByteRange -> ByteRange -> Bool
<= :: ByteRange -> ByteRange -> Bool
$c> :: ByteRange -> ByteRange -> Bool
> :: ByteRange -> ByteRange -> Bool
$c>= :: ByteRange -> ByteRange -> Bool
>= :: ByteRange -> ByteRange -> Bool
$cmax :: ByteRange -> ByteRange -> ByteRange
max :: ByteRange -> ByteRange -> ByteRange
$cmin :: ByteRange -> ByteRange -> ByteRange
min :: ByteRange -> ByteRange -> ByteRange
Ord
,
Typeable
,
Typeable ByteRange
Typeable ByteRange =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ByteRange -> c ByteRange)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ByteRange)
-> (ByteRange -> Constr)
-> (ByteRange -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ByteRange))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ByteRange))
-> ((forall b. Data b => b -> b) -> ByteRange -> ByteRange)
-> (forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ByteRange -> r)
-> (forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ByteRange -> r)
-> (forall u. (forall d. Data d => d -> u) -> ByteRange -> [u])
-> (forall u.
Int -> (forall d. Data d => d -> u) -> ByteRange -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ByteRange -> m ByteRange)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ByteRange -> m ByteRange)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ByteRange -> m ByteRange)
-> Data ByteRange
ByteRange -> Constr
ByteRange -> DataType
(forall b. Data b => b -> b) -> ByteRange -> ByteRange
forall a.
Typeable a =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ByteRange -> u
forall u. (forall d. Data d => d -> u) -> ByteRange -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ByteRange -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ByteRange -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ByteRange -> m ByteRange
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ByteRange -> m ByteRange
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ByteRange
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ByteRange -> c ByteRange
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ByteRange)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ByteRange)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ByteRange -> c ByteRange
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ByteRange -> c ByteRange
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ByteRange
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ByteRange
$ctoConstr :: ByteRange -> Constr
toConstr :: ByteRange -> Constr
$cdataTypeOf :: ByteRange -> DataType
dataTypeOf :: ByteRange -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ByteRange)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ByteRange)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ByteRange)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ByteRange)
$cgmapT :: (forall b. Data b => b -> b) -> ByteRange -> ByteRange
gmapT :: (forall b. Data b => b -> b) -> ByteRange -> ByteRange
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ByteRange -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ByteRange -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ByteRange -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ByteRange -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ByteRange -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> ByteRange -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ByteRange -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ByteRange -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ByteRange -> m ByteRange
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ByteRange -> m ByteRange
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ByteRange -> m ByteRange
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ByteRange -> m ByteRange
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ByteRange -> m ByteRange
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ByteRange -> m ByteRange
Data
,
(forall x. ByteRange -> Rep ByteRange x)
-> (forall x. Rep ByteRange x -> ByteRange) -> Generic ByteRange
forall x. Rep ByteRange x -> ByteRange
forall x. ByteRange -> Rep ByteRange x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ByteRange -> Rep ByteRange x
from :: forall x. ByteRange -> Rep ByteRange x
$cto :: forall x. Rep ByteRange x -> ByteRange
to :: forall x. Rep ByteRange x -> ByteRange
Generic
)
renderByteRangeBuilder :: ByteRange -> B.Builder
renderByteRangeBuilder :: ByteRange -> Builder
renderByteRangeBuilder (ByteRangeFrom Integer
from) = Integer -> Builder
B.integerDec Integer
from Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
`mappend` Char -> Builder
B.char7 Char
'-'
renderByteRangeBuilder (ByteRangeFromTo Integer
from Integer
to) = Integer -> Builder
B.integerDec Integer
from Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
`mappend` Char -> Builder
B.char7 Char
'-' Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
`mappend` Integer -> Builder
B.integerDec Integer
to
renderByteRangeBuilder (ByteRangeSuffix Integer
suffix) = Char -> Builder
B.char7 Char
'-' Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
`mappend` Integer -> Builder
B.integerDec Integer
suffix
renderByteRange :: ByteRange -> B.ByteString
renderByteRange :: ByteRange -> ByteString
renderByteRange = LazyByteString -> ByteString
BL.toStrict (LazyByteString -> ByteString)
-> (ByteRange -> LazyByteString) -> ByteRange -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyByteString
B.toLazyByteString (Builder -> LazyByteString)
-> (ByteRange -> Builder) -> ByteRange -> LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteRange -> Builder
renderByteRangeBuilder
type ByteRanges = [ByteRange]
renderByteRangesBuilder :: ByteRanges -> B.Builder
renderByteRangesBuilder :: [ByteRange] -> Builder
renderByteRangesBuilder [ByteRange]
xs =
ByteString -> Builder
B.byteString ByteString
"bytes="
Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
`mappend` [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat (Builder -> [Builder] -> [Builder]
forall a. a -> [a] -> [a]
intersperse (Char -> Builder
B.char7 Char
',') ([Builder] -> [Builder]) -> [Builder] -> [Builder]
forall a b. (a -> b) -> a -> b
$ (ByteRange -> Builder) -> [ByteRange] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map ByteRange -> Builder
renderByteRangeBuilder [ByteRange]
xs)
renderByteRanges :: ByteRanges -> B.ByteString
renderByteRanges :: [ByteRange] -> ByteString
renderByteRanges = LazyByteString -> ByteString
BL.toStrict (LazyByteString -> ByteString)
-> ([ByteRange] -> LazyByteString) -> [ByteRange] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyByteString
B.toLazyByteString (Builder -> LazyByteString)
-> ([ByteRange] -> Builder) -> [ByteRange] -> LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteRange] -> Builder
renderByteRangesBuilder
parseByteRanges :: B.ByteString -> Maybe ByteRanges
parseByteRanges :: ByteString -> Maybe [ByteRange]
parseByteRanges ByteString
bs1 = do
bs2 <- ByteString -> ByteString -> Maybe ByteString
stripPrefixB ByteString
"bytes=" ByteString
bs1
(r, bs3) <- range bs2
ranges (r :) bs3
where
range :: ByteString -> Maybe (ByteRange, ByteString)
range ByteString
bs2 = do
(i, bs3) <- ByteString -> Maybe (Integer, ByteString)
B8.readInteger ByteString
bs2
if i < 0
then Just (ByteRangeSuffix (negate i), bs3)
else do
bs4 <- stripPrefixB "-" bs3
case B8.readInteger bs4 of
Just (Integer
j, ByteString
bs5) | Integer
j Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
i -> (ByteRange, ByteString) -> Maybe (ByteRange, ByteString)
forall a. a -> Maybe a
Just (Integer -> Integer -> ByteRange
ByteRangeFromTo Integer
i Integer
j, ByteString
bs5)
Maybe (Integer, ByteString)
_ -> (ByteRange, ByteString) -> Maybe (ByteRange, ByteString)
forall a. a -> Maybe a
Just (Integer -> ByteRange
ByteRangeFrom Integer
i, ByteString
bs4)
ranges :: ([ByteRange] -> t) -> ByteString -> Maybe t
ranges [ByteRange] -> t
front ByteString
bs3
| ByteString -> Bool
B.null ByteString
bs3 = t -> Maybe t
forall a. a -> Maybe a
Just ([ByteRange] -> t
front [])
| Bool
otherwise = do
bs4 <- ByteString -> ByteString -> Maybe ByteString
stripPrefixB ByteString
"," ByteString
bs3
(r, bs5) <- range bs4
ranges (front . (r :)) bs5
stripPrefixB :: ByteString -> ByteString -> Maybe ByteString
stripPrefixB ByteString
x ByteString
y
| ByteString
x ByteString -> ByteString -> Bool
`B.isPrefixOf` ByteString
y = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Int -> ByteString -> ByteString
B.drop (ByteString -> Int
B.length ByteString
x) ByteString
y)
| Bool
otherwise = Maybe ByteString
forall a. Maybe a
Nothing