Add cloud services needed by gfse to "gf -server" mode

This commit is contained in:
hallgren
2011-10-10 19:46:57 +00:00
parent ad90185b4f
commit 51a15531ce

View File

@@ -7,8 +7,10 @@ import System.IO(stdout,stderr)
import System.IO.Error(try,ioError)
import System.Directory(doesDirectoryExist,doesFileExist,createDirectory,
setCurrentDirectory,getCurrentDirectory,
getDirectoryContents)
getDirectoryContents,removeFile,removeDirectory)
import System.FilePath(takeExtension,takeFileName,takeDirectory,(</>))
import System.Posix.Files(getFileStatus,isSymbolicLink,removeLink,
createSymbolicLink)
import Control.Concurrent.MVar(newMVar,modifyMVar)
import Network.URI(URI(..))
import Network.Shed.Httpd(initServer,Request(..),Response(..),queryToArguments,
@@ -50,7 +52,7 @@ handle state0 cache execute1
-- "/stop" ->
-- "/start" ->
"/gfshell" -> inDir qs $ look "command" . command
"/upload" -> inDir qs upload
"/cloud" -> inDir qs $ look "command" . cloud
'/':rpath ->
case (takeDirectory path,takeFileName path,takeExtension path) of
(_ ,_ ,".pgf") -> wrapCGI $ PS.cgiMain' cache path
@@ -97,15 +99,51 @@ handle state0 cache execute1
let state' = maybe state (flip (M.insert dir) state) st'
return (state',ok200 output)
upload dir files=
cloud dir cmd qs =
case cmd of
"upload" -> upload qs
"ls" -> jsonList
"rm" -> look "file" rm qs
"download" -> look "file" download qs
"link_directories" -> look "newdir" (link_directories dir) qs
_ -> return (state,resp400 $ "cloud command "++cmd)
upload files =
do let update (name,contents)= updateFile (name++".gf") contents
mapM_ update files
return (state,resp204)
grammarList dir =
do paths <- liftIO $ getDirectoryContents dir
let pgfs = [path|path<-paths, takeExtension path==".pgf"]
outputJSONP pgfs
jsonList =
do jsons <- ls_ext "." ".json"
return (state,ok200 (unwords jsons))
rm path _ | takeExtension path==".json" =
do b <- doesFileExist path
if b
then do removeFile path
return (state,ok200 "")
else return (state,resp404 path)
rm path _ = return (state,resp400 $ "unacceptable file "++path)
download path _ = (,) state `fmap` serveStaticFile path
link_directories olddir newdir@('/':'t':'m':'p':'/':_) _ | olddir/=newdir =
do setCurrentDirectory ".."
st <- getFileStatus old
if isSymbolicLink st then removeLink old else removeDir old
createSymbolicLink new old
return (state,ok200 "")
where
old = takeFileName olddir
new = takeFileName newdir
link_directories olddir newdir _ =
return (state,resp400 $ "unacceptable directories "++olddir++" "++newdir)
grammarList dir = outputJSONP =<< liftIO (ls_ext dir ".pgf")
ls_ext dir ext =
do paths <- getDirectoryContents dir
return [path | path<-paths, takeExtension path==ext]
-- * Static content
@@ -117,10 +155,13 @@ serveStaticFile path =
serveStaticFile' path'
serveStaticFile' path =
do b <- doesFileExist path
let (t,rdFile,encode) = contentTypeFromExt (takeExtension path)
if b then fmap (ok200' (ct t) . encode) $ rdFile path
else return (resp404 path)
do let ext = takeExtension path
(t,rdFile,encode) = contentTypeFromExt ext
if ext `elem` [".cgi",".fcgi",".sh",".php"]
then return $ resp400 $ "Unsupported file type: "++ext
else do b <- doesFileExist path
if b then fmap (ok200' (ct t) . encode) $ rdFile path
else return (resp404 path)
-- * Logging
logPutStrLn = putStrLn
@@ -168,6 +209,12 @@ newDirectory =
Left _ -> newDirectory
Right _ -> return ('/':path)
-- | Remove a directory and the files in it, but not recursively
removeDir dir =
do files <- filter (`notElem` [".",".."]) `fmap` getDirectoryContents dir
mapM (removeFile . (dir</>)) files
removeDirectory dir
-- * misc utils
decodeQ qs = [(decode n,decode v)|(n,v)<-qs]