Artifact 49ca0d00a6f2892bde0d5fdcc0f49fdfacca9f17:


0000: 3b 3b 3b 0a 3b 3b 3b 20 63 6f 6f 6b 69 65 2e 73  ;;;.;;; cookie.s
0010: 63 6d 20 2d 20 70 61 72 73 65 20 61 6e 64 20 63  cm - parse and c
0020: 6f 6e 73 74 72 75 63 74 20 68 74 74 70 20 73 74  onstruct http st
0030: 61 74 65 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 0a  ate information.
0040: 3b 3b 3b 20 20 0a 3b 3b 3b 20 20 20 43 6f 70 79  ;;;  .;;;   Copy
0050: 72 69 67 68 74 20 28 63 29 20 32 30 30 30 2d 32  right (c) 2000-2
0060: 30 30 33 20 53 68 69 72 6f 20 4b 61 77 61 69 2c  003 Shiro Kawai,
0070: 20 41 6c 6c 20 72 69 67 68 74 73 20 72 65 73 65   All rights rese
0080: 72 76 65 64 2e 0a 3b 3b 3b 20 20 20 0a 3b 3b 3b  rved..;;;   .;;;
0090: 20 20 20 52 65 64 69 73 74 72 69 62 75 74 69 6f     Redistributio
00a0: 6e 20 61 6e 64 20 75 73 65 20 69 6e 20 73 6f 75  n and use in sou
00b0: 72 63 65 20 61 6e 64 20 62 69 6e 61 72 79 20 66  rce and binary f
00c0: 6f 72 6d 73 2c 20 77 69 74 68 20 6f 72 20 77 69  orms, with or wi
00d0: 74 68 6f 75 74 0a 3b 3b 3b 20 20 20 6d 6f 64 69  thout.;;;   modi
00e0: 66 69 63 61 74 69 6f 6e 2c 20 61 72 65 20 70 65  fication, are pe
00f0: 72 6d 69 74 74 65 64 20 70 72 6f 76 69 64 65 64  rmitted provided
0100: 20 74 68 61 74 20 74 68 65 20 66 6f 6c 6c 6f 77   that the follow
0110: 69 6e 67 20 63 6f 6e 64 69 74 69 6f 6e 73 0a 3b  ing conditions.;
0120: 3b 3b 20 20 20 61 72 65 20 6d 65 74 3a 0a 3b 3b  ;;   are met:.;;
0130: 3b 20 20 20 0a 3b 3b 3b 20 20 20 31 2e 20 52 65  ;   .;;;   1. Re
0140: 64 69 73 74 72 69 62 75 74 69 6f 6e 73 20 6f 66  distributions of
0150: 20 73 6f 75 72 63 65 20 63 6f 64 65 20 6d 75 73   source code mus
0160: 74 20 72 65 74 61 69 6e 20 74 68 65 20 61 62 6f  t retain the abo
0170: 76 65 20 63 6f 70 79 72 69 67 68 74 0a 3b 3b 3b  ve copyright.;;;
0180: 20 20 20 20 20 20 6e 6f 74 69 63 65 2c 20 74 68        notice, th
0190: 69 73 20 6c 69 73 74 20 6f 66 20 63 6f 6e 64 69  is list of condi
01a0: 74 69 6f 6e 73 20 61 6e 64 20 74 68 65 20 66 6f  tions and the fo
01b0: 6c 6c 6f 77 69 6e 67 20 64 69 73 63 6c 61 69 6d  llowing disclaim
01c0: 65 72 2e 0a 3b 3b 3b 20 20 0a 3b 3b 3b 20 20 20  er..;;;  .;;;   
01d0: 32 2e 20 52 65 64 69 73 74 72 69 62 75 74 69 6f  2. Redistributio
01e0: 6e 73 20 69 6e 20 62 69 6e 61 72 79 20 66 6f 72  ns in binary for
01f0: 6d 20 6d 75 73 74 20 72 65 70 72 6f 64 75 63 65  m must reproduce
0200: 20 74 68 65 20 61 62 6f 76 65 20 63 6f 70 79 72   the above copyr
0210: 69 67 68 74 0a 3b 3b 3b 20 20 20 20 20 20 6e 6f  ight.;;;      no
0220: 74 69 63 65 2c 20 74 68 69 73 20 6c 69 73 74 20  tice, this list 
0230: 6f 66 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 6e  of conditions an
0240: 64 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  d the following 
0250: 64 69 73 63 6c 61 69 6d 65 72 20 69 6e 20 74 68  disclaimer in th
0260: 65 0a 3b 3b 3b 20 20 20 20 20 20 64 6f 63 75 6d  e.;;;      docum
0270: 65 6e 74 61 74 69 6f 6e 20 61 6e 64 2f 6f 72 20  entation and/or 
0280: 6f 74 68 65 72 20 6d 61 74 65 72 69 61 6c 73 20  other materials 
0290: 70 72 6f 76 69 64 65 64 20 77 69 74 68 20 74 68  provided with th
02a0: 65 20 64 69 73 74 72 69 62 75 74 69 6f 6e 2e 0a  e distribution..
02b0: 3b 3b 3b 20 20 0a 3b 3b 3b 20 20 20 33 2e 20 4e  ;;;  .;;;   3. N
02c0: 65 69 74 68 65 72 20 74 68 65 20 6e 61 6d 65 20  either the name 
02d0: 6f 66 20 74 68 65 20 61 75 74 68 6f 72 73 20 6e  of the authors n
02e0: 6f 72 20 74 68 65 20 6e 61 6d 65 73 20 6f 66 20  or the names of 
02f0: 69 74 73 20 63 6f 6e 74 72 69 62 75 74 6f 72 73  its contributors
0300: 0a 3b 3b 3b 20 20 20 20 20 20 6d 61 79 20 62 65  .;;;      may be
0310: 20 75 73 65 64 20 74 6f 20 65 6e 64 6f 72 73 65   used to endorse
0320: 20 6f 72 20 70 72 6f 6d 6f 74 65 20 70 72 6f 64   or promote prod
0330: 75 63 74 73 20 64 65 72 69 76 65 64 20 66 72 6f  ucts derived fro
0340: 6d 20 74 68 69 73 0a 3b 3b 3b 20 20 20 20 20 20  m this.;;;      
0350: 73 6f 66 74 77 61 72 65 20 77 69 74 68 6f 75 74  software without
0360: 20 73 70 65 63 69 66 69 63 20 70 72 69 6f 72 20   specific prior 
0370: 77 72 69 74 74 65 6e 20 70 65 72 6d 69 73 73 69  written permissi
0380: 6f 6e 2e 0a 3b 3b 3b 20 20 0a 3b 3b 3b 20 20 20  on..;;;  .;;;   
0390: 54 48 49 53 20 53 4f 46 54 57 41 52 45 20 49 53  THIS SOFTWARE IS
03a0: 20 50 52 4f 56 49 44 45 44 20 42 59 20 54 48 45   PROVIDED BY THE
03b0: 20 43 4f 50 59 52 49 47 48 54 20 48 4f 4c 44 45   COPYRIGHT HOLDE
03c0: 52 53 20 41 4e 44 20 43 4f 4e 54 52 49 42 55 54  RS AND CONTRIBUT
03d0: 4f 52 53 0a 3b 3b 3b 20 20 20 22 41 53 20 49 53  ORS.;;;   "AS IS
03e0: 22 20 41 4e 44 20 41 4e 59 20 45 58 50 52 45 53  " AND ANY EXPRES
03f0: 53 20 4f 52 20 49 4d 50 4c 49 45 44 20 57 41 52  S OR IMPLIED WAR
0400: 52 41 4e 54 49 45 53 2c 20 49 4e 43 4c 55 44 49  RANTIES, INCLUDI
0410: 4e 47 2c 20 42 55 54 20 4e 4f 54 0a 3b 3b 3b 20  NG, BUT NOT.;;; 
0420: 20 20 4c 49 4d 49 54 45 44 20 54 4f 2c 20 54 48    LIMITED TO, TH
0430: 45 20 49 4d 50 4c 49 45 44 20 57 41 52 52 41 4e  E IMPLIED WARRAN
0440: 54 49 45 53 20 4f 46 20 4d 45 52 43 48 41 4e 54  TIES OF MERCHANT
0450: 41 42 49 4c 49 54 59 20 41 4e 44 20 46 49 54 4e  ABILITY AND FITN
0460: 45 53 53 20 46 4f 52 0a 3b 3b 3b 20 20 20 41 20  ESS FOR.;;;   A 
0470: 50 41 52 54 49 43 55 4c 41 52 20 50 55 52 50 4f  PARTICULAR PURPO
0480: 53 45 20 41 52 45 20 44 49 53 43 4c 41 49 4d 45  SE ARE DISCLAIME
0490: 44 2e 20 49 4e 20 4e 4f 20 45 56 45 4e 54 20 53  D. IN NO EVENT S
04a0: 48 41 4c 4c 20 54 48 45 20 43 4f 50 59 52 49 47  HALL THE COPYRIG
04b0: 48 54 0a 3b 3b 3b 20 20 20 4f 57 4e 45 52 20 4f  HT.;;;   OWNER O
04c0: 52 20 43 4f 4e 54 52 49 42 55 54 4f 52 53 20 42  R CONTRIBUTORS B
04d0: 45 20 4c 49 41 42 4c 45 20 46 4f 52 20 41 4e 59  E LIABLE FOR ANY
04e0: 20 44 49 52 45 43 54 2c 20 49 4e 44 49 52 45 43   DIRECT, INDIREC
04f0: 54 2c 20 49 4e 43 49 44 45 4e 54 41 4c 2c 0a 3b  T, INCIDENTAL,.;
0500: 3b 3b 20 20 20 53 50 45 43 49 41 4c 2c 20 45 58  ;;   SPECIAL, EX
0510: 45 4d 50 4c 41 52 59 2c 20 4f 52 20 43 4f 4e 53  EMPLARY, OR CONS
0520: 45 51 55 45 4e 54 49 41 4c 20 44 41 4d 41 47 45  EQUENTIAL DAMAGE
0530: 53 20 28 49 4e 43 4c 55 44 49 4e 47 2c 20 42 55  S (INCLUDING, BU
0540: 54 20 4e 4f 54 20 4c 49 4d 49 54 45 44 0a 3b 3b  T NOT LIMITED.;;
0550: 3b 20 20 20 54 4f 2c 20 50 52 4f 43 55 52 45 4d  ;   TO, PROCUREM
0560: 45 4e 54 20 4f 46 20 53 55 42 53 54 49 54 55 54  ENT OF SUBSTITUT
0570: 45 20 47 4f 4f 44 53 20 4f 52 20 53 45 52 56 49  E GOODS OR SERVI
0580: 43 45 53 3b 20 4c 4f 53 53 20 4f 46 20 55 53 45  CES; LOSS OF USE
0590: 2c 20 44 41 54 41 2c 20 4f 52 0a 3b 3b 3b 20 20  , DATA, OR.;;;  
05a0: 20 50 52 4f 46 49 54 53 3b 20 4f 52 20 42 55 53   PROFITS; OR BUS
05b0: 49 4e 45 53 53 20 49 4e 54 45 52 52 55 50 54 49  INESS INTERRUPTI
05c0: 4f 4e 29 20 48 4f 57 45 56 45 52 20 43 41 55 53  ON) HOWEVER CAUS
05d0: 45 44 20 41 4e 44 20 4f 4e 20 41 4e 59 20 54 48  ED AND ON ANY TH
05e0: 45 4f 52 59 20 4f 46 0a 3b 3b 3b 20 20 20 4c 49  EORY OF.;;;   LI
05f0: 41 42 49 4c 49 54 59 2c 20 57 48 45 54 48 45 52  ABILITY, WHETHER
0600: 20 49 4e 20 43 4f 4e 54 52 41 43 54 2c 20 53 54   IN CONTRACT, ST
0610: 52 49 43 54 20 4c 49 41 42 49 4c 49 54 59 2c 20  RICT LIABILITY, 
0620: 4f 52 20 54 4f 52 54 20 28 49 4e 43 4c 55 44 49  OR TORT (INCLUDI
0630: 4e 47 0a 3b 3b 3b 20 20 20 4e 45 47 4c 49 47 45  NG.;;;   NEGLIGE
0640: 4e 43 45 20 4f 52 20 4f 54 48 45 52 57 49 53 45  NCE OR OTHERWISE
0650: 29 20 41 52 49 53 49 4e 47 20 49 4e 20 41 4e 59  ) ARISING IN ANY
0660: 20 57 41 59 20 4f 55 54 20 4f 46 20 54 48 45 20   WAY OUT OF THE 
0670: 55 53 45 20 4f 46 20 54 48 49 53 0a 3b 3b 3b 20  USE OF THIS.;;; 
0680: 20 20 53 4f 46 54 57 41 52 45 2c 20 45 56 45 4e    SOFTWARE, EVEN
0690: 20 49 46 20 41 44 56 49 53 45 44 20 4f 46 20 54   IF ADVISED OF T
06a0: 48 45 20 50 4f 53 53 49 42 49 4c 49 54 59 20 4f  HE POSSIBILITY O
06b0: 46 20 53 55 43 48 20 44 41 4d 41 47 45 2e 0a 3b  F SUCH DAMAGE..;
06c0: 3b 3b 20 20 0a 3b 3b 3b 20 20 50 6f 72 74 65 64  ;;  .;;;  Ported
06d0: 20 74 6f 20 43 68 69 63 6b 65 6e 20 62 79 20 52   to Chicken by R
06e0: 65 65 64 20 53 68 65 72 69 64 61 6e 0a 3b 3b 3b  eed Sheridan.;;;
06f0: 0a 0a 3b 3b 20 50 61 72 73 65 72 20 61 6e 64 20  ..;; Parser and 
0700: 63 6f 6e 73 74 72 75 63 74 6f 72 20 6f 66 20 68  constructor of h
0710: 74 74 70 20 22 43 6f 6f 6b 69 65 73 22 20 64 65  ttp "Cookies" de
0720: 66 69 6e 65 64 20 69 6e 0a 3b 3b 20 52 46 43 20  fined in.;; RFC 
0730: 32 39 36 35 20 48 54 54 50 20 73 74 61 74 65 20  2965 HTTP state 
0740: 6d 61 6e 61 67 65 6d 6e 65 74 20 6d 65 63 68 61  managemnet mecha
0750: 6e 69 73 6d 0a 3b 3b 20 20 20 3c 66 74 70 3a 2f  nism.;;   <ftp:/
0760: 2f 66 74 70 2e 69 73 69 2e 65 64 75 2f 69 6e 2d  /ftp.isi.edu/in-
0770: 6e 6f 74 65 73 2f 72 66 63 32 39 36 35 2e 74 78  notes/rfc2965.tx
0780: 74 3e 0a 3b 3b 20 53 65 65 20 61 6c 73 6f 0a 3b  t>.;; See also.;
0790: 3b 20 52 46 43 20 32 39 36 34 20 55 73 65 20 6f  ; RFC 2964 Use o
07a0: 66 20 48 54 54 50 20 73 74 61 74 65 20 6d 61 6e  f HTTP state man
07b0: 61 67 65 6d 65 6e 74 0a 3b 3b 20 20 20 3c 66 74  agement.;;   <ft
07c0: 70 3a 2f 2f 66 74 70 2e 69 73 69 2e 65 64 75 2f  p://ftp.isi.edu/
07d0: 69 6e 2d 6e 6f 74 65 73 2f 72 66 63 32 39 36 34  in-notes/rfc2964
07e0: 2e 74 78 74 3e 0a 3b 3b 20 54 68 65 20 70 61 72  .txt>.;; The par
07f0: 73 65 72 20 61 6c 73 6f 20 73 75 70 70 6f 72 74  ser also support
0800: 73 20 74 68 65 20 6f 6c 64 20 4e 65 74 73 63 61  s the old Netsca
0810: 70 65 20 73 70 65 63 0a 3b 3b 20 20 20 3c 68 74  pe spec.;;   <ht
0820: 74 70 3a 2f 2f 77 77 77 2e 6e 65 74 73 63 61 70  tp://www.netscap
0830: 65 2e 63 6f 6d 2f 6e 65 77 73 72 65 66 2f 73 74  e.com/newsref/st
0840: 64 2f 63 6f 6f 6b 69 65 5f 73 70 65 63 2e 68 74  d/cookie_spec.ht
0850: 6d 6c 3e 0a 0a 28 64 65 63 6c 61 72 65 20 28 75  ml>..(declare (u
0860: 6e 69 74 20 63 6f 6f 6b 69 65 29 29 0a 28 72 65  nit cookie)).(re
0870: 71 75 69 72 65 2d 65 78 74 65 6e 73 69 6f 6e 20  quire-extension 
0880: 73 72 66 69 2d 31 20 73 72 66 69 2d 31 33 20 73  srfi-1 srfi-13 s
0890: 72 66 69 2d 31 34 20 72 65 67 65 78 29 0a 3b 3b  rfi-14 regex).;;
08a0: 20 28 75 73 65 20 20 73 72 66 69 2d 31 20 73 72   (use  srfi-1 sr
08b0: 66 69 2d 31 33 20 73 72 66 69 2d 31 34 20 72 65  fi-13 srfi-14 re
08c0: 67 65 78 29 0a 3b 3b 20 28 64 65 63 6c 61 72 65  gex).;; (declare
08d0: 20 28 65 78 70 6f 72 74 20 70 61 72 73 65 2d 63   (export parse-c
08e0: 6f 6f 6b 69 65 2d 73 74 72 69 6e 67 20 63 6f 6e  ookie-string con
08f0: 73 74 72 75 63 74 2d 63 6f 6f 6b 69 65 2d 73 74  struct-cookie-st
0900: 72 69 6e 67 29 29 0a 0a 3b 3b 20 23 3e 0a 3b 3b  ring))..;; #>.;;
0910: 20 23 69 6e 63 6c 75 64 65 20 3c 74 69 6d 65 2e   #include <time.
0920: 68 3e 0a 3b 3b 20 3c 23 0a 3b 3b 20 0a 3b 3b 20  h>.;; <#.;; .;; 
0930: 28 64 65 66 69 6e 65 20 66 6d 74 2d 74 69 6d 65  (define fmt-time
0940: 0a 3b 3b 20 20 20 28 66 6f 72 65 69 67 6e 2d 6c  .;;   (foreign-l
0950: 61 6d 62 64 61 2a 20 63 2d 73 74 72 69 6e 67 20  ambda* c-string 
0960: 28 28 6c 6f 6e 67 20 73 65 63 73 5f 73 69 6e 63  ((long secs_sinc
0970: 65 5f 65 70 6f 63 68 29 29 0a 3b 3b 20 20 20 20  e_epoch)).;;    
0980: 20 22 73 74 61 74 69 63 20 63 68 61 72 20 62 75   "static char bu
0990: 66 5b 32 35 36 5d 3b 22 0a 3b 3b 20 20 20 20 20  f[256];".;;     
09a0: 22 74 69 6d 65 5f 74 20 74 20 3d 20 28 74 69 6d  "time_t t = (tim
09b0: 65 5f 74 29 20 73 65 63 73 5f 73 69 6e 63 65 5f  e_t) secs_since_
09c0: 65 70 6f 63 68 3b 22 0a 3b 3b 20 20 20 20 20 22  epoch;".;;     "
09d0: 73 74 72 66 74 69 6d 65 28 62 75 66 2c 20 73 69  strftime(buf, si
09e0: 7a 65 6f 66 28 62 75 66 29 2c 20 5c 22 25 61 2c  zeof(buf), \"%a,
09f0: 20 25 64 2d 25 62 2d 25 59 20 25 48 3a 25 4d 3a   %d-%b-%Y %H:%M:
0a00: 25 53 20 47 4d 54 5c 22 2c 20 67 6d 74 69 6d 65  %S GMT\", gmtime
0a10: 28 26 74 29 29 3b 22 0a 3b 3b 20 20 20 20 20 22  (&t));".;;     "
0a20: 72 65 74 75 72 6e 28 62 75 66 29 3b 22 29 29 0a  return(buf);")).
0a30: 0a 0a 28 64 65 66 69 6e 65 20 28 66 6d 74 2d 74  ..(define (fmt-t
0a40: 69 6d 65 20 73 65 63 6f 6e 64 73 29 0a 20 20 20  ime seconds).   
0a50: 28 74 69 6d 65 2d 3e 73 74 72 69 6e 67 20 28 73  (time->string (s
0a60: 65 63 6f 6e 64 73 2d 3e 75 74 63 2d 74 69 6d 65  econds->utc-time
0a70: 20 73 65 63 6f 6e 64 73 29 20 22 25 44 22 29 29   seconds) "%D"))
0a80: 0a 0a 20 3b 3b 20 75 74 69 6c 69 74 79 20 66 6e  .. ;; utility fn
0a90: 2e 20 20 62 72 65 61 6b 73 20 20 60 60 61 74 74  .  breaks  ``att
0aa0: 72 3d 76 61 6c 75 65 3b 61 74 74 72 3d 76 61 6c  r=value;attr=val
0ab0: 75 65 20 2e 2e 2e 20 27 27 20 69 6e 74 6f 20 61  ue ... '' into a
0ac0: 6c 69 73 74 2e 0a 20 3b 3b 20 76 65 72 73 69 6f  list.. ;; versio
0ad0: 6e 20 69 73 20 61 20 63 6f 6f 6b 69 65 20 76 65  n is a cookie ve
0ae0: 72 73 69 6f 6e 2e 20 20 69 66 20 76 65 72 73 69  rsion.  if versi
0af0: 6f 6e 3e 30 2c 20 77 65 20 61 6c 6c 6f 77 20 63  on>0, we allow c
0b00: 6f 6d 6d 61 20 61 73 20 74 68 65 0a 20 3b 3b 20  omma as the. ;; 
0b10: 64 65 6c 69 6d 69 74 65 72 20 61 73 20 77 65 6c  delimiter as wel
0b20: 6c 20 61 73 20 73 65 6d 69 63 6f 6c 6f 6e 2e 0a  l as semicolon..
0b30: 20 28 64 65 66 69 6e 65 20 28 70 61 72 73 65 2d   (define (parse-
0b40: 61 76 2d 70 61 69 72 73 20 69 6e 70 75 74 20 76  av-pairs input v
0b50: 65 72 73 69 6f 6e 29 0a 20 20 20 28 64 65 66 69  ersion).   (defi
0b60: 6e 65 20 61 74 74 72 2d 72 65 67 65 78 70 0a 20  ne attr-regexp. 
0b70: 20 20 20 20 28 69 66 20 28 3d 20 76 65 72 73 69      (if (= versi
0b80: 6f 6e 20 30 29 0a 20 20 20 20 20 20 20 20 20 28  on 0).         (
0b90: 72 65 67 65 78 70 20 22 5c 5c 73 2a 28 5b 5c 5c  regexp "\\s*([\\
0ba0: 77 24 5f 2d 5d 2b 29 5c 5c 73 2a 28 5b 3d 5c 5c  w$_-]+)\\s*([=\\
0bb0: 3b 5d 5c 5c 73 2a 29 3f 22 29 0a 20 20 20 20 20  ;]\\s*)?").     
0bc0: 20 20 20 20 28 72 65 67 65 78 70 20 22 5c 5c 73      (regexp "\\s
0bd0: 2a 28 5b 5c 5c 77 24 5f 2d 5d 2b 29 5c 5c 73 2a  *([\\w$_-]+)\\s*
0be0: 28 5b 3d 5c 5c 3b 2c 5d 5c 5c 73 2a 29 3f 22 29  ([=\\;,]\\s*)?")
0bf0: 29 29 0a 20 20 20 28 64 65 66 69 6e 65 20 61 74  )).   (define at
0c00: 74 72 2d 64 65 6c 69 6d 0a 20 20 20 20 20 28 69  tr-delim.     (i
0c10: 66 20 28 3d 20 76 65 72 73 69 6f 6e 20 30 29 20  f (= version 0) 
0c20: 23 5c 3b 20 28 63 68 61 72 2d 73 65 74 20 23 5c  #\; (char-set #\
0c30: 2c 20 23 5c 5c 20 23 5c 3b 29 29 29 0a 20 20 20  , #\\ #\;))).   
0c40: 0a 20 20 20 28 64 65 66 69 6e 65 20 28 72 65 61  .   (define (rea
0c50: 64 2d 61 74 74 72 20 69 6e 70 75 74 20 72 29 0a  d-attr input r).
0c60: 20 20 20 20 20 28 63 6f 6e 64 20 28 28 73 74 72       (cond ((str
0c70: 69 6e 67 2d 6e 75 6c 6c 3f 20 69 6e 70 75 74 29  ing-null? input)
0c80: 20 28 72 65 76 65 72 73 65 21 20 72 29 29 0a 20   (reverse! r)). 
0c90: 20 20 20 20 20 20 20 20 20 20 28 28 73 74 72 69            ((stri
0ca0: 6e 67 2d 73 65 61 72 63 68 20 61 74 74 72 2d 72  ng-search attr-r
0cb0: 65 67 65 78 70 20 69 6e 70 75 74 29 0a 20 20 20  egexp input).   
0cc0: 20 20 20 20 20 20 20 20 20 3d 3e 20 28 6c 61 6d           => (lam
0cd0: 62 64 61 20 28 6d 29 0a 20 20 20 20 20 20 20 20  bda (m).        
0ce0: 20 20 20 20 20 20 20 20 20 28 69 66 20 28 61 6e           (if (an
0cf0: 64 2d 6c 65 74 2a 20 28 28 64 65 6c 69 6d 69 74  d-let* ((delimit
0d00: 65 72 20 28 74 68 69 72 64 20 6d 29 29 29 20 3b  er (third m))) ;
0d10: 3b 69 73 20 61 6e 20 61 74 74 72 5f 76 61 6c 75  ;is an attr_valu
0d20: 65 20 70 61 69 0a 20 09 09 20 20 20 20 20 20 28  e pai. ..      (
0d30: 73 74 72 69 6e 67 2d 70 72 65 66 69 78 3f 20 22  string-prefix? "
0d40: 3d 22 20 64 65 6c 69 6d 69 74 65 72 29 29 0a 20  =" delimiter)). 
0d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d60: 20 20 20 20 28 6c 65 74 20 28 28 61 74 74 72 20      (let ((attr 
0d70: 28 73 65 63 6f 6e 64 20 6d 29 29 0a 20 20 20 20  (second m)).    
0d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d90: 20 20 20 20 20 20 20 28 72 65 73 74 20 28 73 74         (rest (st
0da0: 72 69 6e 67 2d 73 65 61 72 63 68 2d 61 66 74 65  ring-search-afte
0db0: 72 20 61 74 74 72 2d 72 65 67 65 78 70 20 69 6e  r attr-regexp in
0dc0: 70 75 74 29 29 29 0a 20 20 20 20 20 20 20 20 20  put))).         
0dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 28 69                (i
0de0: 66 20 28 73 74 72 69 6e 67 2d 70 72 65 66 69 78  f (string-prefix
0df0: 3f 20 22 5c 22 22 20 72 65 73 74 29 0a 20 20 20  ? "\"" rest).   
0e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e10: 20 20 20 20 20 20 20 20 28 72 65 61 64 2d 74 6f          (read-to
0e20: 6b 65 6e 2d 71 75 6f 74 65 64 20 61 74 74 72 20  ken-quoted attr 
0e30: 28 73 74 72 69 6e 67 2d 64 72 6f 70 20 72 65 73  (string-drop res
0e40: 74 20 31 29 20 72 29 0a 20 20 20 20 20 20 20 20  t 1) r).        
0e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e60: 20 20 20 28 72 65 61 64 2d 74 6f 6b 65 6e 20 61     (read-token a
0e70: 74 74 72 20 72 65 73 74 20 72 29 29 29 0a 20 20  ttr rest r))).  
0e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e90: 20 20 20 28 72 65 61 64 2d 61 74 74 72 20 28 73     (read-attr (s
0ea0: 74 72 69 6e 67 2d 73 65 61 72 63 68 2d 61 66 74  tring-search-aft
0eb0: 65 72 20 61 74 74 72 2d 72 65 67 65 78 70 20 69  er attr-regexp i
0ec0: 6e 70 75 74 29 20 3b 3b 20 53 6b 69 70 20 61 68  nput) ;; Skip ah
0ed0: 65 61 64 20 69 66 20 62 72 6f 6b 65 6e 20 69 6e  ead if broken in
0ee0: 70 75 74 3f 0a 20 20 20 20 20 20 20 20 20 20 20  put?.           
0ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f00: 20 20 20 20 20 28 61 6c 69 73 74 2d 63 6f 6e 73       (alist-cons
0f10: 20 28 73 65 63 6f 6e 64 20 6d 29 20 23 66 20 72   (second m) #f r
0f20: 29 29 29 29 29 0a 20 20 20 20 20 20 20 20 20 20  ))))).          
0f30: 20 28 65 6c 73 65 0a 20 20 20 20 20 20 20 20 20   (else.         
0f40: 20 20 20 3b 3b 20 74 68 65 20 69 6e 70 75 74 20     ;; the input 
0f50: 69 73 20 62 72 6f 6b 65 6e 3b 20 66 6f 72 20 6e  is broken; for n
0f60: 6f 77 2c 20 77 65 20 69 67 6e 6f 72 65 20 74 68  ow, we ignore th
0f70: 65 20 72 65 73 74 2e 0a 20 20 20 20 20 20 20 20  e rest..        
0f80: 20 20 20 20 28 72 65 76 65 72 73 65 21 20 72 29      (reverse! r)
0f90: 29 29 29 0a 20 20 20 28 64 65 66 69 6e 65 20 28  ))).   (define (
0fa0: 72 65 61 64 2d 74 6f 6b 65 6e 20 61 74 74 72 20  read-token attr 
0fb0: 69 6e 70 75 74 20 72 29 0a 20 20 20 20 20 28 63  input r).     (c
0fc0: 6f 6e 64 20 28 28 73 74 72 69 6e 67 2d 69 6e 64  ond ((string-ind
0fd0: 65 78 20 69 6e 70 75 74 20 61 74 74 72 2d 64 65  ex input attr-de
0fe0: 6c 69 6d 29 0a 20 20 20 20 20 20 20 20 20 20 20  lim).           
0ff0: 20 3d 3e 20 28 6c 61 6d 62 64 61 20 28 69 29 0a   => (lambda (i).
1000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1010: 20 28 72 65 61 64 2d 61 74 74 72 20 28 73 74 72   (read-attr (str
1020: 69 6e 67 2d 64 72 6f 70 20 69 6e 70 75 74 20 28  ing-drop input (
1030: 2b 20 69 20 31 29 29 0a 20 20 20 20 20 20 20 20  + i 1)).        
1040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1050: 20 20 20 20 28 61 6c 69 73 74 2d 63 6f 6e 73 20      (alist-cons 
1060: 61 74 74 72 0a 20 09 09 09 09 20 20 20 20 20 20  attr. ....      
1070: 20 28 73 74 72 69 6e 67 2d 74 72 69 6d 2d 72 69   (string-trim-ri
1080: 67 68 74 20 28 73 74 72 69 6e 67 2d 74 61 6b 65  ght (string-take
1090: 20 69 6e 70 75 74 20 69 29 29 0a 20 09 09 09 09   input i)). ....
10a0: 20 20 20 20 20 20 20 72 29 29 29 29 0a 20 20 20         r)))).   
10b0: 20 20 20 20 20 20 20 20 28 65 6c 73 65 0a 20 20          (else.  
10c0: 20 20 20 20 20 20 20 20 20 20 28 72 65 76 65 72            (rever
10d0: 73 65 21 20 28 61 6c 69 73 74 2d 63 6f 6e 73 20  se! (alist-cons 
10e0: 61 74 74 72 20 28 73 74 72 69 6e 67 2d 74 72 69  attr (string-tri
10f0: 6d 2d 72 69 67 68 74 20 69 6e 70 75 74 29 20 72  m-right input) r
1100: 29 29 29 29 29 0a 20 20 20 28 64 65 66 69 6e 65  ))))).   (define
1110: 20 28 72 65 61 64 2d 74 6f 6b 65 6e 2d 71 75 6f   (read-token-quo
1120: 74 65 64 20 61 74 74 72 20 69 6e 70 75 74 20 72  ted attr input r
1130: 29 0a 20 20 20 20 20 28 6c 65 74 20 6c 6f 6f 70  ).     (let loop
1140: 20 28 28 69 6e 70 75 74 20 69 6e 70 75 74 29 0a   ((input input).
1150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1160: 28 70 61 72 74 69 61 6c 20 27 28 29 29 29 0a 20  (partial '())). 
1170: 20 20 20 20 20 20 28 63 6f 6e 64 20 28 28 73 74        (cond ((st
1180: 72 69 6e 67 2d 69 6e 64 65 78 20 69 6e 70 75 74  ring-index input
1190: 20 28 63 68 61 72 2d 73 65 74 20 23 5c 5c 20 23   (char-set #\\ #
11a0: 5c 22 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  \")).           
11b0: 20 20 20 3d 3e 20 28 6c 61 6d 62 64 61 20 28 69     => (lambda (i
11c0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
11d0: 20 20 20 20 20 28 6c 65 74 20 28 28 63 20 28 73       (let ((c (s
11e0: 74 72 69 6e 67 2d 72 65 66 20 69 6e 70 75 74 20  tring-ref input 
11f0: 69 29 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  i))).           
1200: 20 20 20 20 20 20 20 20 20 20 28 69 66 20 28 63            (if (c
1210: 68 61 72 3d 3f 20 63 20 23 5c 5c 29 0a 20 20 20  har=? c #\\).   
1220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1230: 20 20 20 20 20 20 28 69 66 20 28 3c 20 28 73 74        (if (< (st
1240: 72 69 6e 67 2d 6c 65 6e 67 74 68 20 69 6e 70 75  ring-length inpu
1250: 74 29 20 28 2b 20 69 20 31 29 29 0a 20 20 20 20  t) (+ i 1)).    
1260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1270: 20 20 20 20 20 20 20 20 20 28 65 72 72 6f 72 2d           (error-
1280: 75 6e 74 65 72 6d 69 6e 61 74 65 64 20 61 74 74  unterminated att
1290: 72 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  r).             
12a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12b0: 28 6c 6f 6f 70 20 28 73 74 72 69 6e 67 2d 64 72  (loop (string-dr
12c0: 6f 70 20 69 6e 70 75 74 20 28 2b 20 69 20 32 29  op input (+ i 2)
12d0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
12e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12f0: 20 20 20 20 20 28 63 6f 6e 73 2a 20 28 73 74 72       (cons* (str
1300: 69 6e 67 20 28 73 74 72 69 6e 67 2d 72 65 66 20  ing (string-ref 
1310: 69 6e 70 75 74 20 28 2b 20 69 20 31 29 29 29 0a  input (+ i 1))).
1320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1340: 20 20 20 20 20 20 20 20 20 20 28 73 74 72 69 6e            (strin
1350: 67 2d 74 61 6b 65 20 69 6e 70 75 74 20 69 29 0a  g-take input i).
1360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1380: 20 20 20 20 20 20 20 20 20 20 70 61 72 74 69 61            partia
1390: 6c 29 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  l))).           
13a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 28 72                (r
13b0: 65 61 64 2d 61 74 74 72 20 28 73 74 72 69 6e 67  ead-attr (string
13c0: 2d 64 72 6f 70 20 69 6e 70 75 74 20 28 2b 20 69  -drop input (+ i
13d0: 20 31 29 29 0a 20 20 20 20 20 20 20 20 20 20 20   1)).           
13e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13f0: 20 20 20 20 20 20 20 20 20 28 61 6c 69 73 74 2d           (alist-
1400: 63 6f 6e 73 20 61 74 74 72 0a 20 09 09 09 09 09  cons attr. .....
1410: 20 20 20 20 20 20 20 28 73 74 72 69 6e 67 2d 63         (string-c
1420: 6f 6e 63 61 74 65 6e 61 74 65 2d 72 65 76 65 72  oncatenate-rever
1430: 73 65 0a 20 09 09 09 09 09 09 28 63 6f 6e 73 20  se. ......(cons 
1440: 28 73 74 72 69 6e 67 2d 74 61 6b 65 20 69 6e 70  (string-take inp
1450: 75 74 20 69 29 0a 20 09 09 09 09 09 09 20 20 20  ut i). ......   
1460: 20 20 20 70 61 72 74 69 61 6c 29 29 0a 20 09 09     partial)). ..
1470: 09 09 09 20 20 20 20 20 20 20 72 29 29 29 29 29  ...       r)))))
1480: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 28  ).             (
1490: 65 6c 73 65 20 28 65 72 72 6f 72 2d 75 6e 74 65  else (error-unte
14a0: 72 6d 69 6e 61 74 65 64 20 61 74 74 72 29 29 29  rminated attr)))
14b0: 29 29 0a 20 20 20 28 64 65 66 69 6e 65 20 28 65  )).   (define (e
14c0: 72 72 6f 72 2d 75 6e 74 65 72 6d 69 6e 61 74 65  rror-unterminate
14d0: 64 20 61 74 74 72 29 0a 20 20 20 20 20 28 65 72  d attr).     (er
14e0: 72 6f 72 20 22 55 6e 74 65 72 6d 69 6e 61 74 65  ror "Unterminate
14f0: 64 20 71 75 6f 74 65 64 20 76 61 6c 75 65 20 67  d quoted value g
1500: 69 76 65 6e 20 66 6f 72 20 61 74 74 72 69 62 75  iven for attribu
1510: 74 65 22 20 61 74 74 72 29 29 0a 20 0a 20 20 20  te" attr)). .   
1520: 28 72 65 61 64 2d 61 74 74 72 20 69 6e 70 75 74  (read-attr input
1530: 20 27 28 29 29 29 0a 20 0a 20 3b 3b 20 50 61 72   '())). . ;; Par
1540: 73 65 73 20 74 68 65 20 68 65 61 64 65 72 20 76  ses the header v
1550: 61 6c 75 65 20 6f 66 20 22 43 6f 6f 6b 69 65 22  alue of "Cookie"
1560: 20 72 65 71 75 65 73 74 20 68 65 61 64 65 72 2e   request header.
1570: 0a 20 3b 3b 20 49 66 20 63 6f 6f 6b 69 65 20 76  . ;; If cookie v
1580: 65 72 73 69 6f 6e 20 69 73 20 6b 6e 6f 77 6e 20  ersion is known 
1590: 62 79 20 22 43 6f 6f 6b 69 65 32 22 20 72 65 71  by "Cookie2" req
15a0: 75 65 73 74 20 68 65 61 64 65 72 2c 20 69 74 20  uest header, it 
15b0: 73 68 6f 75 6c 64 0a 20 3b 3b 20 62 65 20 70 61  should. ;; be pa
15c0: 73 73 65 64 20 74 6f 20 76 65 72 73 69 6f 6e 20  ssed to version 
15d0: 28 61 73 20 69 6e 74 65 67 65 72 29 2e 20 20 4f  (as integer).  O
15e0: 74 68 65 72 77 69 73 65 2c 20 69 74 20 66 69 67  therwise, it fig
15f0: 75 72 65 73 20 6f 75 74 0a 20 3b 3b 20 74 68 65  ures out. ;; the
1600: 20 63 6f 6f 6b 69 65 20 76 65 72 73 69 6f 6e 20   cookie version 
1610: 66 72 6f 6d 20 69 6e 70 75 74 2e 0a 20 3b 3b 0a  from input.. ;;.
1620: 20 3b 3b 20 52 65 74 75 72 6e 73 20 74 68 65 20   ;; Returns the 
1630: 66 6f 6c 6c 6f 77 69 6e 67 20 66 6f 72 6d 61 74  following format
1640: 2e 0a 20 3b 3b 20 20 20 28 28 3c 6e 61 6d 65 3e  .. ;;   ((<name>
1650: 20 3c 76 61 6c 75 65 3e 20 5b 3a 70 61 74 68 20   <value> [:path 
1660: 3c 70 61 74 68 3e 5d 20 5b 3a 64 6f 6d 61 69 6e  <path>] [:domain
1670: 20 3c 64 6f 6d 61 69 6e 3e 5d 20 5b 3a 70 6f 72   <domain>] [:por
1680: 74 20 3c 70 6f 72 74 3e 5d 29 0a 20 3b 3b 20 20  t <port>]). ;;  
1690: 20 20 2e 2e 2e 29 0a 20 0a 20 28 64 65 66 69 6e    ...). . (defin
16a0: 65 20 28 70 61 72 73 65 2d 63 6f 6f 6b 69 65 2d  e (parse-cookie-
16b0: 73 74 72 69 6e 67 20 69 6e 70 75 74 20 23 21 6f  string input #!o
16c0: 70 74 69 6f 6e 61 6c 20 76 65 72 73 69 6f 6e 29  ptional version)
16d0: 0a 20 20 20 28 6c 65 74 20 28 28 76 65 72 20 28  .   (let ((ver (
16e0: 63 6f 6e 64 20 28 28 69 6e 74 65 67 65 72 3f 20  cond ((integer? 
16f0: 76 65 72 73 69 6f 6e 29 20 76 65 72 73 69 6f 6e  version) version
1700: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
1710: 20 20 20 20 20 20 28 28 73 74 72 69 6e 67 2d 73        ((string-s
1720: 65 61 72 63 68 20 22 5e 5c 5c 73 2a 5c 5c 24 56  earch "^\\s*\\$V
1730: 65 72 73 69 6f 6e 5c 5c 73 2a 3d 5c 5c 73 2a 28  ersion\\s*=\\s*(
1740: 5c 5c 64 2b 29 22 20 69 6e 70 75 74 29 0a 20 20  \\d+)" input).  
1750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1760: 20 20 20 3d 3e 20 28 6c 61 6d 62 64 61 20 28 6d     => (lambda (m
1770: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
1780: 20 20 20 20 20 20 20 20 20 20 20 20 28 73 74 72              (str
1790: 69 6e 67 2d 3e 6e 75 6d 62 65 72 20 28 63 61 64  ing->number (cad
17a0: 72 20 6d 29 29 29 29 0a 20 20 20 20 20 20 20 20  r m)))).        
17b0: 20 20 20 20 20 20 20 20 20 20 20 20 28 65 6c 73              (els
17c0: 65 20 30 29 29 29 29 0a 20 20 20 20 20 28 6c 65  e 0)))).     (le
17d0: 74 20 6c 6f 6f 70 20 28 28 61 76 2d 70 61 69 72  t loop ((av-pair
17e0: 73 20 28 70 61 72 73 65 2d 61 76 2d 70 61 69 72  s (parse-av-pair
17f0: 73 20 69 6e 70 75 74 20 76 65 72 29 29 0a 20 20  s input ver)).  
1800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 28 72                (r
1810: 20 27 28 29 29 0a 20 20 20 20 20 20 20 20 20 20   '()).          
1820: 20 20 20 20 20 20 28 63 75 72 72 65 6e 74 20 27        (current '
1830: 28 29 29 29 0a 20 20 20 20 20 20 20 28 63 6f 6e  ())).       (con
1840: 64 20 28 28 6e 75 6c 6c 3f 20 61 76 2d 70 61 69  d ((null? av-pai
1850: 72 73 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  rs).            
1860: 20 20 28 69 66 20 28 6e 75 6c 6c 3f 20 63 75 72    (if (null? cur
1870: 72 65 6e 74 29 0a 20 20 20 20 20 20 20 20 20 20  rent).          
1880: 20 20 20 20 20 20 20 20 28 72 65 76 65 72 73 65          (reverse
1890: 20 72 29 0a 20 20 20 20 20 20 20 20 20 20 20 20   r).            
18a0: 20 20 20 20 20 20 28 72 65 76 65 72 73 65 20 28        (reverse (
18b0: 63 6f 6e 73 20 28 72 65 76 65 72 73 65 20 63 75  cons (reverse cu
18c0: 72 72 65 6e 74 29 20 72 29 29 29 29 0a 20 20 20  rrent) r)))).   
18d0: 20 20 20 20 20 20 20 20 20 20 28 28 73 74 72 69            ((stri
18e0: 6e 67 2d 63 69 3d 3f 20 22 24 70 61 74 68 22 20  ng-ci=? "$path" 
18f0: 28 63 61 61 72 20 61 76 2d 70 61 69 72 73 29 29  (caar av-pairs))
1900: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 28  .              (
1910: 6c 6f 6f 70 20 28 63 64 72 20 61 76 2d 70 61 69  loop (cdr av-pai
1920: 72 73 29 20 72 20 28 63 6f 6e 73 2a 20 28 63 64  rs) r (cons* (cd
1930: 61 72 20 61 76 2d 70 61 69 72 73 29 20 70 61 74  ar av-pairs) pat
1940: 68 3a 20 63 75 72 72 65 6e 74 29 29 29 0a 20 20  h: current))).  
1950: 20 20 20 20 20 20 20 20 20 20 20 28 28 73 74 72             ((str
1960: 69 6e 67 2d 63 69 3d 3f 20 22 24 64 6f 6d 61 69  ing-ci=? "$domai
1970: 6e 22 20 28 63 61 61 72 20 61 76 2d 70 61 69 72  n" (caar av-pair
1980: 73 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  s)).            
1990: 20 20 28 6c 6f 6f 70 20 28 63 64 72 20 61 76 2d    (loop (cdr av-
19a0: 70 61 69 72 73 29 20 72 20 28 63 6f 6e 73 2a 20  pairs) r (cons* 
19b0: 28 63 64 61 72 20 61 76 2d 70 61 69 72 73 29 20  (cdar av-pairs) 
19c0: 64 6f 6d 61 69 6e 3a 20 63 75 72 72 65 6e 74 29  domain: current)
19d0: 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  )).             
19e0: 28 28 73 74 72 69 6e 67 2d 63 69 3d 3f 20 22 24  ((string-ci=? "$
19f0: 70 6f 72 74 22 20 28 63 61 61 72 20 61 76 2d 70  port" (caar av-p
1a00: 61 69 72 73 29 29 0a 20 20 20 20 20 20 20 20 20  airs)).         
1a10: 20 20 20 20 20 28 6c 6f 6f 70 20 28 63 64 72 20       (loop (cdr 
1a20: 61 76 2d 70 61 69 72 73 29 20 72 20 28 63 6f 6e  av-pairs) r (con
1a30: 73 2a 20 28 63 64 61 72 20 61 76 2d 70 61 69 72  s* (cdar av-pair
1a40: 73 29 20 70 6f 72 74 3a 20 63 75 72 72 65 6e 74  s) port: current
1a50: 29 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  ))).            
1a60: 20 28 65 6c 73 65 0a 20 20 20 20 20 20 20 20 20   (else.         
1a70: 20 20 20 20 20 28 69 66 20 28 6e 75 6c 6c 3f 20       (if (null? 
1a80: 63 75 72 72 65 6e 74 29 0a 20 20 20 20 20 20 20  current).       
1a90: 20 20 20 20 20 20 20 20 20 20 20 28 6c 6f 6f 70             (loop
1aa0: 20 28 63 64 72 20 61 76 2d 70 61 69 72 73 29 20   (cdr av-pairs) 
1ab0: 72 20 28 6c 69 73 74 20 28 63 64 61 72 20 61 76  r (list (cdar av
1ac0: 2d 70 61 69 72 73 29 20 28 63 61 61 72 20 61 76  -pairs) (caar av
1ad0: 2d 70 61 69 72 73 29 29 29 0a 20 20 20 20 20 20  -pairs))).      
1ae0: 20 20 20 20 20 20 20 20 20 20 20 20 28 6c 6f 6f              (loo
1af0: 70 20 28 63 64 72 20 61 76 2d 70 61 69 72 73 29  p (cdr av-pairs)
1b00: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1b10: 20 20 20 20 20 20 20 20 20 28 63 6f 6e 73 20 28           (cons (
1b20: 72 65 76 65 72 73 65 20 63 75 72 72 65 6e 74 29  reverse current)
1b30: 20 72 29 0a 20 20 20 20 20 20 20 20 20 20 20 20   r).            
1b40: 20 20 20 20 20 20 20 20 20 20 20 20 28 6c 69 73              (lis
1b50: 74 20 28 63 64 61 72 20 61 76 2d 70 61 69 72 73  t (cdar av-pairs
1b60: 29 20 28 63 61 61 72 20 61 76 2d 70 61 69 72 73  ) (caar av-pairs
1b70: 29 29 29 29 29 29 29 29 29 0a 20 0a 20 3b 3b 20  ))))))))). . ;; 
1b80: 43 6f 6e 73 74 72 75 63 74 20 61 20 63 6f 6f 6b  Construct a cook
1b90: 69 65 20 73 74 72 69 6e 67 20 73 75 69 74 61 62  ie string suitab
1ba0: 6c 65 20 66 6f 72 20 53 65 74 2d 43 6f 6f 6b 69  le for Set-Cooki
1bb0: 65 20 6f 72 20 53 65 74 2d 43 6f 6f 6b 69 65 32  e or Set-Cookie2
1bc0: 20 68 65 61 64 65 72 2e 0a 20 3b 3b 20 73 70 65   header.. ;; spe
1bd0: 63 73 20 69 73 20 74 68 65 20 66 6f 6c 6c 6f 77  cs is the follow
1be0: 69 6e 67 20 66 6f 72 6d 61 74 2e 0a 20 3b 3b 0a  ing format.. ;;.
1bf0: 20 3b 3b 20 20 20 28 28 3c 6e 61 6d 65 3e 20 3c   ;;   ((<name> <
1c00: 76 61 6c 75 65 3e 20 5b 3a 63 6f 6d 6d 65 6e 74  value> [:comment
1c10: 20 3c 63 6f 6d 6d 65 6e 74 3e 5d 20 5b 3a 63 6f   <comment>] [:co
1c20: 6d 6d 65 6e 74 2d 75 72 6c 20 3c 63 6f 6d 6d 65  mment-url <comme
1c30: 6e 74 2d 75 72 6c 3e 5d 0a 20 3b 3b 20 20 20 20  nt-url>]. ;;    
1c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c50: 5b 3a 64 69 73 63 61 72 64 20 3c 62 6f 6f 6c 3e  [:discard <bool>
1c60: 5d 20 5b 3a 64 6f 6d 61 69 6e 20 3c 64 6f 6d 61  ] [:domain <doma
1c70: 69 6e 3e 5d 0a 20 3b 3b 20 20 20 20 20 20 20 20  in>]. ;;        
1c80: 20 20 20 20 20 20 20 20 20 20 20 20 5b 3a 6d 61              [:ma
1c90: 78 2d 61 67 65 20 3c 61 67 65 3e 5d 20 5b 3a 70  x-age <age>] [:p
1ca0: 61 74 68 20 3c 76 61 6c 75 65 3e 5d 20 5b 3a 70  ath <value>] [:p
1cb0: 6f 72 74 20 3c 70 6f 72 74 2d 6c 69 73 74 3e 5d  ort <port-list>]
1cc0: 0a 20 3b 3b 20 20 20 20 20 20 20 20 20 20 20 20  . ;;            
1cd0: 20 20 20 20 20 20 20 20 5b 3a 73 65 63 75 72 65          [:secure
1ce0: 20 3c 62 6f 6f 6c 3e 5d 20 5b 3a 76 65 72 73 69   <bool>] [:versi
1cf0: 6f 6e 20 3c 76 65 72 73 69 6f 6e 3e 5d 20 5b 3a  on <version>] [:
1d00: 65 78 70 69 72 65 73 20 3c 64 61 74 65 3e 5d 0a  expires <date>].
1d10: 20 3b 3b 20 20 20 20 29 20 2e 2e 2e 29 0a 20 3b   ;;    ) ...). ;
1d20: 3b 0a 20 3b 3b 20 52 65 74 75 72 6e 73 20 61 20  ;. ;; Returns a 
1d30: 6c 69 73 74 20 6f 66 20 63 6f 6f 6b 69 65 20 73  list of cookie s
1d40: 74 72 69 6e 67 73 20 66 6f 72 20 65 61 63 68 20  trings for each 
1d50: 3c 6e 61 6d 65 3e 3d 3c 76 61 6c 75 65 3e 20 70  <name>=<value> p
1d60: 61 69 72 2e 20 20 49 6e 20 74 68 65 0a 20 3b 3b  air.  In the. ;;
1d70: 20 60 60 6e 65 77 20 63 6f 6f 6b 69 65 27 27 20   ``new cookie'' 
1d80: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2c 20  implementation, 
1d90: 79 6f 75 20 63 61 6e 20 6a 6f 69 6e 20 74 68 65  you can join the
1da0: 6d 20 62 79 20 63 6f 6d 6d 61 20 61 6e 64 20 73  m by comma and s
1db0: 65 6e 64 20 69 74 0a 20 3b 3b 20 61 74 20 6f 6e  end it. ;; at on
1dc0: 63 65 20 77 69 74 68 20 53 65 74 2d 63 6f 6f 6b  ce with Set-cook
1dd0: 69 65 32 20 68 65 61 64 65 72 2e 20 20 46 6f 72  ie2 header.  For
1de0: 20 74 68 65 20 6f 6c 64 20 6e 65 74 73 63 61 70   the old netscap
1df0: 65 20 70 72 6f 74 6f 63 6f 6c 2c 20 79 6f 75 0a  e protocol, you.
1e00: 20 3b 3b 20 6d 75 73 74 20 73 65 6e 64 20 65 61   ;; must send ea
1e10: 63 68 20 6f 66 20 74 68 65 6d 20 62 79 20 53 65  ch of them by Se
1e20: 74 2d 63 6f 6f 6b 69 65 20 68 65 61 64 65 72 2e  t-cookie header.
1e30: 0a 20 0a 20 0a 20 28 64 65 66 69 6e 65 20 28 63  . . . (define (c
1e40: 6f 6e 73 74 72 75 63 74 2d 63 6f 6f 6b 69 65 2d  onstruct-cookie-
1e50: 73 74 72 69 6e 67 20 73 70 65 63 73 20 23 21 6f  string specs #!o
1e60: 70 74 69 6f 6e 61 6c 20 28 76 65 72 73 69 6f 6e  ptional (version
1e70: 20 31 29 29 0a 20 20 20 28 6d 61 70 20 28 6c 61   1)).   (map (la
1e80: 6d 62 64 61 20 28 73 70 65 63 29 20 28 63 6f 6e  mbda (spec) (con
1e90: 73 74 72 75 63 74 2d 63 6f 6f 6b 69 65 2d 73 74  struct-cookie-st
1ea0: 72 69 6e 67 2d 31 20 73 70 65 63 20 76 65 72 73  ring-1 spec vers
1eb0: 69 6f 6e 29 29 0a 20 20 20 20 20 20 20 20 73 70  ion)).        sp
1ec0: 65 63 73 29 29 0a 20 0a 20 28 64 65 66 69 6e 65  ecs)). . (define
1ed0: 20 28 63 6f 6e 73 74 72 75 63 74 2d 63 6f 6f 6b   (construct-cook
1ee0: 69 65 2d 73 74 72 69 6e 67 2d 31 20 73 70 65 63  ie-string-1 spec
1ef0: 20 76 65 72 29 0a 20 20 20 28 77 68 65 6e 20 28   ver).   (when (
1f00: 3c 20 28 6c 65 6e 67 74 68 20 73 70 65 63 29 20  < (length spec) 
1f10: 32 29 0a 20 20 20 20 20 28 65 72 72 6f 72 20 22  2).     (error "
1f20: 62 61 64 20 63 6f 6f 6b 69 65 20 73 70 65 63 3a  bad cookie spec:
1f30: 20 61 74 20 6c 65 61 73 74 20 3c 6e 61 6d 65 3e   at least <name>
1f40: 20 61 6e 64 20 3c 76 61 6c 75 65 3e 20 72 65 71   and <value> req
1f50: 75 69 72 65 64 22 20 73 70 65 63 29 29 0a 20 20  uired" spec)).  
1f60: 20 28 6c 65 74 20 28 28 6e 61 6d 65 20 28 63 61   (let ((name (ca
1f70: 72 20 73 70 65 63 29 29 0a 20 20 20 20 20 20 20  r spec)).       
1f80: 20 20 28 76 61 6c 75 65 20 28 63 61 64 72 20 73    (value (cadr s
1f90: 70 65 63 29 29 29 0a 20 20 20 20 20 28 6c 65 74  pec))).     (let
1fa0: 20 6c 6f 6f 70 20 28 28 61 74 74 72 20 28 63 64   loop ((attr (cd
1fb0: 64 72 20 73 70 65 63 29 29 0a 20 20 20 20 20 20  dr spec)).      
1fc0: 20 20 20 20 20 20 20 20 20 20 28 72 20 20 20 20            (r    
1fd0: 28 6c 69 73 74 20 28 69 66 20 76 61 6c 75 65 0a  (list (if value.
1fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2000: 28 73 74 72 69 6e 67 2d 61 70 70 65 6e 64 20 6e  (string-append n
2010: 61 6d 65 20 22 3d 22 0a 20 20 20 20 20 20 20 20  ame "=".        
2020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2040: 20 20 20 20 20 20 20 28 71 75 6f 74 65 2d 69 66         (quote-if
2050: 2d 6e 65 65 64 65 64 20 76 61 6c 75 65 29 29 0a  -needed value)).
2060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2080: 6e 61 6d 65 29 29 29 29 0a 20 20 20 20 20 20 20  name)))).       
2090: 28 64 65 66 69 6e 65 20 28 6e 65 78 74 20 73 29  (define (next s)
20a0: 20 28 6c 6f 6f 70 20 28 63 64 64 72 20 61 74 74   (loop (cddr att
20b0: 72 29 20 28 63 6f 6e 73 20 73 20 72 29 29 29 0a  r) (cons s r))).
20c0: 20 20 20 20 20 20 20 28 64 65 66 69 6e 65 20 28         (define (
20d0: 69 67 6e 6f 72 65 29 20 28 6c 6f 6f 70 20 28 63  ignore) (loop (c
20e0: 64 64 72 20 61 74 74 72 29 20 72 29 29 0a 20 20  ddr attr) r)).  
20f0: 20 20 20 20 20 28 63 6f 6e 64 0a 20 20 20 20 20       (cond.     
2100: 20 20 20 28 28 6e 75 6c 6c 3f 20 61 74 74 72 29     ((null? attr)
2110: 20 28 73 74 72 69 6e 67 2d 6a 6f 69 6e 20 28 72   (string-join (r
2120: 65 76 65 72 73 65 20 72 29 20 22 3b 22 29 29 0a  everse r) ";")).
2130: 20 20 20 20 20 20 20 20 28 28 6e 75 6c 6c 3f 20          ((null? 
2140: 28 63 64 72 20 61 74 74 72 29 29 0a 20 20 20 20  (cdr attr)).    
2150: 20 20 20 20 20 28 65 72 72 6f 72 20 28 63 6f 6e       (error (con
2160: 63 20 22 62 61 64 20 63 6f 6f 6b 69 65 20 73 70  c "bad cookie sp
2170: 65 63 3a 20 61 74 74 72 69 62 75 74 65 20 22 20  ec: attribute " 
2180: 28 63 61 72 20 61 74 74 72 29 20 22 20 72 65 71  (car attr) " req
2190: 75 69 72 65 73 20 76 61 6c 75 65 22 20 29 29 29  uires value" )))
21a0: 0a 20 20 20 20 20 20 20 20 28 28 65 71 76 3f 20  .        ((eqv? 
21b0: 63 6f 6d 6d 65 6e 74 3a 20 28 63 61 72 20 61 74  comment: (car at
21c0: 74 72 29 29 0a 20 20 20 20 20 20 20 20 20 28 69  tr)).         (i
21d0: 66 20 28 3e 20 76 65 72 20 30 29 0a 20 09 20 20  f (> ver 0). .  
21e0: 20 20 28 6e 65 78 74 20 28 73 74 72 69 6e 67 2d    (next (string-
21f0: 61 70 70 65 6e 64 20 22 43 6f 6d 6d 65 6e 74 3d  append "Comment=
2200: 22 20 28 71 75 6f 74 65 2d 69 66 2d 6e 65 65 64  " (quote-if-need
2210: 65 64 20 28 63 61 64 72 20 61 74 74 72 29 29 29  ed (cadr attr)))
2220: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 28  ).             (
2230: 69 67 6e 6f 72 65 29 29 29 0a 20 20 20 20 20 20  ignore))).      
2240: 20 20 28 28 65 71 76 3f 20 63 6f 6d 6d 65 6e 74    ((eqv? comment
2250: 2d 75 72 6c 3a 20 28 63 61 72 20 61 74 74 72 29  -url: (car attr)
2260: 29 0a 20 20 20 20 20 20 20 20 20 28 69 66 20 28  ).         (if (
2270: 3e 20 76 65 72 20 30 29 0a 20 20 20 20 20 20 20  > ver 0).       
2280: 20 20 20 20 20 20 28 6e 65 78 74 20 28 73 74 72        (next (str
2290: 69 6e 67 2d 61 70 70 65 6e 64 20 22 43 6f 6d 6d  ing-append "Comm
22a0: 65 6e 74 55 52 4c 3d 22 20 28 71 75 6f 74 65 2d  entURL=" (quote-
22b0: 76 61 6c 75 65 20 28 63 61 64 72 20 61 74 74 72  value (cadr attr
22c0: 29 29 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  )))).           
22d0: 20 20 28 69 67 6e 6f 72 65 29 29 29 0a 20 20 20    (ignore))).   
22e0: 20 20 20 20 20 28 28 65 71 76 3f 20 64 69 73 63       ((eqv? disc
22f0: 61 72 64 3a 20 28 63 61 72 20 61 74 74 72 29 29  ard: (car attr))
2300: 0a 20 20 20 20 20 20 20 20 20 28 69 66 20 28 61  .         (if (a
2310: 6e 64 20 28 3e 20 76 65 72 20 30 29 20 28 63 61  nd (> ver 0) (ca
2320: 64 72 20 61 74 74 72 29 29 20 28 6e 65 78 74 20  dr attr)) (next 
2330: 22 44 69 73 63 61 72 64 22 29 20 28 69 67 6e 6f  "Discard") (igno
2340: 72 65 29 29 29 0a 20 20 20 20 20 20 20 20 28 28  re))).        ((
2350: 65 71 76 3f 20 64 6f 6d 61 69 6e 3a 20 28 63 61  eqv? domain: (ca
2360: 72 20 61 74 74 72 29 29 0a 20 20 20 20 20 20 20  r attr)).       
2370: 20 20 28 6e 65 78 74 20 28 73 74 72 69 6e 67 2d    (next (string-
2380: 61 70 70 65 6e 64 20 22 44 6f 6d 61 69 6e 3d 22  append "Domain="
2390: 20 28 63 61 64 72 20 61 74 74 72 29 29 29 29 0a   (cadr attr)))).
23a0: 20 20 20 20 20 20 20 20 28 28 65 71 76 3f 20 6d          ((eqv? m
23b0: 61 78 2d 61 67 65 3a 20 28 63 61 72 20 61 74 74  ax-age: (car att
23c0: 72 29 29 0a 20 20 20 20 20 20 20 20 20 28 69 66  r)).         (if
23d0: 20 28 3e 20 76 65 72 20 30 29 0a 20 20 20 20 20   (> ver 0).     
23e0: 20 20 20 20 20 20 20 20 28 6e 65 78 74 20 28 73          (next (s
23f0: 70 72 69 6e 74 66 20 22 4d 61 78 2d 41 67 65 3d  printf "Max-Age=
2400: 7e 61 22 20 28 63 61 64 72 20 61 74 74 72 29 29  ~a" (cadr attr))
2410: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 28  ).             (
2420: 69 67 6e 6f 72 65 29 29 29 0a 20 20 20 20 20 20  ignore))).      
2430: 20 20 28 28 65 71 76 3f 20 70 61 74 68 3a 20 28    ((eqv? path: (
2440: 63 61 72 20 61 74 74 72 29 29 0a 20 20 20 20 20  car attr)).     
2450: 20 20 20 20 28 6e 65 78 74 20 28 73 74 72 69 6e      (next (strin
2460: 67 2d 61 70 70 65 6e 64 20 22 50 61 74 68 3d 22  g-append "Path="
2470: 20 28 71 75 6f 74 65 2d 69 66 2d 6e 65 65 64 65   (quote-if-neede
2480: 64 20 28 63 61 64 72 20 61 74 74 72 29 29 29 29  d (cadr attr))))
2490: 29 0a 20 20 20 20 20 20 20 20 28 28 65 71 76 3f  ).        ((eqv?
24a0: 20 70 6f 72 74 3a 20 28 63 61 72 20 61 74 74 72   port: (car attr
24b0: 29 29 0a 20 20 20 20 20 20 20 20 20 28 69 66 20  )).         (if 
24c0: 28 3e 20 76 65 72 20 30 29 0a 20 20 20 20 20 20  (> ver 0).      
24d0: 20 20 20 20 20 20 20 28 6e 65 78 74 20 28 73 74         (next (st
24e0: 72 69 6e 67 2d 61 70 70 65 6e 64 20 22 50 6f 72  ring-append "Por
24f0: 74 3d 22 20 28 71 75 6f 74 65 2d 76 61 6c 75 65  t=" (quote-value
2500: 20 28 63 61 64 72 20 61 74 74 72 29 29 29 29 0a   (cadr attr)))).
2510: 20 20 20 20 20 20 20 20 20 20 20 20 20 28 69 67               (ig
2520: 6e 6f 72 65 29 29 29 0a 20 20 20 20 20 20 20 20  nore))).        
2530: 28 28 65 71 76 3f 20 73 65 63 75 72 65 3a 20 28  ((eqv? secure: (
2540: 63 61 72 20 61 74 74 72 29 29 0a 20 20 20 20 20  car attr)).     
2550: 20 20 20 20 28 69 66 20 28 63 61 64 72 20 61 74      (if (cadr at
2560: 74 72 29 20 28 6e 65 78 74 20 22 53 65 63 75 72  tr) (next "Secur
2570: 65 22 29 20 28 69 67 6e 6f 72 65 29 29 29 0a 20  e") (ignore))). 
2580: 20 20 20 20 20 20 20 28 28 65 71 76 3f 20 76 65         ((eqv? ve
2590: 72 73 69 6f 6e 3a 20 28 63 61 72 20 61 74 74 72  rsion: (car attr
25a0: 29 29 0a 20 20 20 20 20 20 20 20 20 28 69 66 20  )).         (if 
25b0: 28 3e 20 76 65 72 20 30 29 0a 20 20 20 20 20 20  (> ver 0).      
25c0: 20 20 20 20 20 20 20 28 6e 65 78 74 20 28 73 70         (next (sp
25d0: 72 69 6e 74 66 20 22 56 65 72 73 69 6f 6e 3d 7e  rintf "Version=~
25e0: 61 22 20 28 63 61 64 72 20 61 74 74 72 29 29 29  a" (cadr attr)))
25f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 28 69  .             (i
2600: 67 6e 6f 72 65 29 29 29 0a 20 20 20 20 20 20 20  gnore))).       
2610: 20 28 28 65 71 76 3f 20 65 78 70 69 72 65 73 3a   ((eqv? expires:
2620: 20 28 63 61 72 20 61 74 74 72 29 29 0a 20 20 20   (car attr)).   
2630: 20 20 20 20 20 20 28 69 66 20 28 3e 20 76 65 72        (if (> ver
2640: 20 30 29 0a 20 20 20 20 20 20 20 20 20 20 20 20   0).            
2650: 20 28 69 67 6e 6f 72 65 29 0a 20 20 20 20 20 20   (ignore).      
2660: 20 20 20 20 20 20 20 28 6e 65 78 74 20 28 6d 61         (next (ma
2670: 6b 65 2d 65 78 70 69 72 65 73 2d 61 74 74 72 20  ke-expires-attr 
2680: 28 63 61 64 72 20 61 74 74 72 29 29 29 29 29 0a  (cadr attr))))).
2690: 20 20 20 20 20 20 20 20 28 65 6c 73 65 20 28 65          (else (e
26a0: 72 72 6f 72 20 22 55 6e 6b 6e 6f 77 6e 20 63 6f  rror "Unknown co
26b0: 6f 6b 69 65 20 61 74 74 72 69 62 75 74 65 22 20  okie attribute" 
26c0: 28 63 61 72 20 61 74 74 72 29 29 29 29 0a 20 20  (car attr)))).  
26d0: 20 20 20 20 20 29 29 0a 20 20 20 29 0a 20 0a 20       )).   ). . 
26e0: 0a 20 3b 3b 20 28 64 65 66 69 6e 65 20 28 71 75  . ;; (define (qu
26f0: 6f 74 65 2d 76 61 6c 75 65 20 76 61 6c 75 65 29  ote-value value)
2700: 0a 20 3b 3b 20 20 20 28 73 74 72 69 6e 67 2d 61  . ;;   (string-a
2710: 70 70 65 6e 64 20 22 5c 22 22 20 28 72 65 67 65  ppend "\"" (rege
2720: 78 70 2d 72 65 70 6c 61 63 65 2d 61 6c 6c 20 23  xp-replace-all #
2730: 2f 5c 22 7c 5c 5c 2f 20 76 61 6c 75 65 20 22 5c  /\"|\\/ value "\
2740: 5c 5c 5c 5c 5c 30 22 29 20 22 5c 22 22 29 29 0a  \\\\\0") "\"")).
2750: 20 0a 20 28 64 65 66 69 6e 65 20 28 71 75 6f 74   . (define (quot
2760: 65 2d 76 61 6c 75 65 20 76 61 6c 75 65 29 0a 20  e-value value). 
2770: 20 20 28 73 74 72 69 6e 67 2d 61 70 70 65 6e 64    (string-append
2780: 20 22 5c 22 22 20 28 73 74 72 69 6e 67 2d 73 75   "\"" (string-su
2790: 62 73 74 69 74 75 74 65 2a 20 76 61 6c 75 65 20  bstitute* value 
27a0: 27 28 28 22 5c 5c 5c 22 22 20 2e 20 22 5c 5c 5c  '(("\\\"" . "\\\
27b0: 22 22 29 20 28 22 5c 5c 5c 5c 22 20 2e 20 22 5c  "") ("\\\\" . "\
27c0: 5c 5c 5c 22 29 29 29 20 22 5c 22 22 29 29 0a 20  \\\"))) "\"")). 
27d0: 0a 20 28 64 65 66 69 6e 65 20 71 75 6f 74 65 2d  . (define quote-
27e0: 69 66 2d 6e 65 65 64 65 64 0a 20 20 20 28 6c 65  if-needed.   (le
27f0: 74 20 28 28 72 78 20 28 72 65 67 65 78 70 20 22  t ((rx (regexp "
2800: 5b 5c 5c 5c 22 2c 3b 5c 5c 5c 5c 20 5c 5c 74 5c  [\\\",;\\\\ \\t\
2810: 5c 6e 5d 22 29 29 29 0a 20 20 20 20 20 28 6c 61  \n]"))).     (la
2820: 6d 62 64 61 20 28 76 61 6c 75 65 29 0a 20 20 20  mbda (value).   
2830: 20 20 20 20 28 69 66 20 28 73 74 72 69 6e 67 2d      (if (string-
2840: 73 65 61 72 63 68 20 72 78 20 76 61 6c 75 65 29  search rx value)
2850: 0a 20 09 20 20 28 71 75 6f 74 65 2d 76 61 6c 75  . .  (quote-valu
2860: 65 20 76 61 6c 75 65 29 0a 20 09 20 20 76 61 6c  e value). .  val
2870: 75 65 29 29 29 29 0a 20 0a 20 28 64 65 66 69 6e  ue)))). . (defin
2880: 65 20 28 6d 61 6b 65 2d 65 78 70 69 72 65 73 2d  e (make-expires-
2890: 61 74 74 72 20 74 69 6d 65 29 0a 20 20 20 28 73  attr time).   (s
28a0: 70 72 69 6e 74 66 20 22 45 78 70 69 72 65 73 3d  printf "Expires=
28b0: 7e 61 22 0a 20 09 20 20 20 28 69 66 20 28 6e 75  ~a". .   (if (nu
28c0: 6d 62 65 72 3f 20 74 69 6d 65 29 0a 20 09 20 20  mber? time). .  
28d0: 20 20 20 20 20 28 66 6d 74 2d 74 69 6d 65 20 74       (fmt-time t
28e0: 69 6d 65 29 0a 20 09 20 20 20 20 20 20 20 74 69  ime). .       ti
28f0: 6d 65 29 29 29 0a 20 0a 20 3b 3b 3b 3b 20 41 64  me))). . ;;;; Ad
2900: 64 65 64 20 73 75 70 70 6f 72 74 20 66 75 6e 63  ded support func
2910: 74 69 6f 6e 73 20 66 72 6f 6d 20 6d 79 20 75 74  tions from my ut
2920: 69 6c 73 2c 20 73 70 6c 69 74 20 74 68 69 73 20  ils, split this 
2930: 6f 75 74 0a 20 0a 20 28 64 65 66 69 6e 65 20 28  out. . (define (
2940: 73 74 72 69 6e 67 2d 73 65 61 72 63 68 2d 61 66  string-search-af
2950: 74 65 72 20 72 20 73 20 23 21 6f 70 74 69 6f 6e  ter r s #!option
2960: 61 6c 20 28 73 74 61 72 74 20 30 29 29 0a 20 20  al (start 0)).  
2970: 20 28 61 6e 64 2d 6c 65 74 2a 20 28 28 6d 61 74   (and-let* ((mat
2980: 63 68 2d 69 6e 64 69 63 65 73 20 28 73 74 72 69  ch-indices (stri
2990: 6e 67 2d 73 65 61 72 63 68 2d 70 6f 73 69 74 69  ng-search-positi
29a0: 6f 6e 73 20 72 20 73 20 73 74 61 72 74 29 29 0a  ons r s start)).
29b0: 20 09 20 20 20 20 20 28 72 69 67 68 74 2d 6d 61   .     (right-ma
29c0: 74 63 68 20 28 73 65 63 6f 6e 64 20 28 66 69 72  tch (second (fir
29d0: 73 74 20 6d 61 74 63 68 2d 69 6e 64 69 63 65 73  st match-indices
29e0: 29 29 29 29 0a 20 20 20 20 20 28 73 75 62 73 74  )))).     (subst
29f0: 72 69 6e 67 20 73 20 72 69 67 68 74 2d 6d 61 74  ring s right-mat
2a00: 63 68 29 29 29 0a                                ch))).