Artifact ab8271f5b75a3f63e43822b4f1bc2743ffbf0ab7:


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 20 23 3e 0a 3b  ring))..;;  #>.;
0910: 3b 20 20 23 69 6e 63 6c 75 64 65 20 3c 74 69 6d  ;  #include <tim
0920: 65 2e 68 3e 0a 3b 3b 20 20 3c 23 0a 3b 3b 20 20  e.h>.;;  <#.;;  
0930: 0a 3b 3b 20 20 28 64 65 66 69 6e 65 20 66 6d 74  .;;  (define fmt
0940: 2d 74 69 6d 65 0a 3b 3b 20 20 20 20 28 66 6f 72  -time.;;    (for
0950: 65 69 67 6e 2d 6c 61 6d 62 64 61 2a 20 63 2d 73  eign-lambda* c-s
0960: 74 72 69 6e 67 20 28 28 6c 6f 6e 67 20 73 65 63  tring ((long sec
0970: 73 5f 73 69 6e 63 65 5f 65 70 6f 63 68 29 29 0a  s_since_epoch)).
0980: 3b 3b 20 20 20 20 20 20 22 73 74 61 74 69 63 20  ;;      "static 
0990: 63 68 61 72 20 62 75 66 5b 32 35 36 5d 3b 22 0a  char buf[256];".
09a0: 3b 3b 20 20 20 20 20 20 22 74 69 6d 65 5f 74 20  ;;      "time_t 
09b0: 74 20 3d 20 28 74 69 6d 65 5f 74 29 20 73 65 63  t = (time_t) sec
09c0: 73 5f 73 69 6e 63 65 5f 65 70 6f 63 68 3b 22 0a  s_since_epoch;".
09d0: 3b 3b 20 20 20 20 20 20 22 73 74 72 66 74 69 6d  ;;      "strftim
09e0: 65 28 62 75 66 2c 20 73 69 7a 65 6f 66 28 62 75  e(buf, sizeof(bu
09f0: 66 29 2c 20 5c 22 25 61 2c 20 25 64 2d 25 62 2d  f), \"%a, %d-%b-
0a00: 25 59 20 25 48 3a 25 4d 3a 25 53 20 47 4d 54 5c  %Y %H:%M:%S GMT\
0a10: 22 2c 20 67 6d 74 69 6d 65 28 26 74 29 29 3b 22  ", gmtime(&t));"
0a20: 0a 3b 3b 20 20 20 20 20 20 22 72 65 74 75 72 6e  .;;      "return
0a30: 28 62 75 66 29 3b 22 29 29 0a 3b 3b 20 20 0a 0a  (buf);")).;;  ..
0a40: 28 64 65 66 69 6e 65 20 28 66 6d 74 2d 74 69 6d  (define (fmt-tim
0a50: 65 20 73 65 63 6f 6e 64 73 29 0a 20 20 28 74 69  e seconds).  (ti
0a60: 6d 65 2d 3e 73 74 72 69 6e 67 20 28 73 65 63 6f  me->string (seco
0a70: 6e 64 73 2d 3e 75 74 63 2d 74 69 6d 65 20 73 65  nds->utc-time se
0a80: 63 6f 6e 64 73 29 20 22 25 44 22 29 29 0a 0a 20  conds) "%D")).. 
0a90: 3b 3b 20 75 74 69 6c 69 74 79 20 66 6e 2e 20 20  ;; utility fn.  
0aa0: 62 72 65 61 6b 73 20 20 60 60 61 74 74 72 3d 76  breaks  ``attr=v
0ab0: 61 6c 75 65 3b 61 74 74 72 3d 76 61 6c 75 65 20  alue;attr=value 
0ac0: 2e 2e 2e 20 27 27 20 69 6e 74 6f 20 61 6c 69 73  ... '' into alis
0ad0: 74 2e 0a 20 3b 3b 20 76 65 72 73 69 6f 6e 20 69  t.. ;; version i
0ae0: 73 20 61 20 63 6f 6f 6b 69 65 20 76 65 72 73 69  s a cookie versi
0af0: 6f 6e 2e 20 20 69 66 20 76 65 72 73 69 6f 6e 3e  on.  if version>
0b00: 30 2c 20 77 65 20 61 6c 6c 6f 77 20 63 6f 6d 6d  0, we allow comm
0b10: 61 20 61 73 20 74 68 65 0a 20 3b 3b 20 64 65 6c  a as the. ;; del
0b20: 69 6d 69 74 65 72 20 61 73 20 77 65 6c 6c 20 61  imiter as well a
0b30: 73 20 73 65 6d 69 63 6f 6c 6f 6e 2e 0a 20 28 64  s semicolon.. (d
0b40: 65 66 69 6e 65 20 28 70 61 72 73 65 2d 61 76 2d  efine (parse-av-
0b50: 70 61 69 72 73 20 69 6e 70 75 74 20 76 65 72 73  pairs input vers
0b60: 69 6f 6e 29 0a 20 20 20 28 64 65 66 69 6e 65 20  ion).   (define 
0b70: 61 74 74 72 2d 72 65 67 65 78 70 0a 20 20 20 20  attr-regexp.    
0b80: 20 28 69 66 20 28 3d 20 76 65 72 73 69 6f 6e 20   (if (= version 
0b90: 30 29 0a 20 20 20 20 20 20 20 20 20 28 72 65 67  0).         (reg
0ba0: 65 78 70 20 22 5c 5c 73 2a 28 5b 5c 5c 77 24 5f  exp "\\s*([\\w$_
0bb0: 2d 5d 2b 29 5c 5c 73 2a 28 5b 3d 5c 5c 3b 5d 5c  -]+)\\s*([=\\;]\
0bc0: 5c 73 2a 29 3f 22 29 0a 20 20 20 20 20 20 20 20  \s*)?").        
0bd0: 20 28 72 65 67 65 78 70 20 22 5c 5c 73 2a 28 5b   (regexp "\\s*([
0be0: 5c 5c 77 24 5f 2d 5d 2b 29 5c 5c 73 2a 28 5b 3d  \\w$_-]+)\\s*([=
0bf0: 5c 5c 3b 2c 5d 5c 5c 73 2a 29 3f 22 29 29 29 0a  \\;,]\\s*)?"))).
0c00: 20 20 20 28 64 65 66 69 6e 65 20 61 74 74 72 2d     (define attr-
0c10: 64 65 6c 69 6d 0a 20 20 20 20 20 28 69 66 20 28  delim.     (if (
0c20: 3d 20 76 65 72 73 69 6f 6e 20 30 29 20 23 5c 3b  = version 0) #\;
0c30: 20 28 63 68 61 72 2d 73 65 74 20 23 5c 2c 20 23   (char-set #\, #
0c40: 5c 5c 20 23 5c 3b 29 29 29 0a 20 20 20 0a 20 20  \\ #\;))).   .  
0c50: 20 28 64 65 66 69 6e 65 20 28 72 65 61 64 2d 61   (define (read-a
0c60: 74 74 72 20 69 6e 70 75 74 20 72 29 0a 20 20 20  ttr input r).   
0c70: 20 20 28 63 6f 6e 64 20 28 28 73 74 72 69 6e 67    (cond ((string
0c80: 2d 6e 75 6c 6c 3f 20 69 6e 70 75 74 29 20 28 72  -null? input) (r
0c90: 65 76 65 72 73 65 21 20 72 29 29 0a 20 20 20 20  everse! r)).    
0ca0: 20 20 20 20 20 20 20 28 28 73 74 72 69 6e 67 2d         ((string-
0cb0: 73 65 61 72 63 68 20 61 74 74 72 2d 72 65 67 65  search attr-rege
0cc0: 78 70 20 69 6e 70 75 74 29 0a 20 20 20 20 20 20  xp input).      
0cd0: 20 20 20 20 20 20 3d 3e 20 28 6c 61 6d 62 64 61        => (lambda
0ce0: 20 28 6d 29 0a 20 20 20 20 20 20 20 20 20 20 20   (m).           
0cf0: 20 20 20 20 20 20 28 69 66 20 28 61 6e 64 2d 6c        (if (and-l
0d00: 65 74 2a 20 28 28 64 65 6c 69 6d 69 74 65 72 20  et* ((delimiter 
0d10: 28 74 68 69 72 64 20 6d 29 29 29 20 3b 3b 69 73  (third m))) ;;is
0d20: 20 61 6e 20 61 74 74 72 5f 76 61 6c 75 65 20 70   an attr_value p
0d30: 61 69 0a 20 09 09 20 20 20 20 20 20 28 73 74 72  ai. ..      (str
0d40: 69 6e 67 2d 70 72 65 66 69 78 3f 20 22 3d 22 20  ing-prefix? "=" 
0d50: 64 65 6c 69 6d 69 74 65 72 29 29 0a 20 20 20 20  delimiter)).    
0d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d70: 20 28 6c 65 74 20 28 28 61 74 74 72 20 28 73 65   (let ((attr (se
0d80: 63 6f 6e 64 20 6d 29 29 0a 20 20 20 20 20 20 20  cond m)).       
0d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0da0: 20 20 20 20 28 72 65 73 74 20 28 73 74 72 69 6e      (rest (strin
0db0: 67 2d 73 65 61 72 63 68 2d 61 66 74 65 72 20 61  g-search-after a
0dc0: 74 74 72 2d 72 65 67 65 78 70 20 69 6e 70 75 74  ttr-regexp input
0dd0: 29 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  ))).            
0de0: 20 20 20 20 20 20 20 20 20 20 20 28 69 66 20 28             (if (
0df0: 73 74 72 69 6e 67 2d 70 72 65 66 69 78 3f 20 22  string-prefix? "
0e00: 5c 22 22 20 72 65 73 74 29 0a 20 20 20 20 20 20  \"" rest).      
0e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e20: 20 20 20 20 20 28 72 65 61 64 2d 74 6f 6b 65 6e       (read-token
0e30: 2d 71 75 6f 74 65 64 20 61 74 74 72 20 28 73 74  -quoted attr (st
0e40: 72 69 6e 67 2d 64 72 6f 70 20 72 65 73 74 20 31  ring-drop rest 1
0e50: 29 20 72 29 0a 20 20 20 20 20 20 20 20 20 20 20  ) r).           
0e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e70: 28 72 65 61 64 2d 74 6f 6b 65 6e 20 61 74 74 72  (read-token attr
0e80: 20 72 65 73 74 20 72 29 29 29 0a 20 20 20 20 20   rest r))).     
0e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ea0: 28 72 65 61 64 2d 61 74 74 72 20 28 73 74 72 69  (read-attr (stri
0eb0: 6e 67 2d 73 65 61 72 63 68 2d 61 66 74 65 72 20  ng-search-after 
0ec0: 61 74 74 72 2d 72 65 67 65 78 70 20 69 6e 70 75  attr-regexp inpu
0ed0: 74 29 20 3b 3b 20 53 6b 69 70 20 61 68 65 61 64  t) ;; Skip ahead
0ee0: 20 69 66 20 62 72 6f 6b 65 6e 20 69 6e 70 75 74   if broken input
0ef0: 3f 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ?.              
0f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f10: 20 20 28 61 6c 69 73 74 2d 63 6f 6e 73 20 28 73    (alist-cons (s
0f20: 65 63 6f 6e 64 20 6d 29 20 23 66 20 72 29 29 29  econd m) #f r)))
0f30: 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 28 65  )).           (e
0f40: 6c 73 65 0a 20 20 20 20 20 20 20 20 20 20 20 20  lse.            
0f50: 3b 3b 20 74 68 65 20 69 6e 70 75 74 20 69 73 20  ;; the input is 
0f60: 62 72 6f 6b 65 6e 3b 20 66 6f 72 20 6e 6f 77 2c  broken; for now,
0f70: 20 77 65 20 69 67 6e 6f 72 65 20 74 68 65 20 72   we ignore the r
0f80: 65 73 74 2e 0a 20 20 20 20 20 20 20 20 20 20 20  est..           
0f90: 20 28 72 65 76 65 72 73 65 21 20 72 29 29 29 29   (reverse! r))))
0fa0: 0a 20 20 20 28 64 65 66 69 6e 65 20 28 72 65 61  .   (define (rea
0fb0: 64 2d 74 6f 6b 65 6e 20 61 74 74 72 20 69 6e 70  d-token attr inp
0fc0: 75 74 20 72 29 0a 20 20 20 20 20 28 63 6f 6e 64  ut r).     (cond
0fd0: 20 28 28 73 74 72 69 6e 67 2d 69 6e 64 65 78 20   ((string-index 
0fe0: 69 6e 70 75 74 20 61 74 74 72 2d 64 65 6c 69 6d  input attr-delim
0ff0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 3d 3e  ).            =>
1000: 20 28 6c 61 6d 62 64 61 20 28 69 29 0a 20 20 20   (lambda (i).   
1010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 28 72                (r
1020: 65 61 64 2d 61 74 74 72 20 28 73 74 72 69 6e 67  ead-attr (string
1030: 2d 64 72 6f 70 20 69 6e 70 75 74 20 28 2b 20 69  -drop input (+ i
1040: 20 31 29 29 0a 20 20 20 20 20 20 20 20 20 20 20   1)).           
1050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1060: 20 28 61 6c 69 73 74 2d 63 6f 6e 73 20 61 74 74   (alist-cons att
1070: 72 0a 20 09 09 09 09 20 20 20 20 20 20 20 28 73  r. ....       (s
1080: 74 72 69 6e 67 2d 74 72 69 6d 2d 72 69 67 68 74  tring-trim-right
1090: 20 28 73 74 72 69 6e 67 2d 74 61 6b 65 20 69 6e   (string-take in
10a0: 70 75 74 20 69 29 29 0a 20 09 09 09 09 20 20 20  put i)). ....   
10b0: 20 20 20 20 72 29 29 29 29 0a 20 20 20 20 20 20      r)))).      
10c0: 20 20 20 20 20 28 65 6c 73 65 0a 20 20 20 20 20       (else.     
10d0: 20 20 20 20 20 20 20 28 72 65 76 65 72 73 65 21         (reverse!
10e0: 20 28 61 6c 69 73 74 2d 63 6f 6e 73 20 61 74 74   (alist-cons att
10f0: 72 20 28 73 74 72 69 6e 67 2d 74 72 69 6d 2d 72  r (string-trim-r
1100: 69 67 68 74 20 69 6e 70 75 74 29 20 72 29 29 29  ight input) r)))
1110: 29 29 0a 20 20 20 28 64 65 66 69 6e 65 20 28 72  )).   (define (r
1120: 65 61 64 2d 74 6f 6b 65 6e 2d 71 75 6f 74 65 64  ead-token-quoted
1130: 20 61 74 74 72 20 69 6e 70 75 74 20 72 29 0a 20   attr input r). 
1140: 20 20 20 20 28 6c 65 74 20 6c 6f 6f 70 20 28 28      (let loop ((
1150: 69 6e 70 75 74 20 69 6e 70 75 74 29 0a 20 20 20  input input).   
1160: 20 20 20 20 20 20 20 20 20 20 20 20 20 28 70 61               (pa
1170: 72 74 69 61 6c 20 27 28 29 29 29 0a 20 20 20 20  rtial '())).    
1180: 20 20 20 28 63 6f 6e 64 20 28 28 73 74 72 69 6e     (cond ((strin
1190: 67 2d 69 6e 64 65 78 20 69 6e 70 75 74 20 28 63  g-index input (c
11a0: 68 61 72 2d 73 65 74 20 23 5c 5c 20 23 5c 22 29  har-set #\\ #\")
11b0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
11c0: 3d 3e 20 28 6c 61 6d 62 64 61 20 28 69 29 0a 20  => (lambda (i). 
11d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11e0: 20 20 28 6c 65 74 20 28 28 63 20 28 73 74 72 69    (let ((c (stri
11f0: 6e 67 2d 72 65 66 20 69 6e 70 75 74 20 69 29 29  ng-ref input i))
1200: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
1210: 20 20 20 20 20 20 20 28 69 66 20 28 63 68 61 72         (if (char
1220: 3d 3f 20 63 20 23 5c 5c 29 0a 20 20 20 20 20 20  =? c #\\).      
1230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1240: 20 20 20 28 69 66 20 28 3c 20 28 73 74 72 69 6e     (if (< (strin
1250: 67 2d 6c 65 6e 67 74 68 20 69 6e 70 75 74 29 20  g-length input) 
1260: 28 2b 20 69 20 31 29 29 0a 20 20 20 20 20 20 20  (+ i 1)).       
1270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1280: 20 20 20 20 20 20 28 65 72 72 6f 72 2d 75 6e 74        (error-unt
1290: 65 72 6d 69 6e 61 74 65 64 20 61 74 74 72 29 0a  erminated attr).
12a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 28 6c 6f               (lo
12c0: 6f 70 20 28 73 74 72 69 6e 67 2d 64 72 6f 70 20  op (string-drop 
12d0: 69 6e 70 75 74 20 28 2b 20 69 20 32 29 29 0a 20  input (+ i 2)). 
12e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1300: 20 20 28 63 6f 6e 73 2a 20 28 73 74 72 69 6e 67    (cons* (string
1310: 20 28 73 74 72 69 6e 67 2d 72 65 66 20 69 6e 70   (string-ref inp
1320: 75 74 20 28 2b 20 69 20 31 29 29 29 0a 20 20 20  ut (+ i 1))).   
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 20 20 20 20 20 20                  
1350: 20 20 20 20 20 20 20 28 73 74 72 69 6e 67 2d 74         (string-t
1360: 61 6b 65 20 69 6e 70 75 74 20 69 29 0a 20 20 20  ake input i).   
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 20 20 20 20 20 20                  
1390: 20 20 20 20 20 20 20 70 61 72 74 69 61 6c 29 29         partial))
13a0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
13b0: 20 20 20 20 20 20 20 20 20 20 20 28 72 65 61 64             (read
13c0: 2d 61 74 74 72 20 28 73 74 72 69 6e 67 2d 64 72  -attr (string-dr
13d0: 6f 70 20 69 6e 70 75 74 20 28 2b 20 69 20 31 29  op input (+ i 1)
13e0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
13f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1400: 20 20 20 20 20 20 28 61 6c 69 73 74 2d 63 6f 6e        (alist-con
1410: 73 20 61 74 74 72 0a 20 09 09 09 09 09 20 20 20  s attr. .....   
1420: 20 20 20 20 28 73 74 72 69 6e 67 2d 63 6f 6e 63      (string-conc
1430: 61 74 65 6e 61 74 65 2d 72 65 76 65 72 73 65 0a  atenate-reverse.
1440: 20 09 09 09 09 09 09 28 63 6f 6e 73 20 28 73 74   ......(cons (st
1450: 72 69 6e 67 2d 74 61 6b 65 20 69 6e 70 75 74 20  ring-take input 
1460: 69 29 0a 20 09 09 09 09 09 09 20 20 20 20 20 20  i). ......      
1470: 70 61 72 74 69 61 6c 29 29 0a 20 09 09 09 09 09  partial)). .....
1480: 20 20 20 20 20 20 20 72 29 29 29 29 29 29 0a 20         r)))))). 
1490: 20 20 20 20 20 20 20 20 20 20 20 20 28 65 6c 73              (els
14a0: 65 20 28 65 72 72 6f 72 2d 75 6e 74 65 72 6d 69  e (error-untermi
14b0: 6e 61 74 65 64 20 61 74 74 72 29 29 29 29 29 0a  nated attr))))).
14c0: 20 20 20 28 64 65 66 69 6e 65 20 28 65 72 72 6f     (define (erro
14d0: 72 2d 75 6e 74 65 72 6d 69 6e 61 74 65 64 20 61  r-unterminated a
14e0: 74 74 72 29 0a 20 20 20 20 20 28 65 72 72 6f 72  ttr).     (error
14f0: 20 22 55 6e 74 65 72 6d 69 6e 61 74 65 64 20 71   "Unterminated q
1500: 75 6f 74 65 64 20 76 61 6c 75 65 20 67 69 76 65  uoted value give
1510: 6e 20 66 6f 72 20 61 74 74 72 69 62 75 74 65 22  n for attribute"
1520: 20 61 74 74 72 29 29 0a 20 0a 20 20 20 28 72 65   attr)). .   (re
1530: 61 64 2d 61 74 74 72 20 69 6e 70 75 74 20 27 28  ad-attr input '(
1540: 29 29 29 0a 20 0a 20 3b 3b 20 50 61 72 73 65 73  ))). . ;; Parses
1550: 20 74 68 65 20 68 65 61 64 65 72 20 76 61 6c 75   the header valu
1560: 65 20 6f 66 20 22 43 6f 6f 6b 69 65 22 20 72 65  e of "Cookie" re
1570: 71 75 65 73 74 20 68 65 61 64 65 72 2e 0a 20 3b  quest header.. ;
1580: 3b 20 49 66 20 63 6f 6f 6b 69 65 20 76 65 72 73  ; If cookie vers
1590: 69 6f 6e 20 69 73 20 6b 6e 6f 77 6e 20 62 79 20  ion is known by 
15a0: 22 43 6f 6f 6b 69 65 32 22 20 72 65 71 75 65 73  "Cookie2" reques
15b0: 74 20 68 65 61 64 65 72 2c 20 69 74 20 73 68 6f  t header, it sho
15c0: 75 6c 64 0a 20 3b 3b 20 62 65 20 70 61 73 73 65  uld. ;; be passe
15d0: 64 20 74 6f 20 76 65 72 73 69 6f 6e 20 28 61 73  d to version (as
15e0: 20 69 6e 74 65 67 65 72 29 2e 20 20 4f 74 68 65   integer).  Othe
15f0: 72 77 69 73 65 2c 20 69 74 20 66 69 67 75 72 65  rwise, it figure
1600: 73 20 6f 75 74 0a 20 3b 3b 20 74 68 65 20 63 6f  s out. ;; the co
1610: 6f 6b 69 65 20 76 65 72 73 69 6f 6e 20 66 72 6f  okie version fro
1620: 6d 20 69 6e 70 75 74 2e 0a 20 3b 3b 0a 20 3b 3b  m input.. ;;. ;;
1630: 20 52 65 74 75 72 6e 73 20 74 68 65 20 66 6f 6c   Returns the fol
1640: 6c 6f 77 69 6e 67 20 66 6f 72 6d 61 74 2e 0a 20  lowing format.. 
1650: 3b 3b 20 20 20 28 28 3c 6e 61 6d 65 3e 20 3c 76  ;;   ((<name> <v
1660: 61 6c 75 65 3e 20 5b 3a 70 61 74 68 20 3c 70 61  alue> [:path <pa
1670: 74 68 3e 5d 20 5b 3a 64 6f 6d 61 69 6e 20 3c 64  th>] [:domain <d
1680: 6f 6d 61 69 6e 3e 5d 20 5b 3a 70 6f 72 74 20 3c  omain>] [:port <
1690: 70 6f 72 74 3e 5d 29 0a 20 3b 3b 20 20 20 20 2e  port>]). ;;    .
16a0: 2e 2e 29 0a 20 0a 20 28 64 65 66 69 6e 65 20 28  ..). . (define (
16b0: 70 61 72 73 65 2d 63 6f 6f 6b 69 65 2d 73 74 72  parse-cookie-str
16c0: 69 6e 67 20 69 6e 70 75 74 20 23 21 6f 70 74 69  ing input #!opti
16d0: 6f 6e 61 6c 20 76 65 72 73 69 6f 6e 29 0a 20 20  onal version).  
16e0: 20 28 6c 65 74 20 28 28 76 65 72 20 28 63 6f 6e   (let ((ver (con
16f0: 64 20 28 28 69 6e 74 65 67 65 72 3f 20 76 65 72  d ((integer? ver
1700: 73 69 6f 6e 29 20 76 65 72 73 69 6f 6e 29 0a 20  sion) version). 
1710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1720: 20 20 20 28 28 73 74 72 69 6e 67 2d 73 65 61 72     ((string-sear
1730: 63 68 20 22 5e 5c 5c 73 2a 5c 5c 24 56 65 72 73  ch "^\\s*\\$Vers
1740: 69 6f 6e 5c 5c 73 2a 3d 5c 5c 73 2a 28 5c 5c 64  ion\\s*=\\s*(\\d
1750: 2b 29 22 20 69 6e 70 75 74 29 0a 20 20 20 20 20  +)" input).     
1760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1770: 3d 3e 20 28 6c 61 6d 62 64 61 20 28 6d 29 0a 20  => (lambda (m). 
1780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1790: 20 20 20 20 20 20 20 20 20 28 73 74 72 69 6e 67           (string
17a0: 2d 3e 6e 75 6d 62 65 72 20 28 63 61 64 72 20 6d  ->number (cadr m
17b0: 29 29 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  )))).           
17c0: 20 20 20 20 20 20 20 20 20 28 65 6c 73 65 20 30           (else 0
17d0: 29 29 29 29 0a 20 20 20 20 20 28 6c 65 74 20 6c  )))).     (let l
17e0: 6f 6f 70 20 28 28 61 76 2d 70 61 69 72 73 20 28  oop ((av-pairs (
17f0: 70 61 72 73 65 2d 61 76 2d 70 61 69 72 73 20 69  parse-av-pairs i
1800: 6e 70 75 74 20 76 65 72 29 29 0a 20 20 20 20 20  nput ver)).     
1810: 20 20 20 20 20 20 20 20 20 20 20 28 72 20 27 28             (r '(
1820: 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  )).             
1830: 20 20 20 28 63 75 72 72 65 6e 74 20 27 28 29 29     (current '())
1840: 29 0a 20 20 20 20 20 20 20 28 63 6f 6e 64 20 28  ).       (cond (
1850: 28 6e 75 6c 6c 3f 20 61 76 2d 70 61 69 72 73 29  (null? av-pairs)
1860: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 28  .              (
1870: 69 66 20 28 6e 75 6c 6c 3f 20 63 75 72 72 65 6e  if (null? curren
1880: 74 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  t).             
1890: 20 20 20 20 20 28 72 65 76 65 72 73 65 20 72 29       (reverse r)
18a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
18b0: 20 20 20 28 72 65 76 65 72 73 65 20 28 63 6f 6e     (reverse (con
18c0: 73 20 28 72 65 76 65 72 73 65 20 63 75 72 72 65  s (reverse curre
18d0: 6e 74 29 20 72 29 29 29 29 0a 20 20 20 20 20 20  nt) r)))).      
18e0: 20 20 20 20 20 20 20 28 28 73 74 72 69 6e 67 2d         ((string-
18f0: 63 69 3d 3f 20 22 24 70 61 74 68 22 20 28 63 61  ci=? "$path" (ca
1900: 61 72 20 61 76 2d 70 61 69 72 73 29 29 0a 20 20  ar av-pairs)).  
1910: 20 20 20 20 20 20 20 20 20 20 20 20 28 6c 6f 6f              (loo
1920: 70 20 28 63 64 72 20 61 76 2d 70 61 69 72 73 29  p (cdr av-pairs)
1930: 20 72 20 28 63 6f 6e 73 2a 20 28 63 64 61 72 20   r (cons* (cdar 
1940: 61 76 2d 70 61 69 72 73 29 20 70 61 74 68 3a 20  av-pairs) path: 
1950: 63 75 72 72 65 6e 74 29 29 29 0a 20 20 20 20 20  current))).     
1960: 20 20 20 20 20 20 20 20 28 28 73 74 72 69 6e 67          ((string
1970: 2d 63 69 3d 3f 20 22 24 64 6f 6d 61 69 6e 22 20  -ci=? "$domain" 
1980: 28 63 61 61 72 20 61 76 2d 70 61 69 72 73 29 29  (caar av-pairs))
1990: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 28  .              (
19a0: 6c 6f 6f 70 20 28 63 64 72 20 61 76 2d 70 61 69  loop (cdr av-pai
19b0: 72 73 29 20 72 20 28 63 6f 6e 73 2a 20 28 63 64  rs) r (cons* (cd
19c0: 61 72 20 61 76 2d 70 61 69 72 73 29 20 64 6f 6d  ar av-pairs) dom
19d0: 61 69 6e 3a 20 63 75 72 72 65 6e 74 29 29 29 0a  ain: current))).
19e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 28 28 73               ((s
19f0: 74 72 69 6e 67 2d 63 69 3d 3f 20 22 24 70 6f 72  tring-ci=? "$por
1a00: 74 22 20 28 63 61 61 72 20 61 76 2d 70 61 69 72  t" (caar av-pair
1a10: 73 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  s)).            
1a20: 20 20 28 6c 6f 6f 70 20 28 63 64 72 20 61 76 2d    (loop (cdr av-
1a30: 70 61 69 72 73 29 20 72 20 28 63 6f 6e 73 2a 20  pairs) r (cons* 
1a40: 28 63 64 61 72 20 61 76 2d 70 61 69 72 73 29 20  (cdar av-pairs) 
1a50: 70 6f 72 74 3a 20 63 75 72 72 65 6e 74 29 29 29  port: current)))
1a60: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 28 65  .             (e
1a70: 6c 73 65 0a 20 20 20 20 20 20 20 20 20 20 20 20  lse.            
1a80: 20 20 28 69 66 20 28 6e 75 6c 6c 3f 20 63 75 72    (if (null? cur
1a90: 72 65 6e 74 29 0a 20 20 20 20 20 20 20 20 20 20  rent).          
1aa0: 20 20 20 20 20 20 20 20 28 6c 6f 6f 70 20 28 63          (loop (c
1ab0: 64 72 20 61 76 2d 70 61 69 72 73 29 20 72 20 28  dr av-pairs) r (
1ac0: 6c 69 73 74 20 28 63 64 61 72 20 61 76 2d 70 61  list (cdar av-pa
1ad0: 69 72 73 29 20 28 63 61 61 72 20 61 76 2d 70 61  irs) (caar av-pa
1ae0: 69 72 73 29 29 29 0a 20 20 20 20 20 20 20 20 20  irs))).         
1af0: 20 20 20 20 20 20 20 20 20 28 6c 6f 6f 70 20 28           (loop (
1b00: 63 64 72 20 61 76 2d 70 61 69 72 73 29 0a 20 20  cdr av-pairs).  
1b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b20: 20 20 20 20 20 20 28 63 6f 6e 73 20 28 72 65 76        (cons (rev
1b30: 65 72 73 65 20 63 75 72 72 65 6e 74 29 20 72 29  erse current) r)
1b40: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1b50: 20 20 20 20 20 20 20 20 20 28 6c 69 73 74 20 28           (list (
1b60: 63 64 61 72 20 61 76 2d 70 61 69 72 73 29 20 28  cdar av-pairs) (
1b70: 63 61 61 72 20 61 76 2d 70 61 69 72 73 29 29 29  caar av-pairs)))
1b80: 29 29 29 29 29 29 0a 20 0a 20 3b 3b 20 43 6f 6e  )))))). . ;; Con
1b90: 73 74 72 75 63 74 20 61 20 63 6f 6f 6b 69 65 20  struct a cookie 
1ba0: 73 74 72 69 6e 67 20 73 75 69 74 61 62 6c 65 20  string suitable 
1bb0: 66 6f 72 20 53 65 74 2d 43 6f 6f 6b 69 65 20 6f  for Set-Cookie o
1bc0: 72 20 53 65 74 2d 43 6f 6f 6b 69 65 32 20 68 65  r Set-Cookie2 he
1bd0: 61 64 65 72 2e 0a 20 3b 3b 20 73 70 65 63 73 20  ader.. ;; specs 
1be0: 69 73 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  is the following
1bf0: 20 66 6f 72 6d 61 74 2e 0a 20 3b 3b 0a 20 3b 3b   format.. ;;. ;;
1c00: 20 20 20 28 28 3c 6e 61 6d 65 3e 20 3c 76 61 6c     ((<name> <val
1c10: 75 65 3e 20 5b 3a 63 6f 6d 6d 65 6e 74 20 3c 63  ue> [:comment <c
1c20: 6f 6d 6d 65 6e 74 3e 5d 20 5b 3a 63 6f 6d 6d 65  omment>] [:comme
1c30: 6e 74 2d 75 72 6c 20 3c 63 6f 6d 6d 65 6e 74 2d  nt-url <comment-
1c40: 75 72 6c 3e 5d 0a 20 3b 3b 20 20 20 20 20 20 20  url>]. ;;       
1c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 5b 3a 64               [:d
1c60: 69 73 63 61 72 64 20 3c 62 6f 6f 6c 3e 5d 20 5b  iscard <bool>] [
1c70: 3a 64 6f 6d 61 69 6e 20 3c 64 6f 6d 61 69 6e 3e  :domain <domain>
1c80: 5d 0a 20 3b 3b 20 20 20 20 20 20 20 20 20 20 20  ]. ;;           
1c90: 20 20 20 20 20 20 20 20 20 5b 3a 6d 61 78 2d 61           [:max-a
1ca0: 67 65 20 3c 61 67 65 3e 5d 20 5b 3a 70 61 74 68  ge <age>] [:path
1cb0: 20 3c 76 61 6c 75 65 3e 5d 20 5b 3a 70 6f 72 74   <value>] [:port
1cc0: 20 3c 70 6f 72 74 2d 6c 69 73 74 3e 5d 0a 20 3b   <port-list>]. ;
1cd0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1ce0: 20 20 20 20 20 5b 3a 73 65 63 75 72 65 20 3c 62       [:secure <b
1cf0: 6f 6f 6c 3e 5d 20 5b 3a 76 65 72 73 69 6f 6e 20  ool>] [:version 
1d00: 3c 76 65 72 73 69 6f 6e 3e 5d 20 5b 3a 65 78 70  <version>] [:exp
1d10: 69 72 65 73 20 3c 64 61 74 65 3e 5d 0a 20 3b 3b  ires <date>]. ;;
1d20: 20 20 20 20 29 20 2e 2e 2e 29 0a 20 3b 3b 0a 20      ) ...). ;;. 
1d30: 3b 3b 20 52 65 74 75 72 6e 73 20 61 20 6c 69 73  ;; Returns a lis
1d40: 74 20 6f 66 20 63 6f 6f 6b 69 65 20 73 74 72 69  t of cookie stri
1d50: 6e 67 73 20 66 6f 72 20 65 61 63 68 20 3c 6e 61  ngs for each <na
1d60: 6d 65 3e 3d 3c 76 61 6c 75 65 3e 20 70 61 69 72  me>=<value> pair
1d70: 2e 20 20 49 6e 20 74 68 65 0a 20 3b 3b 20 60 60  .  In the. ;; ``
1d80: 6e 65 77 20 63 6f 6f 6b 69 65 27 27 20 69 6d 70  new cookie'' imp
1d90: 6c 65 6d 65 6e 74 61 74 69 6f 6e 2c 20 79 6f 75  lementation, you
1da0: 20 63 61 6e 20 6a 6f 69 6e 20 74 68 65 6d 20 62   can join them b
1db0: 79 20 63 6f 6d 6d 61 20 61 6e 64 20 73 65 6e 64  y comma and send
1dc0: 20 69 74 0a 20 3b 3b 20 61 74 20 6f 6e 63 65 20   it. ;; at once 
1dd0: 77 69 74 68 20 53 65 74 2d 63 6f 6f 6b 69 65 32  with Set-cookie2
1de0: 20 68 65 61 64 65 72 2e 20 20 46 6f 72 20 74 68   header.  For th
1df0: 65 20 6f 6c 64 20 6e 65 74 73 63 61 70 65 20 70  e old netscape p
1e00: 72 6f 74 6f 63 6f 6c 2c 20 79 6f 75 0a 20 3b 3b  rotocol, you. ;;
1e10: 20 6d 75 73 74 20 73 65 6e 64 20 65 61 63 68 20   must send each 
1e20: 6f 66 20 74 68 65 6d 20 62 79 20 53 65 74 2d 63  of them by Set-c
1e30: 6f 6f 6b 69 65 20 68 65 61 64 65 72 2e 0a 20 0a  ookie header.. .
1e40: 20 0a 20 28 64 65 66 69 6e 65 20 28 63 6f 6e 73   . (define (cons
1e50: 74 72 75 63 74 2d 63 6f 6f 6b 69 65 2d 73 74 72  truct-cookie-str
1e60: 69 6e 67 20 73 70 65 63 73 20 23 21 6f 70 74 69  ing specs #!opti
1e70: 6f 6e 61 6c 20 28 76 65 72 73 69 6f 6e 20 31 29  onal (version 1)
1e80: 29 0a 20 20 20 28 6d 61 70 20 28 6c 61 6d 62 64  ).   (map (lambd
1e90: 61 20 28 73 70 65 63 29 20 28 63 6f 6e 73 74 72  a (spec) (constr
1ea0: 75 63 74 2d 63 6f 6f 6b 69 65 2d 73 74 72 69 6e  uct-cookie-strin
1eb0: 67 2d 31 20 73 70 65 63 20 76 65 72 73 69 6f 6e  g-1 spec version
1ec0: 29 29 0a 20 20 20 20 20 20 20 20 73 70 65 63 73  )).        specs
1ed0: 29 29 0a 20 0a 20 28 64 65 66 69 6e 65 20 28 63  )). . (define (c
1ee0: 6f 6e 73 74 72 75 63 74 2d 63 6f 6f 6b 69 65 2d  onstruct-cookie-
1ef0: 73 74 72 69 6e 67 2d 31 20 73 70 65 63 20 76 65  string-1 spec ve
1f00: 72 29 0a 20 20 20 28 77 68 65 6e 20 28 3c 20 28  r).   (when (< (
1f10: 6c 65 6e 67 74 68 20 73 70 65 63 29 20 32 29 0a  length spec) 2).
1f20: 20 20 20 20 20 28 65 72 72 6f 72 20 22 62 61 64       (error "bad
1f30: 20 63 6f 6f 6b 69 65 20 73 70 65 63 3a 20 61 74   cookie spec: at
1f40: 20 6c 65 61 73 74 20 3c 6e 61 6d 65 3e 20 61 6e   least <name> an
1f50: 64 20 3c 76 61 6c 75 65 3e 20 72 65 71 75 69 72  d <value> requir
1f60: 65 64 22 20 73 70 65 63 29 29 0a 20 20 20 28 6c  ed" spec)).   (l
1f70: 65 74 20 28 28 6e 61 6d 65 20 28 63 61 72 20 73  et ((name (car s
1f80: 70 65 63 29 29 0a 20 20 20 20 20 20 20 20 20 28  pec)).         (
1f90: 76 61 6c 75 65 20 28 63 61 64 72 20 73 70 65 63  value (cadr spec
1fa0: 29 29 29 0a 20 20 20 20 20 28 6c 65 74 20 6c 6f  ))).     (let lo
1fb0: 6f 70 20 28 28 61 74 74 72 20 28 63 64 64 72 20  op ((attr (cddr 
1fc0: 73 70 65 63 29 29 0a 20 20 20 20 20 20 20 20 20  spec)).         
1fd0: 20 20 20 20 20 20 20 28 72 20 20 20 20 28 6c 69         (r    (li
1fe0: 73 74 20 28 69 66 20 76 61 6c 75 65 0a 20 20 20  st (if value.   
1ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2000: 20 20 20 20 20 20 20 20 20 20 20 20 20 28 73 74               (st
2010: 72 69 6e 67 2d 61 70 70 65 6e 64 20 6e 61 6d 65  ring-append name
2020: 20 22 3d 22 0a 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 20 20 20 20 20 20 20 20 20                  
2050: 20 20 20 20 28 71 75 6f 74 65 2d 69 66 2d 6e 65      (quote-if-ne
2060: 65 64 65 64 20 76 61 6c 75 65 29 29 0a 20 20 20  eded value)).   
2070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2080: 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 61 6d               nam
2090: 65 29 29 29 29 0a 20 20 20 20 20 20 20 28 64 65  e)))).       (de
20a0: 66 69 6e 65 20 28 6e 65 78 74 20 73 29 20 28 6c  fine (next s) (l
20b0: 6f 6f 70 20 28 63 64 64 72 20 61 74 74 72 29 20  oop (cddr attr) 
20c0: 28 63 6f 6e 73 20 73 20 72 29 29 29 0a 20 20 20  (cons s r))).   
20d0: 20 20 20 20 28 64 65 66 69 6e 65 20 28 69 67 6e      (define (ign
20e0: 6f 72 65 29 20 28 6c 6f 6f 70 20 28 63 64 64 72  ore) (loop (cddr
20f0: 20 61 74 74 72 29 20 72 29 29 0a 20 20 20 20 20   attr) r)).     
2100: 20 20 28 63 6f 6e 64 0a 20 20 20 20 20 20 20 20    (cond.        
2110: 28 28 6e 75 6c 6c 3f 20 61 74 74 72 29 20 28 73  ((null? attr) (s
2120: 74 72 69 6e 67 2d 6a 6f 69 6e 20 28 72 65 76 65  tring-join (reve
2130: 72 73 65 20 72 29 20 22 3b 22 29 29 0a 20 20 20  rse r) ";")).   
2140: 20 20 20 20 20 28 28 6e 75 6c 6c 3f 20 28 63 64       ((null? (cd
2150: 72 20 61 74 74 72 29 29 0a 20 20 20 20 20 20 20  r attr)).       
2160: 20 20 28 65 72 72 6f 72 20 28 63 6f 6e 63 20 22    (error (conc "
2170: 62 61 64 20 63 6f 6f 6b 69 65 20 73 70 65 63 3a  bad cookie spec:
2180: 20 61 74 74 72 69 62 75 74 65 20 22 20 28 63 61   attribute " (ca
2190: 72 20 61 74 74 72 29 20 22 20 72 65 71 75 69 72  r attr) " requir
21a0: 65 73 20 76 61 6c 75 65 22 20 29 29 29 0a 20 20  es value" ))).  
21b0: 20 20 20 20 20 20 28 28 65 71 76 3f 20 63 6f 6d        ((eqv? com
21c0: 6d 65 6e 74 3a 20 28 63 61 72 20 61 74 74 72 29  ment: (car attr)
21d0: 29 0a 20 20 20 20 20 20 20 20 20 28 69 66 20 28  ).         (if (
21e0: 3e 20 76 65 72 20 30 29 0a 20 09 20 20 20 20 28  > ver 0). .    (
21f0: 6e 65 78 74 20 28 73 74 72 69 6e 67 2d 61 70 70  next (string-app
2200: 65 6e 64 20 22 43 6f 6d 6d 65 6e 74 3d 22 20 28  end "Comment=" (
2210: 71 75 6f 74 65 2d 69 66 2d 6e 65 65 64 65 64 20  quote-if-needed 
2220: 28 63 61 64 72 20 61 74 74 72 29 29 29 29 0a 20  (cadr attr)))). 
2230: 20 20 20 20 20 20 20 20 20 20 20 20 28 69 67 6e              (ign
2240: 6f 72 65 29 29 29 0a 20 20 20 20 20 20 20 20 28  ore))).        (
2250: 28 65 71 76 3f 20 63 6f 6d 6d 65 6e 74 2d 75 72  (eqv? comment-ur
2260: 6c 3a 20 28 63 61 72 20 61 74 74 72 29 29 0a 20  l: (car attr)). 
2270: 20 20 20 20 20 20 20 20 28 69 66 20 28 3e 20 76          (if (> v
2280: 65 72 20 30 29 0a 20 20 20 20 20 20 20 20 20 20  er 0).          
2290: 20 20 20 28 6e 65 78 74 20 28 73 74 72 69 6e 67     (next (string
22a0: 2d 61 70 70 65 6e 64 20 22 43 6f 6d 6d 65 6e 74  -append "Comment
22b0: 55 52 4c 3d 22 20 28 71 75 6f 74 65 2d 76 61 6c  URL=" (quote-val
22c0: 75 65 20 28 63 61 64 72 20 61 74 74 72 29 29 29  ue (cadr attr)))
22d0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 28  ).             (
22e0: 69 67 6e 6f 72 65 29 29 29 0a 20 20 20 20 20 20  ignore))).      
22f0: 20 20 28 28 65 71 76 3f 20 64 69 73 63 61 72 64    ((eqv? discard
2300: 3a 20 28 63 61 72 20 61 74 74 72 29 29 0a 20 20  : (car attr)).  
2310: 20 20 20 20 20 20 20 28 69 66 20 28 61 6e 64 20         (if (and 
2320: 28 3e 20 76 65 72 20 30 29 20 28 63 61 64 72 20  (> ver 0) (cadr 
2330: 61 74 74 72 29 29 20 28 6e 65 78 74 20 22 44 69  attr)) (next "Di
2340: 73 63 61 72 64 22 29 20 28 69 67 6e 6f 72 65 29  scard") (ignore)
2350: 29 29 0a 20 20 20 20 20 20 20 20 28 28 65 71 76  )).        ((eqv
2360: 3f 20 64 6f 6d 61 69 6e 3a 20 28 63 61 72 20 61  ? domain: (car a
2370: 74 74 72 29 29 0a 20 20 20 20 20 20 20 20 20 28  ttr)).         (
2380: 6e 65 78 74 20 28 73 74 72 69 6e 67 2d 61 70 70  next (string-app
2390: 65 6e 64 20 22 44 6f 6d 61 69 6e 3d 22 20 28 63  end "Domain=" (c
23a0: 61 64 72 20 61 74 74 72 29 29 29 29 0a 20 20 20  adr attr)))).   
23b0: 20 20 20 20 20 28 28 65 71 76 3f 20 6d 61 78 2d       ((eqv? max-
23c0: 61 67 65 3a 20 28 63 61 72 20 61 74 74 72 29 29  age: (car attr))
23d0: 0a 20 20 20 20 20 20 20 20 20 28 69 66 20 28 3e  .         (if (>
23e0: 20 76 65 72 20 30 29 0a 20 20 20 20 20 20 20 20   ver 0).        
23f0: 20 20 20 20 20 28 6e 65 78 74 20 28 73 70 72 69       (next (spri
2400: 6e 74 66 20 22 4d 61 78 2d 41 67 65 3d 7e 61 22  ntf "Max-Age=~a"
2410: 20 28 63 61 64 72 20 61 74 74 72 29 29 29 0a 20   (cadr attr))). 
2420: 20 20 20 20 20 20 20 20 20 20 20 20 28 69 67 6e              (ign
2430: 6f 72 65 29 29 29 0a 20 20 20 20 20 20 20 20 28  ore))).        (
2440: 28 65 71 76 3f 20 70 61 74 68 3a 20 28 63 61 72  (eqv? path: (car
2450: 20 61 74 74 72 29 29 0a 20 20 20 20 20 20 20 20   attr)).        
2460: 20 28 6e 65 78 74 20 28 73 74 72 69 6e 67 2d 61   (next (string-a
2470: 70 70 65 6e 64 20 22 50 61 74 68 3d 22 20 28 71  ppend "Path=" (q
2480: 75 6f 74 65 2d 69 66 2d 6e 65 65 64 65 64 20 28  uote-if-needed (
2490: 63 61 64 72 20 61 74 74 72 29 29 29 29 29 0a 20  cadr attr))))). 
24a0: 20 20 20 20 20 20 20 28 28 65 71 76 3f 20 70 6f         ((eqv? po
24b0: 72 74 3a 20 28 63 61 72 20 61 74 74 72 29 29 0a  rt: (car attr)).
24c0: 20 20 20 20 20 20 20 20 20 28 69 66 20 28 3e 20           (if (> 
24d0: 76 65 72 20 30 29 0a 20 20 20 20 20 20 20 20 20  ver 0).         
24e0: 20 20 20 20 28 6e 65 78 74 20 28 73 74 72 69 6e      (next (strin
24f0: 67 2d 61 70 70 65 6e 64 20 22 50 6f 72 74 3d 22  g-append "Port="
2500: 20 28 71 75 6f 74 65 2d 76 61 6c 75 65 20 28 63   (quote-value (c
2510: 61 64 72 20 61 74 74 72 29 29 29 29 0a 20 20 20  adr attr)))).   
2520: 20 20 20 20 20 20 20 20 20 20 28 69 67 6e 6f 72            (ignor
2530: 65 29 29 29 0a 20 20 20 20 20 20 20 20 28 28 65  e))).        ((e
2540: 71 76 3f 20 73 65 63 75 72 65 3a 20 28 63 61 72  qv? secure: (car
2550: 20 61 74 74 72 29 29 0a 20 20 20 20 20 20 20 20   attr)).        
2560: 20 28 69 66 20 28 63 61 64 72 20 61 74 74 72 29   (if (cadr attr)
2570: 20 28 6e 65 78 74 20 22 53 65 63 75 72 65 22 29   (next "Secure")
2580: 20 28 69 67 6e 6f 72 65 29 29 29 0a 20 20 20 20   (ignore))).    
2590: 20 20 20 20 28 28 65 71 76 3f 20 76 65 72 73 69      ((eqv? versi
25a0: 6f 6e 3a 20 28 63 61 72 20 61 74 74 72 29 29 0a  on: (car attr)).
25b0: 20 20 20 20 20 20 20 20 20 28 69 66 20 28 3e 20           (if (> 
25c0: 76 65 72 20 30 29 0a 20 20 20 20 20 20 20 20 20  ver 0).         
25d0: 20 20 20 20 28 6e 65 78 74 20 28 73 70 72 69 6e      (next (sprin
25e0: 74 66 20 22 56 65 72 73 69 6f 6e 3d 7e 61 22 20  tf "Version=~a" 
25f0: 28 63 61 64 72 20 61 74 74 72 29 29 29 0a 20 20  (cadr attr))).  
2600: 20 20 20 20 20 20 20 20 20 20 20 28 69 67 6e 6f             (igno
2610: 72 65 29 29 29 0a 20 20 20 20 20 20 20 20 28 28  re))).        ((
2620: 65 71 76 3f 20 65 78 70 69 72 65 73 3a 20 28 63  eqv? expires: (c
2630: 61 72 20 61 74 74 72 29 29 0a 20 20 20 20 20 20  ar attr)).      
2640: 20 20 20 28 69 66 20 28 3e 20 76 65 72 20 30 29     (if (> ver 0)
2650: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 28 69  .             (i
2660: 67 6e 6f 72 65 29 0a 20 20 20 20 20 20 20 20 20  gnore).         
2670: 20 20 20 20 28 6e 65 78 74 20 28 6d 61 6b 65 2d      (next (make-
2680: 65 78 70 69 72 65 73 2d 61 74 74 72 20 28 63 61  expires-attr (ca
2690: 64 72 20 61 74 74 72 29 29 29 29 29 0a 20 20 20  dr attr))))).   
26a0: 20 20 20 20 20 28 65 6c 73 65 20 28 65 72 72 6f       (else (erro
26b0: 72 20 22 55 6e 6b 6e 6f 77 6e 20 63 6f 6f 6b 69  r "Unknown cooki
26c0: 65 20 61 74 74 72 69 62 75 74 65 22 20 28 63 61  e attribute" (ca
26d0: 72 20 61 74 74 72 29 29 29 29 0a 20 20 20 20 20  r attr)))).     
26e0: 20 20 29 29 0a 20 20 20 29 0a 20 0a 20 0a 20 3b    )).   ). . . ;
26f0: 3b 20 28 64 65 66 69 6e 65 20 28 71 75 6f 74 65  ; (define (quote
2700: 2d 76 61 6c 75 65 20 76 61 6c 75 65 29 0a 20 3b  -value value). ;
2710: 3b 20 20 20 28 73 74 72 69 6e 67 2d 61 70 70 65  ;   (string-appe
2720: 6e 64 20 22 5c 22 22 20 28 72 65 67 65 78 70 2d  nd "\"" (regexp-
2730: 72 65 70 6c 61 63 65 2d 61 6c 6c 20 23 2f 5c 22  replace-all #/\"
2740: 7c 5c 5c 2f 20 76 61 6c 75 65 20 22 5c 5c 5c 5c  |\\/ value "\\\\
2750: 5c 5c 30 22 29 20 22 5c 22 22 29 29 0a 20 0a 20  \\0") "\"")). . 
2760: 28 64 65 66 69 6e 65 20 28 71 75 6f 74 65 2d 76  (define (quote-v
2770: 61 6c 75 65 20 76 61 6c 75 65 29 0a 20 20 20 28  alue value).   (
2780: 73 74 72 69 6e 67 2d 61 70 70 65 6e 64 20 22 5c  string-append "\
2790: 22 22 20 28 73 74 72 69 6e 67 2d 73 75 62 73 74  "" (string-subst
27a0: 69 74 75 74 65 2a 20 76 61 6c 75 65 20 27 28 28  itute* value '((
27b0: 22 5c 5c 5c 22 22 20 2e 20 22 5c 5c 5c 22 22 29  "\\\"" . "\\\"")
27c0: 20 28 22 5c 5c 5c 5c 22 20 2e 20 22 5c 5c 5c 5c   ("\\\\" . "\\\\
27d0: 22 29 29 29 20 22 5c 22 22 29 29 0a 20 0a 20 28  "))) "\"")). . (
27e0: 64 65 66 69 6e 65 20 71 75 6f 74 65 2d 69 66 2d  define quote-if-
27f0: 6e 65 65 64 65 64 0a 20 20 20 28 6c 65 74 20 28  needed.   (let (
2800: 28 72 78 20 28 72 65 67 65 78 70 20 22 5b 5c 5c  (rx (regexp "[\\
2810: 5c 22 2c 3b 5c 5c 5c 5c 20 5c 5c 74 5c 5c 6e 5d  \",;\\\\ \\t\\n]
2820: 22 29 29 29 0a 20 20 20 20 20 28 6c 61 6d 62 64  "))).     (lambd
2830: 61 20 28 76 61 6c 75 65 29 0a 20 20 20 20 20 20  a (value).      
2840: 20 28 69 66 20 28 73 74 72 69 6e 67 2d 73 65 61   (if (string-sea
2850: 72 63 68 20 72 78 20 76 61 6c 75 65 29 0a 20 09  rch rx value). .
2860: 20 20 28 71 75 6f 74 65 2d 76 61 6c 75 65 20 76    (quote-value v
2870: 61 6c 75 65 29 0a 20 09 20 20 76 61 6c 75 65 29  alue). .  value)
2880: 29 29 29 0a 20 0a 20 28 64 65 66 69 6e 65 20 28  ))). . (define (
2890: 6d 61 6b 65 2d 65 78 70 69 72 65 73 2d 61 74 74  make-expires-att
28a0: 72 20 74 69 6d 65 29 0a 20 20 20 28 73 70 72 69  r time).   (spri
28b0: 6e 74 66 20 22 45 78 70 69 72 65 73 3d 7e 61 22  ntf "Expires=~a"
28c0: 0a 20 09 20 20 20 28 69 66 20 28 6e 75 6d 62 65  . .   (if (numbe
28d0: 72 3f 20 74 69 6d 65 29 0a 20 09 20 20 20 20 20  r? time). .     
28e0: 20 20 28 66 6d 74 2d 74 69 6d 65 20 74 69 6d 65    (fmt-time time
28f0: 29 0a 20 09 20 20 20 20 20 20 20 74 69 6d 65 29  ). .       time)
2900: 29 29 0a 20 0a 20 3b 3b 3b 3b 20 41 64 64 65 64  )). . ;;;; Added
2910: 20 73 75 70 70 6f 72 74 20 66 75 6e 63 74 69 6f   support functio
2920: 6e 73 20 66 72 6f 6d 20 6d 79 20 75 74 69 6c 73  ns from my utils
2930: 2c 20 73 70 6c 69 74 20 74 68 69 73 20 6f 75 74  , split this out
2940: 0a 20 0a 20 28 64 65 66 69 6e 65 20 28 73 74 72  . . (define (str
2950: 69 6e 67 2d 73 65 61 72 63 68 2d 61 66 74 65 72  ing-search-after
2960: 20 72 20 73 20 23 21 6f 70 74 69 6f 6e 61 6c 20   r s #!optional 
2970: 28 73 74 61 72 74 20 30 29 29 0a 20 20 20 28 61  (start 0)).   (a
2980: 6e 64 2d 6c 65 74 2a 20 28 28 6d 61 74 63 68 2d  nd-let* ((match-
2990: 69 6e 64 69 63 65 73 20 28 73 74 72 69 6e 67 2d  indices (string-
29a0: 73 65 61 72 63 68 2d 70 6f 73 69 74 69 6f 6e 73  search-positions
29b0: 20 72 20 73 20 73 74 61 72 74 29 29 0a 20 09 20   r s start)). . 
29c0: 20 20 20 20 28 72 69 67 68 74 2d 6d 61 74 63 68      (right-match
29d0: 20 28 73 65 63 6f 6e 64 20 28 66 69 72 73 74 20   (second (first 
29e0: 6d 61 74 63 68 2d 69 6e 64 69 63 65 73 29 29 29  match-indices)))
29f0: 29 0a 20 20 20 20 20 28 73 75 62 73 74 72 69 6e  ).     (substrin
2a00: 67 20 73 20 72 69 67 68 74 2d 6d 61 74 63 68 29  g s right-match)
2a10: 29 29                                            ))