1
0
forked from GitHub/gf-core

make it possible to download larger files but incremental upload

This commit is contained in:
Krasimir Angelov
2023-09-07 15:04:34 +02:00
parent 91681088ca
commit d065e1de66

View File

@@ -1,5 +1,5 @@
-- | GF server mode -- | GF server mode
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP, ScopedTypeVariables #-}
module GF.Server(GF.Server.server) where module GF.Server(GF.Server.server) where
import Data.List(partition,stripPrefix,isInfixOf) import Data.List(partition,stripPrefix,isInfixOf)
@@ -10,8 +10,10 @@ import Control.Monad.State(StateT(..),get,gets,put)
import Control.Monad.Except(ExceptT(..),runExceptT) import Control.Monad.Except(ExceptT(..),runExceptT)
import System.Random(randomRIO) import System.Random(randomRIO)
import GF.System.Catch(try) import GF.System.Catch(try)
import Control.Exception(bracket_) import Control.Exception(bracket,bracket_,catch,throw)
import System.IO.Error(isAlreadyExistsError) import System.IO (openFile,IOMode(ReadMode),hGetBuf,hFileSize,hClose)
import System.IO.Error(isAlreadyExistsError,isDoesNotExistError)
import Foreign(allocaBytes)
import GF.System.Directory(doesDirectoryExist,doesFileExist,createDirectory, import GF.System.Directory(doesDirectoryExist,doesFileExist,createDirectory,
setCurrentDirectory,getCurrentDirectory, setCurrentDirectory,getCurrentDirectory,
getDirectoryContents,removeFile,removeDirectory, getDirectoryContents,removeFile,removeDirectory,
@@ -118,8 +120,7 @@ handle logLn documentroot state0 cache execute stateVar conn = do
(_ ,_ ,".pgf") -> PS.pgfMain logLn conn cache [("PATH_TRANSLATED",path)] rq (_ ,_ ,".pgf") -> PS.pgfMain logLn conn cache [("PATH_TRANSLATED",path)] rq
(_ ,_ ,".ngf") -> PS.pgfMain logLn conn cache [("PATH_TRANSLATED",path)] rq (_ ,_ ,".ngf") -> PS.pgfMain logLn conn cache [("PATH_TRANSLATED",path)] rq
(dir,"grammars.cgi",_ ) -> addDate (grammarList dir query) (dir,"grammars.cgi",_ ) -> addDate (grammarList dir query)
_ -> do rsp <- serveStaticFile rpath path _ -> serveStaticFile conn rpath path
respondHTTP conn rsp
_ -> addDate (return $ resp400 upath) _ -> addDate (return $ resp400 upath)
where where
addDate m = addDate m =
@@ -196,7 +197,6 @@ handle logLn documentroot state0 cache execute stateVar conn = do
"ls" -> jsonList . fromMaybe ".json" . lookup "ext" =<< get_qs "ls" -> jsonList . fromMaybe ".json" . lookup "ext" =<< get_qs
"ls-l" -> jsonListLong . fromMaybe ".json" . lookup "ext" =<< get_qs "ls-l" -> jsonListLong . fromMaybe ".json" . lookup "ext" =<< get_qs
"rm" -> rm =<< look_file "rm" -> rm =<< look_file
"download" -> download =<< look_file
"link_directories" -> link_directories dir =<< look "newdir" "link_directories" -> link_directories dir =<< look "newdir"
_ -> err $ resp400 $ "cloud command "++cmd _ -> err $ resp400 $ "cloud command "++cmd
@@ -248,8 +248,6 @@ handle logLn documentroot state0 cache execute stateVar conn = do
else err $ resp404 path else err $ resp404 path
rm path = err $ resp400 $ "unacceptable extension "++path rm path = err $ resp400 $ "unacceptable extension "++path
download path = liftIO $ serveStaticFile' path
link_directories olddir newdir@('/':'t':'m':'p':'/':_) | old/=new = link_directories olddir newdir@('/':'t':'m':'p':'/':_) | old/=new =
hmInDir ".." $ liftIO $ hmInDir ".." $ liftIO $
do logPutStrLn =<< getCurrentDirectory do logPutStrLn =<< getCurrentDirectory
@@ -301,27 +299,43 @@ jsonresult cwd dir cmd (ecode,stdout,stderr) files =
-- * Static content -- * Static content
serveStaticFile rpath path = serveStaticFile conn rpath path =
do b <- doesDirectoryExist path do b <- doesDirectoryExist path
if b if b
then if rpath `elem` ["","."] || last path=='/' then if rpath `elem` ["","."] || last path=='/'
then serveStaticFile' (path </> "index.html") then serveStaticFile' conn (path </> "index.html")
else return (resp301 ('/':rpath++"/")) else respondHTTP conn (resp301 ('/':rpath++"/"))
else serveStaticFile' path else serveStaticFile' conn path
serveStaticFile' path = serveStaticFile' conn path =
do let ext = takeExtension path do let ext = takeExtension path
(t,rdFile) = contentTypeFromExt ext t = contentTypeFromExt ext
if ext `elem` [".cgi",".fcgi",".sh",".php"] if ext `elem` [".cgi",".fcgi",".sh",".php"]
then return $ resp400 $ "Unsupported file type: "++ext then respondHTTP conn $ resp400 $ "Unsupported file type: "++ext
else do b <- doesFileExist path else (bracket (openFile path ReadMode) hClose $ \h -> do
if b then do time <- getModificationTime path size <- hFileSize h
let fmt = formatTime defaultTimeLocale rfc822DateFormat time time <- getModificationTime path
body <- rdFile path let fmt = formatTime defaultTimeLocale rfc822DateFormat time
return (insertHeader HdrDate fmt (ok200' (ct t "") body)) writeHeaders conn (insertHeader HdrContentLength (show size) $
else do cwd <- getCurrentDirectory insertHeader HdrDate fmt $
logPutStrLn $ "Not found: "++path++" cwd="++cwd ok200' (ct t "") "")
return (resp404 path) allocaBytes buf_size $ transmit h conn size)
`catch`
(\(e :: IOError) ->
if isDoesNotExistError e
then do cwd <- getCurrentDirectory
logPutStrLn $ "Not found: "++path++" cwd="++cwd
respondHTTP conn (resp404 path)
else throw e)
where
buf_size = 4096
transmit h conn 0 buf = return ()
transmit h conn size buf = do
n <- hGetBuf h buf buf_size
writeBytes conn buf n
transmit h conn (size-fromIntegral n) buf
-- * Logging -- * Logging
logPutStrLn s = ePutStrLn s logPutStrLn s = ePutStrLn s
@@ -374,8 +388,8 @@ contentTypeFromExt ext =
".jpg" -> bin "image/jpg" ".jpg" -> bin "image/jpg"
_ -> bin "application/octet-stream" _ -> bin "application/octet-stream"
where where
text subtype = ("text/"++subtype++"; charset=UTF-8",readFile) text subtype = "text/"++subtype++"; charset=UTF-8"
bin t = (t,readBinaryFile) bin t = t
-- * IO utilities -- * IO utilities
updateFile path new = updateFile path new =