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
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
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
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 -
"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
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�
--
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))))))))))
"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
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
"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
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
"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
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/