sendResponse :: ByteString -- ^ default server value
             -> Connection
             -> InternalInfo
             -> Request -- ^ HTTP request.
             -> IndexedHeader -- ^ Indexed header of HTTP request.
             -> IO ByteString -- ^ source from client, for raw response
             -> Response -- ^ HTTP response including status code and response header.
             -> IO Bool -- ^ Returing True if the connection is persistent.
sendResponse defServer conn ii req reqidxhdr src response = do
    hs <- addServerAndDate hs0
    if hasBody s req then do
        -- HEAD comes here even if it does not have body.
        sendRsp conn ver s hs rsp
        T.tickle th
        return ret
      else do
        sendResponseNoBody conn ver s hs
        T.tickle th
        return isPersist
  where
    ver = httpVersion req
    s = responseStatus response
    hs0 = responseHeaders response
    rspidxhdr = indexResponseHeader hs0
    th = threadHandle ii
    dc = dateCacher ii
    addServerAndDate = addDate dc rspidxhdr . addServer defServer rspidxhdr
    mRange = reqidxhdr ! idxRange
    (isPersist,isChunked0) = infoFromRequest req reqidxhdr
    isChunked = if isHead then False else isChunked0
    (isKeepAlive, needsChunked) = infoFromResponse rspidxhdr (isPersist,isChunked)
    isHead = requestMethod req == H.methodHead
    rsp = case response of
        ResponseFile _ _ path mPart -> RspFile path mPart mRange isHead (T.tickle th)
        ResponseBuilder _ _ b       -> RspBuilder b needsChunked
        ResponseStream _ _ fb       -> RspStream fb needsChunked th
        ResponseRaw raw _           -> RspRaw raw src (T.tickle th)
    ret = case response of
        ResponseFile    {} -> isPersist
        ResponseBuilder {} -> isKeepAlive
        ResponseStream  {} -> isKeepAlive
        ResponseRaw     {} -> False

----------------------------------------------------------------
sendResponse :: ByteString -- ^ default server value
             -> Connection
             -> InternalInfo
             -> Request -- ^ HTTP request.
             -> IndexedHeader -- ^ Indexed header of HTTP request.
             -> IO ByteString -- ^ source from client, for raw response
             -> Response -- ^ HTTP response including status code and response header.
             -> IO Bool
sendResponse defServer conn ii req reqidxhdr src response = do
    hs <- addServerAndDate hs0
    if hasBody s req then do
        -- HEAD comes here even if it does not have body.
        sendRsp conn ver s hs rsp
        T.tickle th
        return ret
      else do
        sendResponseNoBody conn ver s hs
        T.tickle th
        return isPersist
  where
    ver = httpVersion req
    s = responseStatus response
    hs0 = responseHeaders response
    rspidxhdr = indexResponseHeader hs0
    th = threadHandle ii
    dc = dateCacher ii
    addServerAndDate = addDate dc rspidxhdr . addServer defServer rspidxhdr
    mRange = reqidxhdr ! idxRange
    (isPersist,isChunked0) = infoFromRequest req reqidxhdr
    isChunked = if isHead then False else isChunked0
    (isKeepAlive, needsChunked) = infoFromResponse rspidxhdr (isPersist,isChunked)
    isHead = requestMethod req == H.methodHead
    rsp = case response of
        ResponseFile _ _ path mPart -> RspFile path mPart mRange isHead (T.tickle th)
        ResponseBuilder _ _ b       -> RspBuilder b needsChunked
        ResponseStream _ _ fb       -> RspStream fb needsChunked th
        ResponseRaw raw _           -> RspRaw raw src (T.tickle th)
    ret = case response of
        ResponseFile    {} -> isPersist
        ResponseBuilder {} -> isKeepAlive
        ResponseStream  {} -> isKeepAlive
        ResponseRaw     {} -> False

----------------------------------------------------------------
sendResponse defServer conn ii req reqidxhdr src response = do
    hs <- addServerAndDate hs0
    if hasBody s req then do
        -- HEAD comes here even if it does not have body.
        sendRsp conn ver s hs rsp
        T.tickle th
        return ret
      else do
        sendResponseNoBody conn ver s hs
        T.tickle th
        return isPersist
  where
    ver = httpVersion req
    s = responseStatus response
    hs0 = responseHeaders response
    rspidxhdr = indexResponseHeader hs0
    th = threadHandle ii
    dc = dateCacher ii
    addServerAndDate = addDate dc rspidxhdr . addServer defServer rspidxhdr
    mRange = reqidxhdr ! idxRange
    (isPersist,isChunked0) = infoFromRequest req reqidxhdr
    isChunked = if isHead then False else isChunked0
    (isKeepAlive, needsChunked) = infoFromResponse rspidxhdr (isPersist,isChunked)
    isHead = requestMethod req == H.methodHead
    rsp = case response of
        ResponseFile _ _ path mPart -> RspFile path mPart mRange isHead (T.tickle th)
        ResponseBuilder _ _ b       -> RspBuilder b needsChunked
        ResponseStream _ _ fb       -> RspStream fb needsChunked th
        ResponseRaw raw _           -> RspRaw raw src (T.tickle th)
    ret = case response of
        ResponseFile    {} -> isPersist
        ResponseBuilder {} -> isKeepAlive
        ResponseStream  {} -> isKeepAlive
        ResponseRaw     {} -> False

----------------------------------------------------------------