sorry a missing paren in stringify-session<br><br><div class="gmail_quote">On Jan 8, 2008 10:12 AM, Andrea Chiumenti <<a href="mailto:kiuma72@gmail.com">kiuma72@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi Edi,<br>are you interested in these modifications ?<br><br><br>(defgeneric request-realm (req)<br> (:documentation "Returns the realm under which the request has been sent.<br>A realm is used to group resources under a common 'place', and is used for registered web applications
<br>to have different or common sessions for a give user."))<br>(defgeneric (setf request-realm) (value req)<br> (:documentation "Sets the realm under which the request has been sent, where value is the realm name.
<br>A realm is used to group resources under a common 'place', and is used for registered web applications<br>to have different or common sessions for a give user."))<br><br>(defmethod request-realm ((req hunchentoot::request))
<br> (aux-request-value 'realm req))<br><br>(defmethod (setf request-realm) (value (req hunchentoot::request))<br> (setf (aux-request-value req) value))<br><br>(defclass session ()<br> ((session-id :initform (get-next-session-id)
<br> :reader session-id<br> :type integer<br> :documentation "The unique ID \(an INTEGER) of the session.")<br> (session-realm :initform (request-realm *request*)<br>
:reader session-realm
<br> :documentation "Defines a realm for this session.<br>A realm is injected by *request* aux parameter, and is used to group resources that will share this session object.")<br> (session-string :reader session-string
<br> :documentation "The session strings encodes enough<br>data to safely retrieve this session. It is sent to the browser as a<br>cookie value or as a GET parameter.")<br> (user-agent :initform (user-agent *request*)
<br> :reader session-user-agent<br> :documentation "The incoming 'User-Agent' header that<br>was sent when this session was created.")<br> (remote-addr :initform (real-remote-addr *request*)
<br> :reader session-remote-addr<br> :documentation "The remote IP address of the client when<br>this sessions was started as returned by REAL-REMOTE-ADDR.")<br> (session-start :initform (get-universal-time)
<br> :reader session-start<br> :documentation "The time this session was started.")<br> (last-click :initform (get-universal-time)<br> :reader session-last-click
<br> :documentation "The last time this session was used.")<br> (session-data :initarg :session-data<br> :initform nil<br> :reader session-data<br> :documentation "Data associated with this session -
<br>see SESSION-VALUE.")<br> (session-counter :initform 0<br> :reader session-counter<br> :documentation "The number of times this session<br>has been used.")<br> (max-time :initarg :max-time
<br> :initform *session-max-time*<br> :accessor session-max-time<br> :type fixnum<br> :documentation "The time \(in seconds) after which this<br>session expires if it's not used."))
<br> (:documentation "SESSION objects are automatically maintained<br>by Hunchentoot. They should not be created explicitly with<br>MAKE-INSTANCE but implicitly with START-SESSION. Note that<br>SESSION objects can only be created when the special variable
<br>*REQUEST* is bound to a REQUEST object."))<br><br>(defun encode-session-string (id user-agent remote-addr start realm)<br> "Create a uniquely encoded session string based on the values ID,<br>USER-AGENT, REMOTE-ADDR, and START"
<br> ;; *SESSION-SECRET* is used twice due to known theoretical<br> ;; vulnerabilities of MD5 encoding<br> (md5-hex (concatenate 'string<br> *session-secret*<br> (md5-hex (format nil "~A~A~@[~A~]~@[~A~]~A~@[~A~]"
<br> *session-secret*<br> id<br> (and *use-user-agent-for-sessions*<br> user-agent)
<br> (and *use-remote-addr-for-sessions*<br> remote-addr)<br> start<br> realm)))))
<br><br>(defun stringify-session (session)<br> "Creates a string representing the SESSION object SESSION. See<br>ENCODE-SESSION-STRING."<br> (encode-session-string (session-id session)<br> (session-user-agent session)
<br> (session-remote-addr session)<br> (session-start session)<br> (session-realm session))<br><br><br><br>(defun session-verify (request)<br> "Tries to get a session identifier from the cookies \(or
<br>alternatively from the GET parameters) sent by the client. This<br>identifier is then checked for validity against the REQUEST object<br>REQUEST. On success the corresponding session object \(if not too old)<br>is returned \(and updated). Otherwise NIL is returned."
<br> (let ((session-identifier (or (cookie-in *session-cookie-name* request)<br> (get-parameter *session-cookie-name* request))))<br> (unless (and session-identifier<br> (stringp session-identifier)
<br> (plusp (length session-identifier)))<br> (return-from session-verify nil))<br> (destructuring-bind (id-string session-string)<br> (split ":" session-identifier :limit 2)<br> (let* ((id (and (scan "^\\d+$" id-string)
<br> (parse-integer id-string<br> :junk-allowed t)))<br> (session (and id<br> (get-stored-session id)))<br> (user-agent (user-agent request))
<br> (remote-addr (remote-addr request)))<br> (unless (and session<br> session-string<br> (string= session-string<br> (session-string session))
<br> (string= session-string<br> (encode-session-string id<br> user-agent<br> (real-remote-addr request)
<br> (session-start session)<br> (request-realm request))))<br> (when *reply*<br> (cond ((null session)<br> (log-message :notice "No session for session identifier '~A' (User-Agent: '~A', IP: '~A')"
<br> session-identifier user-agent remote-addr))<br> (t<br> (log-message :warning "Fake session identifier '~A' (User-Agent: '~A', IP: '~A')"
<br> session-identifier user-agent remote-addr))))<br> (when session<br> (remove-session session))<br> (return-from session-verify nil))<br> (incf (slot-value session 'session-counter))
<br> (setf (slot-value session 'last-click) (get-universal-time))<br> session))))<br><br>(defun start-session (&optional (path "/"))<br> "Returns the current SESSION object. If there is no current session,
<br>creates one and updates the corresponding data structures. In this<br>case the function will also send a session cookie to the browser.<br>This function slightly differs from standard hunchentoot implementation because
<br>it can bound a session to a specific url inside the same server instance."<br> (count-session-usage)<br> (let ((session (session *request*)))<br> (when session<br> (return-from start-session session))<br>
(setf session (make-instance 'session)<br> (session *request*) session)<br> (with-lock (*session-data-lock*)<br> (setq *session-data* (acons (session-id session) session *session-data*)))<br> (set-cookie *session-cookie-name*
<br> :value (session-cookie-value session)<br> :path path)<br> (setq *session* session)))<div><div></div><div class="Wj3C7c"><br><br><div class="gmail_quote">On Jan 7, 2008 7:43 AM, Andrea Chiumenti <
<a href="mailto:kiuma72@gmail.com" target="_blank">
kiuma72@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Hello, Edi<br><br>I've spent the weekend on figuring out how to bind sessions for each application registered and finally I've found a solution!
<br>Before writing function redefinitions into my project, thing that I find a bit 'dirty', do you want me to post here my modifications so
<br>that sessions have their own realm and session cookies are bound to specific applications ?<br><br>Cheers,<br>kiuma<div><div></div><div><br><br><div class="gmail_quote">On Jan 7, 2008 5:45 AM, Edi Weitz <
<a href="mailto:edi@agharta.de" target="_blank">
edi@agharta.de</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div>On Sat, 5 Jan 2008 11:31:06 +0100, "Andrea Chiumenti" <
<a href="mailto:kiuma72@gmail.com" target="_blank">kiuma72@gmail.com</a>> wrote:<br><br>> now my question is *session-data* common to all hunchentoot servers<br>> instantiated on the same lisp instance ?<br><br>
</div>Yes, it's a global special variable.
<br><div><br>> Another question, now suppose we have in a single hunchentoot server<br>> serves two applications ( distinguished by their path ). It seems<br>> that hunchentoot shares the session between these two, and sometime
<br>> it's good, but what should I do if I want applications to share<br>> different sessions ?<br><br></div>There's currently no mechanism for this. Unless you write your own,<br>of course.<br>_______________________________________________
<br><div><div></div><div>tbnl-devel site list<br><a href="mailto:tbnl-devel@common-lisp.net" target="_blank">tbnl-devel@common-lisp.net</a><br><a href="http://common-lisp.net/mailman/listinfo/tbnl-devel" target="_blank">
http://common-lisp.net/mailman/listinfo/tbnl-devel
</a><br></div></div></blockquote></div><br>
</div></div></blockquote></div><br>
</div></div></blockquote></div><br>