r7061: initial property settings
[wol.git] / project.lisp
index 346ccd31b302744946e6ba62d18290a75fbff7e5..ed1ef4892c8a0beb42db44cbe477bbc1f3c28290 100644 (file)
@@ -7,7 +7,7 @@
 ;;;; Programmer:    Kevin M. Rosenberg
 ;;;; Date Started:  July 2003
 ;;;;
-;;;; $Id: project.lisp,v 1.7 2003/08/08 09:03:45 kevin Exp $
+;;;; $Id$
 ;;;;
 ;;;; This file and Wol are Copyright (c) 2001-2003 by Kevin M. Rosenberg
 ;;;; *************************************************************************
 (in-package #:wol)
 
 (defun wol-project (name &key (project-prefix "/") map index
-                   (sessions t) (session-lifetime 18000)
-                   (reap-interval 300) server
-                   (connector :modlisp))
+                             (sessions t) (session-lifetime 18000)
+                             (reap-interval 300) server
+                             (connector :modlisp)
+                             timeout)
   (unless server
     (setq server 
          (ecase connector
@@ -53,7 +54,8 @@
       (:aserve
        (net.aserve:publish-prefix :prefix project-prefix
                                  :server server
-                                 :function 'wol-aserve-processor)))
+                                 :function 'wol-aserve-processor
+                                 :timeout timeout)))
   
   (if sessions
        (when (null (sessions (session-master project)))
@@ -65,7 +67,7 @@
     (setq *reap-interval* reap-interval)
     (when (and sessions (null *reaper-process*))
       (setq *reaper-process* (start-reaper)))))
-    
+
 (defun wol-ml-processor (command)
   "Processes an incoming modlisp command"
   (let* ((req (command->request command
 
 (defun wol-aserve-processor (as-req as-ent)
   "Processes an incoming modlisp command"
-  (let* ((req (make-request-from-aserve as-req))
-        (ent (make-entity-from-aserve req as-ent)))
-    (dispatch-request req ent)))
-
-(defun make-request-from-aserve (as-req)
-  (make-instance 'http-request
-                :method (net.aserve:request-method as-req)
-                ;;:host (net.aserve:request-host as-req)
-                :raw-uri (puri:intern-uri
-                          (net.uri:render-uri
-                           (net.aserve:request-raw-uri as-req) nil))
-                :uri (puri:intern-uri
-                      (net.uri:render-uri
-                       (net.aserve:request-uri as-req) nil))
-                :protocol (net.aserve:request-protocol as-req)
-                :protocol-string
-                (net.aserve:request-protocol-string as-req)
-                :posted-content (net.aserve::request-request-body as-req)
-                :socket (net.aserve:request-socket as-req)
-                :aserve-server net.aserve:*wserver*
-                :aserve-request as-req))
-
-(defun make-entity-from-aserve (req as-ent)
-  (make-instance 'entity
-                :project (find-project-for-request req)
-                :aserve-entity as-ent))
+  (multiple-value-bind (req ent) (make-request/ent-from-aserve as-req as-ent)
+    (if (entity-project ent)
+       (dispatch-request req ent)
+      (no-url-handler req ent))))
+
+    
+(defun make-request/ent-from-aserve (as-req as-ent)
+  (let* ((req (make-instance
+              'http-request
+              :method (net.aserve:request-method as-req)
+              ;;:host (net.aserve:request-host as-req)
+              :raw-request (net.aserve::request-raw-request as-req)
+              :raw-uri (puri:intern-uri
+                        (net.uri:render-uri
+                        (net.aserve:request-raw-uri as-req) nil))
+              :decoded-uri-path
+              (net.aserve::request-decoded-uri-path as-req)
+              :uri (puri:intern-uri
+                    (net.uri:render-uri
+                    (net.aserve:request-uri as-req) nil))
+              :protocol (net.aserve:request-protocol as-req)
+              :protocol-string
+              (net.aserve:request-protocol-string as-req)
+              :posted-content (net.aserve::request-request-body as-req)
+              :socket (net.aserve:request-socket as-req)
+              :headers (net.aserve::request-headers as-req)
+              :aserve-server net.aserve:*wserver*
+              :aserve-request as-req))
+        (project (find-project-for-request req))
+        (ent (make-instance 'entity :project project
+                            :aserve-entity as-ent)))
+    (values req ent)))
 
 
 (defun command->request (command &key ml-server)
   (let ((req
         (make-instance 'http-request
           :host (header-value command :host)
-          :raw-uri  (aif (ignore-errors
-                          (puri:intern-uri (header-value command :url)))
-                         it
-                         (header-value command :url))
-          :uri (aif (ignore-errors
-                     (puri:intern-uri (command->uri command)))
-                    it
-                    (command->uri command))
+          :raw-request (header-value command :url) 
+          :raw-uri  (puri:intern-uri (header-value command :url))
+          :uri (puri:intern-uri (command->uri command))
           :protocol (ensure-keyword
                      (header-value command :server-protocol))
           :protocol-string (header-value command :server-protocol)
           :headers command
           :socket *modlisp-socket*
           :ml-server ml-server)))
+    (awhen (request-raw-uri req)
+          (setf (request-decoded-uri-path req) (puri:uri-path it)))
     req))
 
 (defun header-slot-value (req slot)
          (header-value command :url)))
 
 (defun is-index-request (req ent)
-  (string= (puri:uri-path (request-raw-uri req)) 
+  (string= (request-decoded-uri-path req)
           (project-prefix (entity-project ent))))
 
+(defun set-cookie (req ent)
+  (let ((session (websession-from-req req)))
+    (when (and session (websession-key session)
+              (not (eq :url (websession-method session))))
+      (let ((proj (entity-project ent)))
+       (ecase (project-connector proj)
+         (:aserve
+          (net.aserve:set-cookie-header (aserve-request req)
+                                        :name (project-name
+                                               (entity-project ent))
+                                        :expires :never
+                                        :secure nil
+                                        :domain ".b9.com"
+                                        :value (websession-key
+                                                (websession-from-req req))
+                                        :path "/"))
+         (:modlisp
+          ;; fixme
+          ))))))
+
+
 (defun redirect-entity (page req ent &optional plist)
   (let ((proj (entity-project ent))
-       (url (make-wol-url page ent plist)))
+       (url (render-uri
+             (copy-uri (request-uri req)
+                       :path (make-wol-url page req ent plist))
+             nil)))
     (ecase (project-connector proj)
       (:aserve
        (net.aserve:with-http-response 
           ((aserve-request req) 
            (entity-aserve-entity ent)
-           :response net.aserve:*response-moved-permanently*)
+           :response net.aserve:*response-temporary-redirect*)
+        (set-cookie req ent)
         (net.aserve:with-http-body 
             ((aserve-request req) 
              (entity-aserve-entity ent)
        (redirect-to-location url)))))
 
 (defun dispatch-request (req ent)
+  (setq *req* req)
+  (setq *ent* ent)
   (let ((proj (entity-project ent)))
     (if (is-index-request req ent)
        (redirect-entity (project-index proj) req ent)
        (progn
-         (request-decompile-uri req ent)
-         (compute-session req ent)
+         (compute-uris req ent)
          (dispatch-to-handler req ent)))))
 
 (defun make-entity (&key project)
 (defun find-project-for-request (req)
   (maphash (lambda (name project)
             (declare (ignore name))
-            (when (request-matches-prefix req (project-prefix project))
+            (when (and (eq (project-server project)
+                           (or (request-aserve-server req)
+                               (request-ml-server req)))
+                       (request-matches-prefix
+                        req (project-prefix project)))
               (return-from find-project-for-request project)))
           *active-projects*))
 
 (defun request-matches-prefix (req prefix)
   "Returns project if request matches project"
-  (string-starts-with prefix (puri:uri-path (request-raw-uri req))))
+  (string-starts-with prefix (request-decoded-uri-path req)))
 
 
 (defun dispatch-to-handler (req ent)
 
 
 (defmacro with-wol-page ((req ent
-                         &key (format :html) (precompute t) headers)
+                         &key (format :html) (precompute t) headers
+                              (response-code 200)
+                              timeout)
                         &body body)
-  `(ecase (project-connector (entity-project ,ent))
-     (:aserve
+  `(if (request-aserve-server ,req)
       (net.aserve:with-http-response 
          ((aserve-request ,req) 
           (entity-aserve-entity ,ent)
-          :content-type (ml::format-string ,format))
-       (net.aserve:with-http-body 
-           ((aserve-request ,req) 
-            (entity-aserve-entity ,ent)
-            :headers ,headers)
-         (let ((*html-stream* net.html.generator:*html-stream*))
-           ,@body))))
-     (:modlisp
-      (%with-wol-page (,req ,ent :format ,format :precompute ,precompute
-                           :headers ,headers)
-                     ,@body))))
+          :content-type (ml::format-string ,format)
+          :timeout ,timeout
+          :response
+          (case ,response-code
+            (302 net.aserve::*response-moved-permanently*)
+            (307 net.aserve::*response-temporary-redirect*)
+            (404 net.aserve::*response-not-found*)
+            (otherwise net.aserve::*response-ok*)))
+       (set-cookie ,req ,ent)
+         (net.aserve:with-http-body 
+             ((aserve-request ,req) 
+              (entity-aserve-entity ,ent)
+              :headers ,headers)
+           (let ((*html-stream* net.html.generator:*html-stream*))
+             ,@body)))
+     (%with-wol-page (,req ,ent :format ,format :precompute ,precompute
+                          :headers ,headers 
+                          :response-string 
+                          (case ,response-code
+                            (302 "302 Moved Permanently")
+                            (307 "307 Temporary Redirect")
+                            (404 "404 Not Found")
+                             (otherwise "200 OK")))
+                    ,@body)))
   
 
 (defmacro %with-wol-page ((req ent
-                             &key (format :html) (precompute t) headers)
+                          &key (format :html) (precompute t) headers
+                               (response-string "200 OK"))
                         &body body)
   (declare (ignore req ent))
   (let ((fmt (gensym "FMT-"))
           (,precomp ,precompute)
           ,result ,outstr ,stream)
        (declare (ignorable ,stream))
-       (write-header-line "Status" "200 OK")
+       (write-header-line "Status" ,response-string)
        (write-header-line "Content-Type" (ml::format-string ,fmt))
        (dolist (,hdr ,headers)
         (write-header-line (car ,hdr) (cdr ,hdr)))
 
 
 (defun no-url-handler (req ent)
-  (with-wol-page (req ent)
+  (with-wol-page (req ent :response-code 404)
     (html
      (:html
       (:head