From: Trastabuga
Subject: Uploading a file to web server using Lisp
Date: 
Message-ID: <1170699584.740423.253080@a75g2000cwd.googlegroups.com>
Could anyone point me the direction how I can implement uploading
files from a web browser to a web server using lisp? Any libraries? Is
CGI the only way to accomplish it? There are lots of materials on how
to do it using PHP but I could nothing for Lisp.

Any suggestions are welcome!
Andrew

From: ········@gmail.com
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <1170705893.287467.273390@p10g2000cwp.googlegroups.com>
On Feb 5, 10:19 am, "Trastabuga" <·········@gmail.com> wrote:
> Could anyone point me the direction how I can implement uploading
> files from a web browser to a web server using lisp? Any libraries? Is
> CGI the only way to accomplish it? There are lots of materials on how
> to do it using PHP but I could nothing for Lisp.

Here's an exmple on how to do it with portableaserve http://
www.cliki.net/Portableaserve (from examples.cl included in the
tarball)

http://paste.lisp.org/display/36419

hth

Nick

;; these two urls show how to transfer a user-selected file from
;; the client browser to the server.
;;
;; We use two urls (/getfile to put up the form and /getfile-post to
;; handle the post action of the form).   We could have done it all
;; with one url but since there's a lot of code it helps in the
;; presentation to separate the two.
;;
(publish :path "/getfile-old"
	 :content-type "text/html; charset=utf-8"
	 :function #'(lambda (req ent) (getfile-function
					req ent "/getfile-got-old")))

(publish :path "/getfile"
	 :content-type "text/html; charset=utf-8"
	 :function #'(lambda (req ent) (getfile-function
					req ent "/getfile-got")))


(defun getfile-function (req ent posturl)
  (with-http-response (req ent)
    (with-http-body (req ent)
      (html (:head "get file")
	    (:body
	     ((:form :enctype "multipart/form-data"
		     :method "post"
		     :action posturl)
	      "Let me know what file to grab"
	      :br
	      ((:input :type "file"
		       :name "thefile"
		       :value "*.txt"))
	      :br
	      ((:input :type "text" :name "textthing"))
	      "Enter some text"
	      :br
	      ((:input :type "checkbox" :name "checkone"))
	      "check box one"
	      :br
	      ((:input :type "checkbox" :name "checktwo"))
	      "check box two"
	      :br
	      ((:input :type "submit"))))))))



>
> Any suggestions are welcome!
> Andrew
From: Trastabuga
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <1170710540.347156.74840@j27g2000cwj.googlegroups.com>
On Feb 5, 3:04 pm, ········@gmail.com wrote:
> On Feb 5, 10:19 am, "Trastabuga" <·········@gmail.com> wrote:
>
> > Could anyone point me the direction how I can implement uploading
> > files from a web browser to a web server using lisp? Any libraries? Is
> > CGI the only way to accomplish it? There are lots of materials on how
> > to do it using PHP but I could nothing for Lisp.
>
> Here's an exmple on how to do it with portableaserve http://www.cliki.net/Portableaserve(from examples.cl included in the
> tarball)
>
> http://paste.lisp.org/display/36419
>
> hth
>
> Nick
>
> ;; these two urls show how to transfer a user-selected file from
> ;; the client browser to the server.
> ;;
> ;; We use two urls (/getfile to put up the form and /getfile-post to
> ;; handle the post action of the form).   We could have done it all
> ;; with one url but since there's a lot of code it helps in the
> ;; presentation to separate the two.
> ;;
> (publish :path "/getfile-old"
>          :content-type "text/html; charset=utf-8"
>          :function #'(lambda (req ent) (getfile-function
>                                         req ent "/getfile-got-old")))
>
> (publish :path "/getfile"
>          :content-type "text/html; charset=utf-8"
>          :function #'(lambda (req ent) (getfile-function
>                                         req ent "/getfile-got")))
>
> (defun getfile-function (req ent posturl)
>   (with-http-response (req ent)
>     (with-http-body (req ent)
>       (html (:head "get file")
>             (:body
>              ((:form :enctype "multipart/form-data"
>                      :method "post"
>                      :action posturl)
>               "Let me know what file to grab"
>               :br
>               ((:input :type "file"
>                        :name "thefile"
>                        :value "*.txt"))
>               :br
>               ((:input :type "text" :name "textthing"))
>               "Enter some text"
>               :br
>               ((:input :type "checkbox" :name "checkone"))
>               "check box one"
>               :br
>               ((:input :type "checkbox" :name "checktwo"))
>               "check box two"
>               :br
>               ((:input :type "submit"))))))))
>
>
>
> > Any suggestions are welcome!
> > Andrew


