
I’m trying to create a trivial Happstack application based on the example from the “File Uploads” section of the Happstack book [1]. It should work as follows: 1. If there is no file called ‘foo’ on disk, show the upload form at any page. 2. If the file exists, show its contents at ‘localhost:8000/file’ and the upload form at any other page. The difficulty is that initially the uploaded file is placed to a temporary location, but since I want to read the file later, I have to move it somewhere. ‘UploadFile-working.hs’ uses two handlers for that, which doesn’t look right. I’d like the code to look like ‘UploadFile.hs’, but it doesn’t work properly. Could anyone explain why? [1] http://happstack.com/docs/crashcourse/index.html

On Tue, Jun 03, 2014 at 12:31:14AM +0400, Nikita Karetnikov wrote:
I’d like the code to look like ‘UploadFile.hs’, but it doesn’t work properly. Could anyone explain why?
Yes, you can't receive the client's request containing the form data in the reponse that sends out the form!
tempFile :: ServerPart Response tempFile = do (tmpFile, _, _) <- lookFile "file_upload" liftIO $ renameFile tmpFile permFileLoc file <- liftIO $ readFile permFileLoc showFile file
permFile :: ServerPart Response permFile = do file <- liftIO $ readFile permFileLoc showFile file
Why not merge these with something like (unchecked!) readFile :: ServerPart Response readFile = do flip (<|>) (return ()) $ do (tmpFile, _, _) <- lookFile "file_upload" liftIO $ renameFile tmpFile permFileLoc file <- liftIO $ readFile permFileLoc showFile file Tom

You code does not work correctly because what you are trying to do
really requires three separate requests. You want the client to be
able to:
1. do a GET request to receive the form
2. do a POST request to upload the file
3. do another GET request to view the file after it has been uploaded
In UploadFile.hs you have the first two steps merged together in
uploadForm. In UploadFile-working -- you have steps 2 and 3 oddly
separated and merged at the same time.
I have created a modified version that probably does what you want.
- jeremy
On Mon, Jun 2, 2014 at 3:31 PM, Nikita Karetnikov
I’m trying to create a trivial Happstack application based on the example from the “File Uploads” section of the Happstack book [1]. It should work as follows:
1. If there is no file called ‘foo’ on disk, show the upload form at any page.
2. If the file exists, show its contents at ‘localhost:8000/file’ and the upload form at any other page.
The difficulty is that initially the uploaded file is placed to a temporary location, but since I want to read the file later, I have to move it somewhere. ‘UploadFile-working.hs’ uses two handlers for that, which doesn’t look right. I’d like the code to look like ‘UploadFile.hs’, but it doesn’t work properly. Could anyone explain why?
[1] http://happstack.com/docs/crashcourse/index.html
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

I have created a modified version that probably does what you want.
Thanks, but it fails when a user tries to access ‘/view’ before uploading a file. Also, I want the file to be available only at ‘/view’. I’ve attached a version that’s based on yours, can it be further improved? For instance, is there a need for ‘seeOther’?

On Tue, Jun 3, 2014 at 1:05 PM, Nikita Karetnikov
Thanks, but it fails when a user tries to access ‘/view’ before uploading a file.
Yeah, I didn't bother to implement error handling.
Also, I want the file to be available only at ‘/view’.
The version I provided meets that requirement for viewing the file. Perhaps you also want the the POST address to be /view? Ultimately, you need three end points: 1. a url to GET the file 2. a url to POST the file 3. a url that shows the form How you arrange that depends a lot on your design goals and requirements. If you only allow the user to upload the file once, then you could have: 1. GET /view, shows the form if the file does not yet exist 2. POST /view handles the file upload 3. GET /view shows the file if it has been uploaded This does not provide a way to view the form again once the file has been uploaded. You could also do something like; 1. GET /file/upload_form, shows upload form 2. POST /file, handles submission 3. GET /file shows file if it exists, or redirects to /file/upload_form Or.. whatever you want.
I’ve attached a version that’s based on yours, can it be further improved? For instance, is there a need for ‘seeOther’?
After the file is upload -- you need to return some sort of Response to the user. One logical choice is to redirect to the client to GET the resource that was just uploaded. In theory, at the end of handleUpload you could call readFile+output directly to show the file. But if the user then refreshes the page, it will attempt to POST the data again. If you have the redirect in there, then when they reload the page, it will simply perform the GET request again. As for 'improving' the code -- I think it mostly comes down to personal taste at this point. - jeremy
participants (3)
-
Jeremy Shaw
-
Nikita Karetnikov
-
Tom Ellis