1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; Package: wol -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
6 ;;;; Purpose: URI functions for wol
7 ;;;; Programmer: Kevin M. Rosenberg
8 ;;;; Date Started: July 2003
10 ;;;; $Id: uri.lisp,v 1.6 2003/08/08 23:40:13 kevin Exp $
12 ;;;; This file and Wol are Copyright (c) 2003 by Kevin M. Rosenberg
13 ;;;; *************************************************************************
17 (defun uri->recode-uri-sans-session-id (uri)
18 (let ((parsed-path (puri:uri-parsed-path uri)))
20 ((and (eq :absolute (first parsed-path))
21 (is-raw-session-id (second parsed-path)))
22 (values (copy-uri uri :place t
24 (list* :absolute (cddr parsed-path)))
25 (raw-session-id->session-id (second parsed-path))))
29 (defun request-cookies (req)
30 (aif (aserve-request req)
31 (net.aserve:get-cookie-values it)
32 (loop for h in (request-headers req)
33 when (eq :cookie (car h))
36 (defun cookie-session-key (ent cookies)
37 (let ((name (project-name (entity-project ent))))
38 (cdr (assoc name cookies :test #'string-equal))))
40 (defun url-session-key (url)
41 "Return a session key encoded in a URL"
44 (defun compute-uris (req ent)
45 "Compute URI's of a request"
46 (compute-session req ent)
47 (multiple-value-bind (page plists query)
48 (decode-url (puri:uri-path (request-raw-uri req)))
50 (setf (request-page req) (base-page-name page ent)))
52 (setf (request-plist req) (car plists))
53 (setf (request-next-plists req) (cdr plists))
55 (awhen (getf (request-plist req) :page)
56 (setf (request-page req) it))))
57 (setf (request-uri-query req) query)))
62 (defun base-page-name (page ent)
63 "Return the base page name for a html url"
64 (let ((len-prefix (length (project-prefix (entity-project ent)))))
65 (assert (>= (length page) len-prefix))
66 (string-strip-ending (subseq page len-prefix)
69 (defun split-plist-url (url)
70 (string-delimited-string-to-list url +plist-header+))
72 (defun decode-url (url)
73 "Decode raw url. Returns (values `<pagename>.html' list-of-plists query)"
75 (qsplit (delimited-string-to-list url #\?))
77 (split (split-plist-url (car qsplit)))
79 (when (and (plusp (length (car split)))
80 (not (string= +full-asp-header+ (car split)))
81 (not (string-starts-with +full-asp-header+ (car split))))
83 (dolist (elem (cdr split))
84 (push (url-string-to-plist elem) plists))
85 (values page-name (nreverse plists) query)))
89 (defun make-wol-url (page req ent &optional plist)
90 (let ((session (websession-from-req req))
91 (url-plist (append (list :page page) plist))
92 (prefix (project-prefix (entity-project ent))))
95 (websession-key session)
96 (eq :url (websession-method session)))
97 (format nil "/~~~A~~/" (websession-key session))
101 (concatenate 'string page ".html")
104 (concatenate 'string +plist-header+
105 (plist-to-url-string url-plist)))))))
110 (defun plist-to-url-string (plist &key (base64 t))
111 (let ((str (plist-to-compressed-string plist)))
113 (string-to-base64-string str :uri t)
114 (escape-uri-field str))))
116 (defun url-string-to-plist (str &key (base64 t))
117 (let ((decode (if base64
118 (base64-string-to-string str :uri t)
119 (unescape-uri-field str))))
121 (ignore-errors (compressed-string-to-plist decode)))))
123 (defun plist-to-compressed-string (plist)
124 "Decode an encoded plist"
125 (assert (evenp (length plist)))
127 (list plist (cddr list)))
129 (prin1-to-string (nreverse output)))
130 (push (compress-elem (car list)) output)
131 (push (cadr list) output)))
133 (defun compress-elem (elem)
134 "Encode a plist elem"
158 (defun compressed-string-to-plist (encoded-str)
159 (let ((encoded (ignore-errors (read-from-string encoded-str)))
162 (cmsg "invalid encoded string")
164 (gen-invalid-encoded-str encoded-str)
166 (assert (evenp (length encoded)))
167 (do* ((elist encoded (cddr elist)))
168 ((null elist) (nreverse output))
169 (push (decompress-elem (car elist)) output)
170 (push (cadr elist) output))))
172 (defun decompress-elem (elem)
183 ;; For posting to lookup-func1