Thank you, guys!
Now I've got two options: Portableaserve and Hunchentoot. Which one
should I chose (best support, portability etc)?

Andrew
From: ········@gmail.com
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <1170720571.453990.140760@a75g2000cwd.googlegroups.com>
On Feb 5, 1:22 pm, "Trastabuga" <·········@gmail.com> wrote:
> On Feb 5, 3:04 pm, ········@gmail.com wrote:
>
>
>
>
>
> > On Feb 5, 10:19 am, "Trastabuga" <·········@gmail.com> wrote:
>
> > > Could anyone point me the direction how I can implement uploading
> > > files from a web browser to a web server using lisp? Any libraries? Is
> > > CGI the only way to accomplish it? There are lots of materials on how
> > > to do it using PHP but I could nothing for Lisp.
>
> > Here's an exmple on how to do it with portableaservehttp://www.cliki.net/Portableaserve(fromexamples.cl included in the
> > tarball)
>
> >http://paste.lisp.org/display/36419
>
> > hth
>
> > Nick
>
> > ;; these two urls show how to transfer a user-selected file from
> > ;; the client browser to the server.
> > ;;
> > ;; We use two urls (/getfile to put up the form and /getfile-post to
> > ;; handle the post action of the form).   We could have done it all
> > ;; with one url but since there's a lot of code it helps in the
> > ;; presentation to separate the two.
> > ;;
> > (publish :path "/getfile-old"
> >          :content-type "text/html; charset=utf-8"
> >          :function #'(lambda (req ent) (getfile-function
> >                                         req ent "/getfile-got-old")))
>
> > (publish :path "/getfile"
> >          :content-type "text/html; charset=utf-8"
> >          :function #'(lambda (req ent) (getfile-function
> >                                         req ent "/getfile-got")))
>
> > (defun getfile-function (req ent posturl)
> >   (with-http-response (req ent)
> >     (with-http-body (req ent)
> >       (html (:head "get file")
> >             (:body
> >              ((:form :enctype "multipart/form-data"
> >                      :method "post"
> >                      :action posturl)
> >               "Let me know what file to grab"
> >               :br
> >               ((:input :type "file"
> >                        :name "thefile"
> >                        :value "*.txt"))
> >               :br
> >               ((:input :type "text" :name "textthing"))
> >               "Enter some text"
> >               :br
> >               ((:input :type "checkbox" :name "checkone"))
> >               "check box one"
> >               :br
> >               ((:input :type "checkbox" :name "checktwo"))
> >               "check box two"
> >               :br
> >               ((:input :type "submit"))))))))
>
> > > Any suggestions are welcome!
> > > Andrew
>
> Thank you, guys!
> Now I've got two options: Portableaserve and Hunchentoot. Which one
> should I chose (best support, portability etc)?
>

I don't know, I've never used Hutchentoot. With aserve you also have
the nice added bonus of a chapter from PCL devoted to the subject

   http://www.gigamonkeys.com/book/practical-web-programming-with-
allegroserve.html

hth

Nick




> Andrew- Hide quoted text -
>
> - Show quoted text -
From: Zach Beane
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <m3wt2wp94s.fsf@unnamed.xach.com>
"Trastabuga" <·········@gmail.com> writes:

> Thank you, guys!
> Now I've got two options: Portableaserve and Hunchentoot. Which one
> should I chose (best support, portability etc)?

With Hunchentoot, you get an active community and a superstar project
leader in Edi.

Zach
From: =?ISO-8859-15?Q?Andr=E9_Thieme?=
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <eqa2tv$3ra$1@registered.motzarella.org>
Trastabuga schrieb:

> Now I've got two options: Portableaserve and Hunchentoot. Which one
> should I chose (best support, portability etc)?

AllegroServe supports Webactions, a MVC framework.


