[Bese-devel] UCW file upload example

Mac Chan lispweb at mac.e4ward.com
Wed Jul 13 22:24:50 UTC 2005


Hi,

I was unable to run the file upload example. Upon playing around
with the sample code for a while I figured it out.

Please see the attached diff.

I'm building a site for teachers to upload multimedia contents which
can be upward of 100mb+ files. The way ucw stores uploaded content in
memory cannot cut it.

TBNL implemented a hack (write-content-to-file t) where they put a
hook in cl-rfc2388 to allow writing uploaded content to file directly.
Since it's a hack (TBNL manages the file creation, uploaded contents
itself) for TBNL only, it is not usable for other frameworks.

Even if it does, I do not have a good idea of how to incorporate 
this into ucw cleanly.

Right now code in UCW can access the file content with slot-value
directly, which is very simple but it doesn't scale for large files.

If we put a pathname there instead, then everyone that access the slot
will have to examine the tag first (much like the bug fix I submit
below), which complicates things.

Another drawback is when session expires, those files need to be
cleaned up. Right now GC handles that and if we put the pathname in
there, ucw has to do the cleanup.

I'm soliciting opinions how to architech this as I'm not all too
familiar with the underneath framework.

(Araneida right now doesn't support multipart MIME form post.
aserve however do support this.)


BTW There are certain things that can be done in a more straightforward way
in aserve / TBNL / araneida.

I think that UCW cannot share objects with Araneida or other backend directly.
Can we hack both and so that they share a unique session id and some hooks
to access objects created in both sides?

In that case I might be able to handle the boring file upload in
aserve and let ucw handle all the other cool stuff :-)

Does anyone have any experience to share, regarding using both
UCW and other backends in your app?

I heard that drewc runs cliki & ucw in the same image. I wonder
how that works.

-- nsr

Index: httpd.lisp
===================================================================
--- httpd.lisp  (revision 90)
+++ httpd.lisp  (revision 91)
@@ -507,12 +507,16 @@
                      :element-type (array-element-type line)))))

 (defmethod get-parameter ((request httpd-request) name)
-  (let ((cons (assoc name (parameters request) :test #'string=)))
-    (when cons (copy-seq (cdr cons)))))
+  (let* ((cons (assoc name (parameters request) :test #'string=))
+         (value (cdr cons)))
+    (when cons (copy-seq (if (mime-part-p value)
+                             (mime-part-body value) value)))))

 (defmethod map-parameters ((request httpd-request) lambda)
  (dolist* ((name . value) (parameters request))
-    (funcall lambda name (copy-seq value))))
+    (funcall lambda name (copy-seq
+                          (if (mime-part-p value)
+                              (mime-part-body value) value)))))

 (defun read-request-headers (backend stream)
  (iterate
------------------------------------------->8--------------------------------------

Index: examples/examples.lisp
===================================================================
--- examples/examples.lisp      (revision 91)
+++ examples/examples.lisp      (revision 94)
@@ -36,6 +36,8 @@
      (add-component 'counter)
      (add-component 'transaction-example)
      (add-component 'example-form)
+      (add-component 'file-upload-example)
+      (add-component 'file-upload-viewer)
      (add-component 'example-welcome)
      (add-component 'sum)
      (add-component 'presentations-example)
@@ -49,6 +51,7 @@
        (<:li (example-link 'counter "Counter"))
       (<:li (example-link 'transaction-example "Component Transaction"))
       (<:li (example-link 'example-form "Form demo"))
+       (<:li (example-link 'file-upload-example "Form upload example"))
       (<:li (example-link 'presentations-example "Presentations Example"))
       (<:li (example-link 'sum "Add some numbers."))
       (<:li (<ucw:a :action (error "FOO") "Signal an error")))))
Index: examples/forms.lisp
===================================================================
--- examples/forms.lisp (revision 91)
+++ examples/forms.lisp (revision 94)
@@ -7,7 +7,7 @@
 (defclass file-upload-example (widget-component template-component)
  ((file :accessor file-upload-example.file :initform ""))
  (:metaclass standard-component-class)
-  (:default-initargs :template-name "upload.tal")
+  (:default-initargs :template-name "ucw/examples/upload.tal")
  (:documentation "Form for uploading a file."))



More information about the bese-devel mailing list