[Lispweb] up/download files via araneida?
Richard Newman
r.newman at reading.ac.uk
Fri Sep 15 16:00:18 CDT 2006
> I found the body with the multipart content. I installed cl-mime
> in an effort
> to figure out how to separate the parts and convert them back to a
> file.
> That's where I'm stuck right now - parsing the multipart stuff. I
> *think*
> cl-mime:parse-mime expects request-unparsed-body as the string it will
> decompose into the mime objects.
My code...
In the handler:
(multiple-value-bind (data data-properties)
(form-data-param "my-param" (request-body request))
(with-open-file (s filepath
:element-type '(unsigned-byte 8)
:direction :output
:if-does-not-exist :create
:if-exists :supersede)
;; Terrible, terrible encoding issues occur if we
;; supply the data as a string to WRITE-SEQUENCE.
;; Instead, we (rather wastefully) run through it,
;; turning it into a list of bytes!
;; TODO: I can guarantee there is a better way of
;; doing all this.
(write-sequence
(loop for char across data collecting (char-code char))
s))
In araneida/daemon.lisp:
Line 80:
(defun parse-form-data-body (body-string content-type)
(let ((boundary
(cdr (assoc "boundary"
(car (last (rfc2388:parse-header content-
type :value)))
:test #'string=))))
(rfc2388:parse-mime
body-string
boundary
:write-content-to-file nil)))
In araneida/request.lisp:
(defmethod request-body ((r request))
(if (slot-boundp r 'body)
(slot-value r 'body)
(setf (slot-value r 'body)
(let ((body (request-unparsed-body r))
(len (request-unparsed-body-length r)))
(if body
(let ((content-type (car (request-header r :content-
type))))
(cond ((string= content-type "application/x-www-
form-urlencode
d")
(parse-form-urlencoded-body
#+lispworks
(map 'string
;; for some reason lispworks wants
an array of c
ode characters
;; according to Bob Hutchinson
(hutch at recursi
ve.ca)
;; -- Alan Shields [14 November 2005]
(lambda (c) (code-char c))
body)
#-lispworks
body
'(#\&) len))
((search "multipart/form-data" content-type)
;; Ruh-roh! Have to parse a form-data body.
;; This returns something like
;; Have to use a separate accessor because
this is much
;; richer.
(parse-form-data-body body content-type))
(t
;; Tell ya what, we'll just return the raw
contents.
body)))
nil)))))
Should do the trick. A recent araneida might have those patches already.
-R
More information about the lispweb
mailing list