Andr�
-- 
From: ········@gmail.com
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <1170720430.675743.170670@l53g2000cwa.googlegroups.com>
On Feb 5, 12:04 pm, ········@gmail.com wrote:
> On Feb 5, 10:19 am, "Trastabuga" <·········@gmail.com> wrote:
>
> > Could anyone point me the direction how I can implement uploading
> > files from a web browser to a web server using lisp? Any libraries? Is
> > CGI the only way to accomplish it? There are lots of materials on how
> > to do it using PHP but I could nothing for Lisp.
>
> Here's an exmple on how to do it with portableaserve http://www.cliki.net/Portableaserve(from examples.cl included in the
> tarball)
>
> http://paste.lisp.org/display/36419
>
> hth
>
> Nick
>
> ;; these two urls show how to transfer a user-selected file from
> ;; the client browser to the server.
> ;;
> ;; We use two urls (/getfile to put up the form and /getfile-post to
> ;; handle the post action of the form).   We could have done it all
> ;; with one url but since there's a lot of code it helps in the
> ;; presentation to separate the two.
> ;;
> (publish :path "/getfile-old"
>          :content-type "text/html; charset=utf-8"
>          :function #'(lambda (req ent) (getfile-function
>                                         req ent "/getfile-got-old")))
>
> (publish :path "/getfile"
>          :content-type "text/html; charset=utf-8"
>          :function #'(lambda (req ent) (getfile-function
>                                         req ent "/getfile-got")))
>
> (defun getfile-function (req ent posturl)
>   (with-http-response (req ent)
>     (with-http-body (req ent)
>       (html (:head "get file")
>             (:body
>              ((:form :enctype "multipart/form-data"
>                      :method "post"
>                      :action posturl)
>               "Let me know what file to grab"
>               :br
>               ((:input :type "file"
>                        :name "thefile"
>                        :value "*.txt"))
>               :br
>               ((:input :type "text" :name "textthing"))
>               "Enter some text"
>               :br
>               ((:input :type "checkbox" :name "checkone"))
>               "check box one"
>               :br
>               ((:input :type "checkbox" :name "checktwo"))
>               "check box two"
>               :br
>               ((:input :type "submit"))))))))
>

this would probubly also help

   http://paste.lisp.org/display/36419#1

Nick

