[Prev][Next][Index][Thread]

Re: got cl-http working-sees nothing! ??



At 8:55 Uhr +0000 27.02.1997, Simon Brooke wrote:

>Anyone else struggling with cl-http on ACL on Linux, perhaps we should
>set up a sub-list; there seem to be several of us. I'm assembling what I
>learn at 
>
>http://www.intelligent.co.uk/~simon/cl-http-dummies.html

Well, I would not say, that CL-HTTP is to difficult to use.

Not many people are used to do stuff like writing web sites
in Lisp. We'll change that.



Do you prefer stuff like (from Netscape Enterprise Server 2.0):


>Init fn=load-types mime-types=mime.types
>Init fn="flex-init" lavielle-log="/export/logs/lavielle/lavielle.log.access" fo\
>rmat.lavielle-log="%Ses->client.ip% - %Req->vars.auth-user% [%SYSDATE%] \"%Req-\
>>reqpb.clf-request%\" %Req->srvhdrs.clf-status% %Req->srvhdrs.content-length%"
>Init fn="init-uhome" pwfile="/etc/nsusers"
>
>
><Object name="default">
>NameTrans fn="pfx2dir" from="/mc-icons" dir="/usr/local/netscape/nse-home/ns-ic\
>ons"
>NameTrans fn="pfx2dir" from="/ns-icons" dir="/usr/local/netscape/nse-home/ns-ic\
>ons"
>NameTrans fn="pfx2dir" from="/cgi-bin" dir="/export/WWW/lavielle/cgi-bin"
>NameTrans fn="unix-home" from="/~" subdir="htdocs"
>NameTrans root="/export/WWW/lavielle/htdocs" fn="document-root"
>PathCheck fn="unix-uri-clean"
>PathCheck fn="find-pathinfo"
>PathCheck index-names="Welcome.html" fn="find-index"
>ObjectType fn="type-by-extension"


There is a lot to learn, since you can *program*
CL-HTTP - the web server. Serving directories is simple - but
writing dynamically generated pages is a bit
harder. It does not make sense to use CL-HTTP
to do a single export on a file system
hierarchy (stuff you do in Apache, ...).
This actually is boring.

EXPORT-URL may look complicated, but it is the uniform interface
for exporting URLs with CL-HTTP. You may even want
to print the doc string and paste it on the wall.


It is CLOS programming, stupid!
-------------------------------

For this purpose it may be necessary to add another abstraction
layer. For example you could use knowledge of object-oriented
programming.

For example in my code the following make-instance
generates and controls a whole range of pages (on www.als.de):


(defparameter *leasing-companies-page*
  (make-instance 'als-address-overview-page
    :title "Leasinggesellschaften in Deutschland"
    :address-file "als:Adressen;adressen.tabtext"
    :url #u"/als/firmen/deutschland/leasing-firmen"
    :by-name-link #u"/als/firmen/deutschland/leasing-firmen-nach-name"
    :by-zip-link #u"/als/firmen/deutschland/leasing-firmen-nach-plz"
    :by-city-link #u"/als/firmen/deutschland/leasing-firmen-nach-stadt"
    :by-web-page-link #u"/als/firmen/deutschland/leasing-firmen-mit-web-seite"
    :by-zip-area-link #u"/als/firmen/deutschland/leasing-firmen-nach-plz-bereich.gif?"
    :base-link-to-zip-area-pages "/als/firmen/leasing/plz/"
    :map-file-pathname "als:GIF;leasing.map"
    :map-GIF-pathname "als:GIF;PLZmap.GIF"
    :company-folders-directory (pathname "als:firmen;")
    :title-prefix "Leasingfirmen"))



Much of my stuff has been written in Genera and MCL and runs completely
portable. I can run it on may PowerBook or on the Lisp machine.
On the weekend I'll try to bring it up on ACL/Linux.

You end up doing normal CLOS programming. The only difference
is, that your GUI is the web.

This is another example from my code. You can export folders
automatically. The server looks for new folders (if you
tell him to update a certain page). Now the server reads
a description file from each folder and generates
the appropriate exports. It also announces the new
folders into certain registries (which may be also
visible). The idea is, that you sell web space and
people can assemble pages on their own. The web server
looks into that stuff and automagically integrates
the alien pages into his server structure.

Here comes an example (its only a fragment) from my code.
This is stuff that will be automagically invoked by
the above make-instance.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Export Company Folders

(defclass company-folder ()
    ((name :accessor company-name :initform "unknown"
	   :documentation "The name of the company"
	   :initarg :name)
     (overview-page :accessor company-folder-overview-page
		    :initarg :overview-page)
     (url :accessor company-url :documentation "The base URL for this company")
     (directory :accessor company-directory
		:documentation "The directory where the files are located"
		:initform nil
		:initarg :directory)
     (pages :accessor company-pages :initarg :pages
	    :documentation "All URLs or Pages for this company")
     (description-file :accessor company-description-file
		       :documentation "This file describes the configuration.")
     (folder-description :accessor company-folder-description)))

(defmethod print-object ((company-folder company-folder) stream)
  (print-unreadable-object (company-folder stream :type t :identity t)
    (format stream "name:~a directory:~a"
	    (company-name company-folder)
	    (company-directory company-folder))))

