[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