module Network.HTTP.Lucu.Implant
( Input(..)
, originalLen
, gzippedLen
, useGZip
, openInput
)
where
import Codec.Compression.GZip
import Control.Applicative
import qualified Data.ByteString.Lazy as L
import Data.Convertible.Base
import Data.Convertible.Instances.Ascii ()
import Data.Digest.Pure.SHA
import Data.Maybe
import Data.Time
import Network.HTTP.Lucu.ETag
import Network.HTTP.Lucu.MIMEType
import Network.HTTP.Lucu.MIMEType.DefaultExtensionMap
import Network.HTTP.Lucu.MIMEType.Guess
import Network.HTTP.Lucu.Utils
import Prelude.Unicode
data Input
= Input {
iPath ∷ !FilePath
, iLastMod ∷ !UTCTime
, iType ∷ !MIMEType
, iETag ∷ !ETag
, iRawData ∷ !L.ByteString
, iGZipped ∷ !L.ByteString
}
originalLen ∷ Input → Integer
originalLen (Input {..})
= fromIntegral $ L.length iRawData
gzippedLen ∷ Input → Integer
gzippedLen (Input {..})
= fromIntegral $ L.length iGZipped
useGZip ∷ Input → Bool
useGZip i
= originalLen i ≥ gzippedLen i
openInput ∷ FilePath → Maybe MIMEType → Maybe ETag → IO Input
openInput fpath ctype etag
= do lastMod ← lastModified fpath
input ← openInputFile fpath
return Input {
iPath = fpath
, iLastMod = lastMod
, iType = fromMaybe octetStream
$ ctype <|> guessType fpath
, iETag = fromMaybe (mkETagFromInput input) etag
, iRawData = input
, iGZipped = compressWith compParams input
}
where
octetStream ∷ MIMEType
octetStream = [mimeType| application/octetstream |]
compParams ∷ CompressParams
compParams = defaultCompressParams {
compressLevel = bestCompression
}
lastModified ∷ FilePath → IO UTCTime
lastModified "-" = getCurrentTime
lastModified fpath = getLastModified fpath
openInputFile ∷ FilePath → IO L.ByteString
openInputFile "-" = L.getContents
openInputFile fpath = L.readFile fpath
guessType ∷ FilePath → Maybe MIMEType
guessType = guessTypeByFileName defaultExtensionMap
mkETagFromInput ∷ L.ByteString → ETag
mkETagFromInput input
= strongETag $ convertUnsafe
$ "SHA-1:" ⧺ showDigest (sha1 input)