{-# LANGUAGE OverloadedStrings #-}{-# LANGUAGE CPP #-}moduleYesod.Internal.Request(parseWaiRequest,Request(..),RequestBodyContents,FileInfo(..)-- The below are exported for testing.,randomString,parseWaiRequest')whereimportControl.Applicative((<$>))importControl.Arrow(second)importqualifiedNetwork.Wai.ParseasNWPimportYesod.InternalimportqualifiedNetwork.WaiasWimportSystem.Random(RandomGen,newStdGen,randomRs)importWeb.Cookie(parseCookiesText)importData.ByteString(ByteString)importqualifiedData.ByteString.Char8asS8importData.Text(Text,pack)importNetwork.HTTP.Types(queryToQueryText)importControl.Monad(join)importData.Maybe(fromMaybe,catMaybes)importqualifiedData.ByteString.LazyasLimportqualifiedData.SetasSetimportqualifiedData.TextasTimportData.Text.Encoding(decodeUtf8With)importData.Text.Encoding.Error(lenientDecode)-- | The parsed request information.dataRequest=Request{reqGetParams::[(Text,Text)],reqCookies::[(Text,Text)],reqWaiRequest::W.Request-- | Languages which the client supports.,reqLangs::[Text]-- | A random, session-specific token used to prevent CSRF attacks.,reqToken::MaybeText}parseWaiRequest::W.Request->[(Text,ByteString)]-- ^ session->Bool->IORequestparseWaiRequestenvsession'useToken=parseWaiRequest'envsession'useToken<$>newStdGenparseWaiRequest'::RandomGeng=>W.Request->[(Text,ByteString)]-- ^ session->Bool->g->RequestparseWaiRequest'envsession'useTokengen=Requestgets''cookies'envlangs''tokenwheregets'=queryToQueryText$W.queryStringenvgets''=map(second$fromMaybe"")gets'reqCookie=lookup"Cookie"$W.requestHeadersenvcookies'=maybe[]parseCookiesTextreqCookieacceptLang=lookup"Accept-Language"$W.requestHeadersenvlangs=map(pack.S8.unpack)$maybe[]NWP.parseHttpAcceptacceptLanglookupTextk=fmap(decodeUtf8WithlenientDecode).lookupk-- The language preferences are prioritized as follows:langs'=catMaybes[join$lookuplangKeygets'-- Query _LANG,lookuplangKeycookies'-- Cookie _LANG,lookupTextlangKeysession'-- Session _LANG]++langs-- Accept-Language(s)-- Github issue #195. We want to add an extra two-letter version of any-- language in the list.langs''=addTwoLetters(id,Set.empty)langs'-- If sessions are disabled tokens should not be used (any-- tokenKey present in the session is ignored). If sessions-- are enabled and a session has no tokenKey a new one is-- generated.token=ifnotuseTokenthenNothingelseJust$maybe(pack$randomString10gen)(decodeUtf8WithlenientDecode)(lookuptokenKeysession')addTwoLetters::([Text]->[Text],Set.SetText)->[Text]->[Text]addTwoLetters(toAdd,exist)[]=filter(flipSet.notMemberexist)$toAdd[]addTwoLetters(toAdd,exist)(l:ls)=l:addTwoLetters(toAdd',exist')lswhere(toAdd',exist')|T.lengthl>2=(toAdd.(T.take2l:),exist)|otherwise=(toAdd,Set.insertlexist)-- | Generate a random String of alphanumerical characters-- (a-z, A-Z, and 0-9) of the given length using the given-- random number generator.randomString::RandomGeng=>Int->g->StringrandomStringlen=takelen.maptoChar.randomRs(0,61)wheretoChari|i<26=toEnum$i+fromEnum'A'|i<52=toEnum$i+fromEnum'a'-26|otherwise=toEnum$i+fromEnum'0'-52-- | A tuple containing both the POST parameters and submitted files.typeRequestBodyContents=([(Text,Text)],[(Text,FileInfo)])dataFileInfo=FileInfo{fileName::Text,fileContentType::Text,fileContent::L.ByteString}deriving(Eq,Show)