Reputation: 301
I'm trying to enable file upload to a web server using Racket's file-upload formlet (http://docs.racket-lang.org/web-server/formlets.html). The trouble is that formlet-process just returns the name of the file instead of its contents.
Here's what I have so far:
#lang web-server/insta
(require web-server/formlets
web-server/http
xml)
; start: request -> doesn't return
(define (start request)
(show-page request))
; show-page: request -> doesn't return
(define (show-page request)
; Response generator
(define (response-generator embed/url)
(response/xexpr
`(html
(head (title "File upload example"))
(body (h1 "File upload example"))
(form
([action ,(embed/url upload-handler)])
,@(formlet-display file-upload-formlet)
(input ([type "submit"] [value "Upload"]))))))
(define (upload-handler request)
(define a-file (formlet-process file-upload-formlet request))
(display a-file)
(response/xexpr
`(html
(head (title "File Uploaded"))
(body (h1 "File uploaded")
(p "Some text here to say file has been uploaded")))))
(send/suspend/dispatch response-generator))
; file-upload-formlet: formlet (binding?)
(define file-upload-formlet
(formlet
(div ,{(required (file-upload)) . => . a-file})
a-file))
In this case, a-file
gets set to a byte string with the name of the file, instead of the contents of the file. How do I get the contents of the file so that I can write it to a file on the server?
Thanks in advance for your help!
Upvotes: 3
Views: 775
Reputation: 301
OK, here's something that works, though I'm not sure it's the best way of doing things. Basically I had to
References that helped in figuring this out were http://lists.racket-lang.org/users/archive/2009-August/034925.html and http://docs.racket-lang.org/web-server/http.html
So here's the working code. Obviously WORKINGDIR needs to be set to some working path.
#lang web-server/insta
(require web-server/formlets)
; start: request -> doesn't return
(define (start request)
(show-page request))
; show-page: request -> doesn't return
(define (show-page request)
; Response generator
(define (response-generator embed/url)
(response/xexpr
`(html
(head (title "File upload example"))
(body (h1 "File upload example"))
(form
([action ,(embed/url upload-handler)]
[method "POST"]
[enctype "multipart/form-data"])
,@(formlet-display file-upload-formlet)
(input ([type "submit"] [value "Upload"]))))))
(define (upload-handler request)
(define-values (fname fcontents)
(formlet-process file-upload-formlet request))
(define save-name (string-append "!uploaded-" fname))
(current-directory WORKINGDIR)
(display-to-file fcontents save-name #:exists 'replace)
(response/xexpr
`(html
(head (title "File Uploaded"))
(body (h2 "File uploaded")
(p ,fname)
(h2 "File size (bytes)")
(p ,(number->string (file-size save-name)))))))
(send/suspend/dispatch response-generator))
; file-upload-formlet: formlet (binding?)
(define file-upload-formlet
(formlet
(div ,{(file-upload) . => . binds})
; (formlet-process file-upload-formlet request)
; returns the file name and contents:
(let
([fname (bytes->string/utf-8 (binding:file-filename binds))]
[fcontents (binding:file-content binds)])
(values fname fcontents))))
Upvotes: 4