Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.

Commit a2ca3eb

Browse files
committed
2 parents 648ea70 + af6b1e2 commit a2ca3eb

File tree

2 files changed

+79
-64
lines changed

2 files changed

+79
-64
lines changed

Filehandler.cabal

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ cabal-version: 1.12
77
-- hash: 810c23ddfee0d410c3632560ab726ca5db1e957ed8095989f8e2e7e554eb65f4
88

99
name: Filehandler
10-
version: 0.1.0.0
10+
version: 0.0.2
1111
description: Please see the README on GitHub at <https://github.com/githubuser/Filehandler#readme>
1212
homepage: https://github.com/githubuser/Filehandler#readme
1313
bug-reports: https://github.com/githubuser/Filehandler/issues
14-
author: Author name here
14+
author: FileFighter
1515
maintainer: [email protected]
16-
copyright: 2021 Author name here
16+
copyright: 2021 FileFighter
1717
license: BSD3
1818
license-file: LICENSE
1919
build-type: Simple

app/Main.hs

Lines changed: 76 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import qualified Data.ByteString.Char8 as S8
1616
import qualified Data.ByteString.Lazy as L
1717
import Data.CaseInsensitive
1818
import Data.Functor.Identity
19+
import Data.Maybe (fromMaybe)
1920
import qualified Data.Text as DataText
2021
import GHC.Generics
2122
import GHC.Int
@@ -32,7 +33,7 @@ import System.Environment
3233
import System.FilePath
3334
import System.IO
3435
import System.IO.Temp
35-
import Data.Maybe ( fromMaybe )
36+
import GHC.IO.Encoding (setLocaleEncoding)
3637