(defmethod export-company-folders ((page address-overview-page))
  (when (page-company-folders-directory page)
    (flet ((file-as-subdir (file)
	     (make-pathname :defaults (page-company-folders-directory page)
			    :directory (append (pathname-directory
                                                (page-company-folders-directory page))
					       (list (pathname-name file))))))
      (setf (page-company-folders page)
	    (loop for directory in
                  #+genera (mapcar #'file-as-subdir
                                   (directory (page-company-folders-directory page)))
                  #-genera (directory (make-pathname :defaults (page-company-folders-directory page)
                                                     :name :wild
                                                     :type :wild)
                                      :directories t)
                  collect (export-company-folder page directory))))))

(defmethod export-company-folder ((page address-overview-page) directory)
  (make-instance 'company-folder
		 :directory directory
		 :overview-page page))

(defgeneric update-company-folder (company-folder))
(defgeneric turn-file-into-a-page (company-folder file url-string type title name))
(defgeneric read-company-folder-description (company-folder))

(defmethod initialize-instance :after ((company-folder company-folder) &rest initargs)
  (declare (ignore initargs))
  (when (stringp (company-directory company-folder))
    (setf (company-directory company-folder)
	  (pathname (company-directory company-folder))))
  (let ((description-file (make-pathname :defaults (company-directory company-folder)
					  :name "description"
					  :type "data"
					  :version nil)))
    (setf (company-description-file company-folder) description-file)
    (update-company-folder company-folder)))


(defmethod update-company-folder ((company-folder company-folder))
  (flet ((get-url (list)
	   (assert list () "No data to get url from: ~a" list)
	   (let ((url (getf list :url)))
	     (assert url (url) "No url string specified for company-folder ~a."
		     company-folder)
	     url)))
    (setf (company-folder-description company-folder)
	  (read-company-folder-description company-folder))
    (let* ((base (getf (company-folder-description company-folder) :base))
	   (urls (getf (company-folder-description company-folder) :urls)))
      (assert (and base urls) ()
	      "Not all data specified for folder ~a." company-folder)
      (let ((company-name (getf base :name)))
        (when (slot-boundp (company-folder-overview-page company-folder) 'addresses-by-name)
          (assert (find company-name
                        (page-addresses-by-name (company-folder-overview-page company-folder))
                        :key #'address-name
                        :test #'string=)
                  ()
                  "Unknown company ~a." company-name))
        (setf (company-name company-folder) company-name
	      (company-url company-folder) (url:INTERN-URL (http:MERGE-URL (get-url base)
									   (http:LOCAL-CONTEXT))
							   :IF-DOES-NOT-EXIST :CREATE)
	      (company-pages company-folder)
	      (loop for line in urls
		    collect (destructuring-bind (&key file url type title name)
			                        line
			      (turn-file-into-a-page-or-url company-folder file
							    url type title name))))))))


(defmethod turn-file-into-a-page-or-url (company-folder file url type title name)
  (declare (ignore title name))
  (flet ((make-url (string)
	   (url:INTERN-URL (http:MERGE-URL string (http:LOCAL-CONTEXT))
			   :IF-DOES-NOT-EXIST :CREATE)))
    (when (stringp url) (setf url (make-url url)))
    (assert file (file) "Export which file?")
    (let* ((prototype (pathname file))
	   (pathname (make-pathname :defaults (company-description-file company-folder)
				    :name (pathname-name prototype)
				    :type (pathname-type prototype))))
      (assert (probe-file pathname) (pathname)
	      "File ~a not found for folder ~a."
	      pathname company-folder)
      (unless type (setf type (pathname-type pathname)))
      (cond ((equalp type "GIF")
	     (http:export-url url :gif-image
			      :pathname pathname))
	    ((equalp type "HTML")
	     (export-url url :html-file
			 :pathname pathname))
	    (t (cerror "Unknown export type: ~a" type))))))


(defmethod read-company-folder-description ((company-folder company-folder))
  (with-open-file (in (company-description-file company-folder) :direction :input)
    (read in)))



A description file then may look like this:

(:base (:name "Auto Leasing Service GmbH"
        :url "/als/firma/als/homepage.html")
 :urls ((:file "alslogo.gif" :url "/als/firma/als/alslogo.gif")
	(:file "alslogomini.gif" :url "/als/firma/als/alslogomini.gif")
	(:file "alsservermini.gif" :url "/als/firma/als/alsservermini.gif")
	(:file "karte.gif" :url "/als/firma/als/karte.gif")
	(:file "draussen.gif" :url "/als/firma/als/draussen.gif")
	(:file "homepage.html" :url "/als/firma/als/homepage.html")
	(:file "firma.html" :url "/als/firma/als/firma.html")
	(:file "filialen.html" :url "/als/firma/als/filialen.html")
	(:file "Leistung.html" :url "/als/firma/als/Leistung.html")
	(:file "Angebot.html" :url "/als/firma/als/Angebot.html")
	(:file "consulting.html" :url "/als/firma/als/consulting.html")))


Greetings,

Rainer Joswig

Rainer Joswig, Lavielle EDV Systemberatung GmbH & Co, Lotharstrasse 2b, D22041
Hamburg, Tel: +49 40 658088, Fax: +49 40 65808-202,
Email: joswig@lavielle.com , WWW: http://www.lavielle.com/~joswig/




References: