1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; Package: modlisp -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
6 ;;;; Purpose: Utility functions for modlisp package
7 ;;;; Programmer: Kevin M. Rosenberg
8 ;;;; Date Started: Dec 2002
10 ;;;; $Id: base.lisp,v 1.3 2003/07/05 00:51:04 kevin Exp $
11 ;;;; *************************************************************************
13 (in-package #:modlisp)
16 (let ((*listener-socket* nil)
17 (*listener-process* nil))
19 (defun modlisp-start (&key (port +default-apache-port+)
20 (function 'demo-apache-command-processor))
22 (make-socket-server (next-server-name) function port
23 :format :text :wait nil)
25 (format t "~&Error while trying to start modlisp server~& ~A" e)
26 (decf *listener-count*)
28 (:no-error (process socket)
29 (setq *listener-socket* socket)
30 (setq *listener-process* process)
33 (defun modlisp-stop ()
34 (when *listener-process*
35 (format t "~&; killing modlisp server process ~A~%" *listener-process*)
38 #+sbcl (sb-thread:destroy-thread *listener-process*)
39 #+cmucl (mp:destroy-process *listener-process*)
40 #+allegro (mp:process-kill *listener-process*)
41 #+allegro (mp:process-allow-schedule)
42 #+lispworks (mp:process-kill *listener-process*))
44 (format t "~&Error while trying to kill modlisp server~& ~A" e))
46 (declare (ignore res))
47 (setq *listener-process* nil))))
48 (when *listener-socket*
49 (ignore-errors (close *listener-socket*))
50 (setq *listener-socket* nil)))
54 (defun next-server-name ()
55 (format nil "modlisp-socket-server-~d" (incf *listener-count*)))
57 (defun next-worker-name ()
58 (format nil "modlisp-worker-~d" (incf *worker-count*)))
60 (let ((*number-server-requests* 0)
61 (*number-worker-requests* 0)
62 (*close-apache-socket* t))
64 (defun apache-command-issuer (*apache-socket* processor-fun)
65 "generates commands from apache, issues commands to processor-fun"
68 (setq *number-worker-requests* 0)
69 (do ((command (read-apache-command) (read-apache-command)))
70 ((null command) 'done)
71 (funcall processor-fun command)
72 (force-output *apache-socket*)
73 (incf *number-worker-requests*)
74 (incf *number-server-requests*)
75 (when *close-apache-socket*
77 (close *apache-socket*)))
79 (defun get-number-worker-requests ()
80 *number-worker-requests*)
82 (defun get-number-server-requests ()
83 *number-server-requests*)
85 (defun set-close-apache-socket (close?)
86 (setq *close-apache-socket* close?))
90 (defun read-apache-command ()
92 (let* ((header (read-apache-header))
93 (content-length (cdr (assoc "content-length" header :test #'equal)))
94 (content (when content-length
96 (parse-integer content-length :junk-allowed t)))))
98 (read-sequence content *apache-socket*)
99 (push (cons "posted-content" content) header))
102 (defun read-apache-header ()
103 (loop for key = (read-line *apache-socket* nil nil)
105 (string-not-equal key "end")
107 for value = (read-line *apache-socket* nil nil)
108 collect (cons key value)))
110 (defun write-header-line (key value)
111 (write-string key *apache-socket*)
112 (write-char #\NewLine *apache-socket*)
113 (write-string value *apache-socket*)
114 (write-char #\NewLine *apache-socket*))
116 (defun header-value (command key)
117 (cdr (assoc key command :test #'string=)))