3738
-- | Entrypoint to our application
3839
main :: IO ()
@@ -44,6 +45,7 @@ main = do
4445
-- If we have the argument "sanity", immediately exit
4546
-- If we have no arguments, run the server
4647
-- Otherwise, error out
48+
setLocaleEncoding utf8
4749
args <- getArgs
4850
case args of
4951
["sanity"] -> putStrLn "Sanity check passed, ready to roll!"
@@ -159,74 +161,83 @@ postApi allHeaders file restUrl fileId = runReq (defaultHttpConfig {httpConfigCh
159161
download :: Application
160162
download req send = do
161163
let headers = requestHeaders req
162-
restUrl <- getRestUrl
163-
logStdOut "download"
164-
(responseBody, responseStatusCode, responseStatusMessage) <- getApi headers restUrl
165-
case responseStatusCode of
166-
200 -> do
167-
let d = (eitherDecode $ L.fromStrict responseBody) :: (Either String [RestResponseFile])
168-
case d of
169-
Left err ->
170-
send $
171-
responseLBS
172-
HttpTypes.status501
173-
[("Content-Type", "application/json; charset=utf-8")]
174-
(L.fromStrict $ S8.pack err)
175-
Right files ->
176-
case files of
177-
[fileObject] -> do
178-
let fileID = fileSystemId fileObject
179-
path = getPathFromFileId $ show fileID
180-
realName = name fileObject
181-
fileMimeType = fromMaybe "application/octet-stream" (mimeType fileObject)
182-
send $
183-
responseFile
184-
HttpTypes.status200
185-
[ ("Content-Disposition", S8.pack ("attachment; filename=\"" ++ realName ++ "\"")),
186-
("Content-Type", S8.pack fileMimeType)
187-
]
188-
path
189-
Nothing
190-
xs ->
191-
withSystemTempFile "FileFighterFileHandler.zip" $
192-
\tmpFileName handle ->
193-
do
194-
let nameOfTheFolder = "NameOfTheFolderToDownload.zip"
195-
let ss =
196-
mapM
197-
( \file -> do
198-
inZipPath <- mkEntrySelector $ fromMaybe (name file) (path file)
199-
loadEntry Store inZipPath (getPathFromFileId (show $ fileSystemId file))
200-
)
201-
xs
202-
createArchive tmpFileName ss
203-
send $
204-
responseFile
205-
HttpTypes.status200
206-
[ ("Content-Disposition", S8.pack ("attachment; filename=\"" ++ nameOfTheFolder ++ "\"")),
207-
("Content-Type", "application/zip")
208-
]
209-
tmpFileName
210-
Nothing
211-
_ ->
164+
queryParam = getDownloadQuery $ queryString req
165+
case queryParam of
166+
Nothing ->
212167
send $
213168
responseLBS
214-
(HttpTypes.mkStatus responseStatusCode responseStatusMessage)
169+
HttpTypes.status501
215170
[("Content-Type", "application/json; charset=utf-8")]
216-
(L.fromStrict responseBody)
171+
"No ids parameter supplied."
172+
Just param -> do
173+
restUrl <- getRestUrl
174+
logStdOut "download"
175+
(responseBody, responseStatusCode, responseStatusMessage, fileNameHeader) <- getApi headers param restUrl
176+
case responseStatusCode of
177+
200 -> do
178+
let d = (eitherDecode $ L.fromStrict responseBody) :: (Either String [RestResponseFile])
179+
case d of
180+
Left err ->
181+
send $
182+
responseLBS
183+
HttpTypes.status501
184+
[("Content-Type", "application/json; charset=utf-8")]
185+
(L.fromStrict $ S8.pack err)
186+
Right files ->
187+
case files of
188+
[fileObject] -> do
189+
let fileID = fileSystemId fileObject
190+
path = getPathFromFileId $ show fileID
191+
realName = name fileObject
192+
fileMimeType = fromMaybe "application/octet-stream" (mimeType fileObject)
193+
send $
194+
responseFile
195+
HttpTypes.status200
196+
[ ("Content-Disposition", S8.pack ("attachment; filename=\"" ++ realName ++ "\"")),
197+
("Content-Type", S8.pack fileMimeType)
198+
]
199+
path
200+
Nothing
201+
xs ->
202+
withSystemTempFile "FileFighterFileHandler.zip" $
203+
\tmpFileName handle ->
204+
do
205+
let nameOfTheFolder = fromMaybe "Files" fileNameHeader
206+
let ss =
207+
mapM
208+
( \file -> do
209+
inZipPath <- mkEntrySelector $ fromMaybe (name file) (path file)
210+
loadEntry Store inZipPath (getPathFromFileId (show $ fileSystemId file))
211+
)
212+
xs
213+
createArchive tmpFileName ss
214+
send $
215+
responseFile
216+
HttpTypes.status200
217+
[ ("Content-Disposition", S8.pack ("attachment; filename=\"" ++ S8.unpack nameOfTheFolder ++ ".zip" ++ "\"")),
218+
("Content-Type", "application/zip")
219+
]
220+
tmpFileName
221+
Nothing
222+
_ ->
223+
send $
224+
responseLBS
225+
(HttpTypes.mkStatus responseStatusCode responseStatusMessage)
226+
[("Content-Type", "application/json; charset=utf-8")]
227+
(L.fromStrict responseBody)
217228

218-
getApi :: [HttpTypes.Header] -> String -> IO (S8.ByteString, Int, S8.ByteString)
219-
getApi allHeaders restUrl = runReq (defaultHttpConfig {httpConfigCheckResponse = httpConfigDontCheckResponse}) $ do
229+
getApi :: [HttpTypes.Header] -> String -> String -> IO (S8.ByteString, Int, S8.ByteString, Maybe S8.ByteString)
230+
getApi allHeaders param restUrl = runReq (defaultHttpConfig {httpConfigCheckResponse = httpConfigDontCheckResponse}) $ do
220231
r <-
221232
req
222233
GET -- method
223-
(http (DataText.pack restUrl) /: "v1" /: "filesystem" /: "download") -- safe by construction URL
234+
(http (DataText.pack restUrl) /: "api" /: "v1" /: "filesystem" /: "download") -- safe by construction URL
224235
-- (http (DataText.pack restUrl) /:"v1" /: "filesystem" /: DataText.pack (S8.unpack (getOneHeader allHeaders "X-FF-IDS" )) /: "info")
225236
NoReqBody -- use built-in options or add your own
226237
bsResponse -- specify how to interpret response
227-
(header "X-FF-IDS" (getOneHeader allHeaders "X-FF-IDS") <> header "Authorization" (getOneHeader allHeaders "Authorization") <> port 8080) --PORT !!
238+
(header "X-FF-IDS" (getOneHeader allHeaders "X-FF-IDS") <> header "Cookie" (getOneHeader allHeaders "Cookie") <> port 8080 <> (=:) "ids" param) --PORT !!
228239
-- mempty -- query params, headers, explicit port number, etc.
229-
return (responseBody r, responseStatusCode r, responseStatusMessage r)
240+
return (responseBody r, responseStatusCode r, responseStatusMessage r, responseHeader r "X-FF-NAME")
230241

231242
delete :: Application
232243
delete req send = do
@@ -263,7 +274,7 @@ deleteApi allHeaders restUrl fileId = runReq (defaultHttpConfig {httpConfigCheck
263274
r <-
264275
req
265276
DELETE
266-
(http (DataText.pack restUrl) /: "api" /: "v1" /: "filesystem" /: DataText.pack fileId /: "delete")
277+
(http (DataText.pack restUrl) /: "api" /: "v1" /: "filesystem" /: DataText.pack fileId /: "delete")
267278
NoReqBody
268279
bsResponse
269280
(header "Authorization" (getOneHeader allHeaders "Authorization") <> port 8080) -- parentID not in Headers
@@ -279,7 +290,7 @@ health req send = do
279290

280291
let response =
281292
object
282-
[ "version" .= ("1.0.0" :: String),
293+
[ "version" .= ("0.2.0" :: String),
283294
"deploymentType" .= deploymentType,
284295
"actualFilesSize" .= actualFilesSize,
285296
"fileCount" .= length files
@@ -296,6 +307,10 @@ getOneHeader headers headerName =
296307
[header] -> snd header
297308
_ -> ""
298309

310+
getDownloadQuery :: HttpTypes.Query -> Maybe String
311+
getDownloadQuery [(param, Just value)] = if param == "ids" then Just (S8.unpack value) else Nothing
312+
getDownloadQuery _ = Nothing
313+
299314
-- needed because buffering is causing problems with docker
300315
logStdOut :: String -> IO ()
301316
logStdOut text = do
@@ -355,7 +370,7 @@ instance ToJSON User
355370

356371
data RestResponseFile = RestResponseFile
357372
{ fileSystemId :: !Int,
358-
name :: String,
373+
name :: String,
359374
path :: Maybe String,
360375
size :: Int,
361376
owner :: User,

0 commit comments

Comments
 (0)