;;
;; this demonstrates the use of the low level multipart access
functions.
;; In this code we parse the result of get-multipart-header ourselves
;; and we use get-multipart-sequence.
;; In the example that follows (associate with path "/getfile-got")
;; we show now to use the higher level functions to retrive multipart
;; data
(publish :path "/getfile-got-old"
         :content-type "text/html; charset=utf-8"
         :function
         #'(lambda (req ent)

             (with-http-response (req ent)
               (let ((h nil)
                     (files-written)
                     (text-strings)
                     )
                 (loop
                   ; get headers for the next item
                   (if* (null (setq h (get-multipart-header req)))
                      then ; no more items
                           (return))
                   ; we can get the filename from the header if
                   ; it was an <input type="file"> item.  If there is
                   ; no filename, we just create one.
                   (pprint h)
                   (pprint (multiple-value-list (parse-multipart-
header h)))
                   (let ((cd (assoc :content-disposition h :test
#'eq))
                         (filename)
                         (sep))
                     (if* (and cd (consp (cadr cd)))
                        then (setq filename (cdr (assoc "filename"
                                                        (cddr (cadr
cd))
                                                        :test
#'equalp)))
                             (if* filename
                                then ;; locate the part of the
filename
                                     ;; after the last directory
separator.
                                     ;; the common lisp pathname
functions are
                                     ;; no help since the filename
syntax
                                     ;; may be foreign to the OS on
which
                                     ;; the server is running.
                                     (setq sep
                                       (max (or (position #\/ filename
                                                          :from-end t)
-1)
                                            (or (position #\\ filename
                                                          :from-end t)
-1)))
                                     (setq filename
                                       (subseq filename (1+ sep)
                                               (length filename)))))
                     (if* (and filename (not (equal filename "")))
                        then (push filename files-written)
                             (with-open-file (pp
filename :direction :output
                                              :if-exists :supersede
                                              :element-type '(unsigned-
byte 8))
                               (format t "writing file ~s~%" filename)
                               (let ((buffer (make-array 4096
                                                         :element-
type
                                                         '(unsigned-
byte 8))))

                                 (loop (let ((count (get-multipart-
sequence
                                                     req
                                                     buffer)))
                                         (if* (null count) then
(return))
                                         (write-sequence buffer
pp :end count)))))
                      elseif (null filename)
                        then  ; no filename, just grab as a text
                             ; string
                             (let ((buffer (make-string 1024)))
                               (loop
                                 (let ((count (get-multipart-sequence
                                               req buffer
                                               :external-format :utf8-
base)))
                                   (if* count
                                      then (push (subseq buffer 0
count)
                                                 text-strings)
                                      else (return))))))))



                 ;; now send back a response for the browser

                 (with-http-body (req ent
                                      :external-format :utf8-base)
                   (html (:html (:head (:title "form example"))
                                (:body "-- processed the form, files
written --"
                                       (dolist (file (nreverse files-
written))
                                         (html :br "file: "
                                               (:b (:prin1-safe
file))))
                                       :br
                                       "-- Non-file items Returned: --
" :br
                                       (dolist (ts (reverse text-
strings))
                                         (html (:princ-safe
ts) :br))))))))))


;;
;; this retrieves data from a multipart form using the high level
;; functions.  You can compare this code to that above to see which
;; method you prefer
;;
(publish :path "/getfile-got"
         :content-type "text/html; charset=utf-8"
         :function
         #'(lambda (req ent)
             (with-http-response (req ent)
               (let ((files-written)
                     (text-strings)
                     (overlimit)
                     )
                 (loop
                   (multiple-value-bind (kind name filename content-
type)
                       (parse-multipart-header
                        (get-multipart-header req))

                     (case kind
                       (:eof (return)) ; no more to read
                       (:data
                        (push (cons name (get-all-multipart-data req))
                              text-strings))
                       (:file
                        (let ((contents (get-all-multipart-data
                                         req
                                         :type :binary
                                         :limit 1000000 ; abitrary
limit
                                         )))
                          ; find the tail of the filename, can't use
                          ; lisp pathname code since the filename
syntax
                          ; may not correspond to this lisp's native
os
                          (let ((sep (max (or (position #\/ filename
                                                        :from-end t)
-1)
                                          (or (position #\\ filename
                                                        :from-end t)
-1))))
                            (if* sep
                               then (setq filename
                                      (subseq filename (1+ sep)))))
                          (if* (eq contents :limit)
                             then ; tried to give us too much
                                  (setq overlimit t)
                           elseif (equal filename "") ; no file given
                             thenret ; ignore
                             else
                                  (with-open-file (p filename
                                                   :direction :output
                                                   :if-
exists :supersede
                                                   :element-type
'(unsigned-byte 8))
                                    (format
                                     t "writing file ~s, content-type
~s~%"
                                     filename content-type)
                                    (push filename files-written)
                                    (write-sequence contents p)))))
                       (t ; all else ignore but read to next header
                        (get-all-multipart-data req :limit 1000)))))




                 ;; now send back a response for the browser

                 (with-http-body (req ent
                                      :external-format :utf8-base)
                   (html (:html (:head (:title "form example"))
                                (:body "-- processed the form, files
written --"
                                       (dolist (file (nreverse files-
written))
                                         (html :br "file: "
                                               (:b (:prin1-safe
file))))
                                       (if* overlimit
                                          then (html :br
                                                     "File given was
over our "
                                                     "limit in the
size we "
                                                     "will accept"))
                                       :br
                                       "-- Non-file items Returned: --
" :br
                                       (dolist (ts (reverse text-
strings))
                                         (html
                                          "item name: " (:princ-safe
(car ts))
                                          ", item value: "
                                          (:princ-safe (cdr ts))
                                          :br))))))))))
From: Zach Beane
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <m31wl4qx4u.fsf@unnamed.xach.com>
"Trastabuga" <·········@gmail.com> writes:

> Could anyone point me the direction how I can implement uploading
> files from a web browser to a web server using lisp? Any libraries? Is
> CGI the only way to accomplish it? There are lots of materials on how
> to do it using PHP but I could nothing for Lisp.

I use the Hunchentoot web server. It supports uploads.

  http://weitz.de/hunchentoot/

I use it here:

  http://wigflip.com/

Zach
From: Trastabuga
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <1170716347.161381.90700@v45g2000cwv.googlegroups.com>
On Feb 5, 1:26 pm, Zach Beane <····@xach.com> wrote:
> "Trastabuga" <·········@gmail.com> writes:
> > Could anyone point me the direction how I can implement uploading
> > files from a web browser to a web server using lisp? Any libraries? Is
> > CGI the only way to accomplish it? There are lots of materials on how
> > to do it using PHP but I could nothing for Lisp.
>
> I use the Hunchentoot web server. It supports uploads.
>
>  http://weitz.de/hunchentoot/
>
> I use it here:
>
>  http://wigflip.com/
>
> Zach


Zach, do you use Hunchentoot under proxy or mod_lisp?

Thank you,
Andrew
From: Zach Beane
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <m3sldkp29z.fsf@unnamed.xach.com>
"Trastabuga" <·········@gmail.com> writes:

> Zach, do you use Hunchentoot under proxy or mod_lisp?

I use it behind mod_lisp on my current site. It's behind mod_proxy for
a site under development.

Zach
From: Trastabuga
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <1170778842.513206.278120@k78g2000cwa.googlegroups.com>
On Feb 5, 7:18 pm, Zach Beane <····@xach.com> wrote:
> "Trastabuga" <·········@gmail.com> writes:
> > Zach, do you use Hunchentoot underproxyor mod_lisp?
>
> I use it behind mod_lispon my current site. It's behind mod_proxyfor
> a site under development.
>
> Zach


I've installed the hunchentoot server, put in my Lisp lines:

(asdf:oos 'asdf:load-op :hunchentoot-test)
(hunchentoot:start-server :port 3001)

Now I am trying to figure out how can I display the test page (if I
don't have a direct connection to my local server and the port 3001).
If I try to use url like http://www.mydomain.com/lisp/hunchentoot/
test/
I see the default page of Hunchentoot (with message "You're most
likely seeing it because the server administrator hasn't set up a
custom default page yet").
Any ideas how can I reach the test page?

Thank you,
Andrew
From: Thomas A. Russ
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <ymi64afb2sm.fsf@sevak.isi.edu>
"Trastabuga" <·········@gmail.com> writes:
> I've installed the hunchentoot server, put in my Lisp lines:
> 
> (asdf:oos 'asdf:load-op :hunchentoot-test)
> (hunchentoot:start-server :port 3001)
> 
> Now I am trying to figure out how can I display the test page (if I
> don't have a direct connection to my local server and the port 3001).
> If I try to use url like http://www.mydomain.com/lisp/hunchentoot/
> test/

Try adding the port to your URL:

 http://www.mydomain.com:3001/lisp/hunchentoot/test
                        ^^^^^

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Zach Beane
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <m3lkjbp7xb.fsf@unnamed.xach.com>
"Trastabuga" <·········@gmail.com> writes:

> I've installed the hunchentoot server, put in my Lisp lines:
> 
> (asdf:oos 'asdf:load-op :hunchentoot-test)
> (hunchentoot:start-server :port 3001)
> 
> Now I am trying to figure out how can I display the test page (if I
> don't have a direct connection to my local server and the port 3001).
> If I try to use url like http://www.mydomain.com/lisp/hunchentoot/
> test/
> I see the default page of Hunchentoot (with message "You're most
> likely seeing it because the server administrator hasn't set up a
> custom default page yet").
> Any ideas how can I reach the test page?

It looks to me like you typed the URL wrong (/test/ instead of
/test). 

Hunchentoot questions are best asked on the Hunchentoot mailing
list. (A common novice error is to email Edi directly; don't make that
mistake! Ask the entire community, Edi included, on the mailing list!)

Zach
From: John Thingstad
Subject: Re: Uploading a file to web server using Lisp
Date: 
Message-ID: <op.tnaiukiipqzri1@pandora.upc.no>
On Mon, 05 Feb 2007 19:19:44 +0100, Trastabuga <·········@gmail.com> wrote:

> Could anyone point me the direction how I can implement uploading
> files from a web browser to a web server using lisp? Any libraries? Is
> CGI the only way to accomplish it? There are lots of materials on how
> to do it using PHP but I could nothing for Lisp.
>
> Any suggestions are welcome!
> Andrew
>

Read about it just yesterday actually when playing around with
hunchentoot. Edi Weitz's web server.
This is a excerpt from the source of the demostration server that comes  
with it.
It is called test.lisp

The important bits are
(:form :method :post :enctype "multipart/form-data"..)
and
(post-parameter "FILE1")
in upload-test.

CL-WHO is used for the (:form.. bit
Hunchentoot gets the post-parameter

note that the structure of a "multipart/form-data" is return (from  
post-parameter) as
(destructuring-bind (path file-name content-type)
           post-parameter

in handle-file
The web server just uploads the file for you
You then just makes a link to the file or copy it from the temporary  
directory.

To get the file explicitly you need something like this:
Got that from the StarterPack tutorial also from Edi Weitz.

(defun show-jpg-from-web (url)
               (let ((tmp-file (merge-pathnames "tmp/foo.jpg" (probe-file
                                                               (sys:get-folder-path  
:my-documents)))))
                 (with-open-file (file-stream (ensure-directories-exist  
tmp-file)
                                              :direction :output
                                              :if-exists :overwrite
                                              :if-does-not-exist :create
                                              :element-type '(unsigned-byte  
8))
                   (cl-fad:copy-stream (drakma:http-request url  
:want-stream t :force-binary t)
                                       file-stream))
                 (capi:contain (make-instance 'capi:image-pinboard-object
                                              :image (namestring  
tmp-file)))))

This pops a image from a URL on the web in a capi window (LispWorks)
This uses packages cl-fad and drakma.

Well that should give you a idea.
-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/