{-# LANGUAGE OverloadedStrings #-} module Network.HTTP.Attoparsec ( byteRangesParser, parseByteRanges ) where import Network.HTTP.Types.Header import qualified Data.ByteString as B import qualified Data.Attoparsec.ByteString.Char8 as A8 import Control.Applicative ((<|>), (<$>)) byteRangesParser :: A8.Parser ByteRanges byteRangesParser = do _ <- A8.string "bytes=" br <- range rest <- maybeMoreRanges return $ br:rest where range = rangeFromTo <|> rangeSuffix rangeFromTo = do f <- A8.decimal _ <- A8.char '-' mt <- Just <$> A8.decimal <|> return Nothing return $ case mt of Just t -> ByteRangeFromTo f t Nothing -> ByteRangeFrom f rangeSuffix = do _ <- A8.char '-' s <- A8.decimal return $ ByteRangeSuffix s maybeMoreRanges = moreRanges <|> return [] moreRanges = do _ <- A8.char ',' r <- range rest <- maybeMoreRanges return $ r:rest parseByteRanges :: B.ByteString -> Maybe ByteRanges parseByteRanges bs = case A8.parseOnly byteRangesParser bs of Left _ -> Nothing Right br -> Just br