WebGate

Hex Artifact Content
Login

Artifact 1c83faab8d93fc4657511ca33528a963d13ff62a:


0000: 3b 3b 20 2d 2a 2d 20 6d 6f 64 65 3a 20 53 63 68  ;; -*- mode: Sch
0010: 65 6d 65 3b 20 2d 2a 2d 0a 3b 3b 0a 3b 3b 20 54  eme; -*-.;;.;; T
0020: 68 69 73 20 66 69 6c 65 20 69 73 20 70 61 72 74  his file is part
0030: 20 6f 66 20 57 65 62 47 61 74 65 20 66 6f 72 20   of WebGate for 
0040: 43 48 49 43 4b 45 4e 2e 0a 3b 3b 20 43 6f 70 79  CHICKEN..;; Copy
0050: 72 69 67 68 74 20 28 63 29 20 32 30 31 31 2d 32  right (c) 2011-2
0060: 30 31 33 20 62 79 20 54 68 6f 6d 61 73 20 43 68  013 by Thomas Ch
0070: 75 73 74 2e 20 20 41 6c 6c 20 72 69 67 68 74 73  ust.  All rights
0080: 20 72 65 73 65 72 76 65 64 2e 0a 3b 3b 0a 3b 3b   reserved..;;.;;
0090: 20 50 65 72 6d 69 73 73 69 6f 6e 20 69 73 20 68   Permission is h
00a0: 65 72 65 62 79 20 67 72 61 6e 74 65 64 2c 20 66  ereby granted, f
00b0: 72 65 65 20 6f 66 20 63 68 61 72 67 65 2c 20 74  ree of charge, t
00c0: 6f 20 61 6e 79 20 70 65 72 73 6f 6e 0a 3b 3b 20  o any person.;; 
00d0: 6f 62 74 61 69 6e 69 6e 67 20 61 20 63 6f 70 79  obtaining a copy
00e0: 20 6f 66 20 74 68 69 73 20 73 6f 66 74 77 61 72   of this softwar
00f0: 65 20 61 6e 64 20 61 73 73 6f 63 69 61 74 65 64  e and associated
0100: 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 0a 3b   documentation.;
0110: 3b 20 66 69 6c 65 73 20 28 74 68 65 20 53 6f 66  ; files (the Sof
0120: 74 77 61 72 65 29 2c 20 74 6f 20 64 65 61 6c 20  tware), to deal 
0130: 69 6e 20 74 68 65 20 53 6f 66 74 77 61 72 65 20  in the Software 
0140: 77 69 74 68 6f 75 74 20 72 65 73 74 72 69 63 74  without restrict
0150: 69 6f 6e 2c 0a 3b 3b 20 69 6e 63 6c 75 64 69 6e  ion,.;; includin
0160: 67 20 77 69 74 68 6f 75 74 20 6c 69 6d 69 74 61  g without limita
0170: 74 69 6f 6e 20 74 68 65 20 72 69 67 68 74 73 20  tion the rights 
0180: 74 6f 20 75 73 65 2c 20 63 6f 70 79 2c 20 6d 6f  to use, copy, mo
0190: 64 69 66 79 2c 0a 3b 3b 20 6d 65 72 67 65 2c 20  dify,.;; merge, 
01a0: 70 75 62 6c 69 73 68 2c 20 64 69 73 74 72 69 62  publish, distrib
01b0: 75 74 65 2c 20 73 75 62 6c 69 63 65 6e 73 65 2c  ute, sublicense,
01c0: 20 61 6e 64 2f 6f 72 20 73 65 6c 6c 20 63 6f 70   and/or sell cop
01d0: 69 65 73 20 6f 66 20 74 68 65 0a 3b 3b 20 53 6f  ies of the.;; So
01e0: 66 74 77 61 72 65 2c 20 61 6e 64 20 74 6f 20 70  ftware, and to p
01f0: 65 72 6d 69 74 20 70 65 72 73 6f 6e 73 20 74 6f  ermit persons to
0200: 20 77 68 6f 6d 20 74 68 65 20 53 6f 66 74 77 61   whom the Softwa
0210: 72 65 20 69 73 20 66 75 72 6e 69 73 68 65 64 0a  re is furnished.
0220: 3b 3b 20 74 6f 20 64 6f 20 73 6f 2c 20 73 75 62  ;; to do so, sub
0230: 6a 65 63 74 20 74 6f 20 74 68 65 20 66 6f 6c 6c  ject to the foll
0240: 6f 77 69 6e 67 20 63 6f 6e 64 69 74 69 6f 6e 73  owing conditions
0250: 3a 0a 3b 3b 20 0a 3b 3b 20 54 68 65 20 61 62 6f  :.;; .;; The abo
0260: 76 65 20 63 6f 70 79 72 69 67 68 74 20 6e 6f 74  ve copyright not
0270: 69 63 65 20 61 6e 64 20 74 68 69 73 20 70 65 72  ice and this per
0280: 6d 69 73 73 69 6f 6e 20 6e 6f 74 69 63 65 20 73  mission notice s
0290: 68 61 6c 6c 20 62 65 0a 3b 3b 20 69 6e 63 6c 75  hall be.;; inclu
02a0: 64 65 64 20 69 6e 20 61 6c 6c 20 63 6f 70 69 65  ded in all copie
02b0: 73 20 6f 72 20 73 75 62 73 74 61 6e 74 69 61 6c  s or substantial
02c0: 20 70 6f 72 74 69 6f 6e 73 20 6f 66 20 74 68 65   portions of the
02d0: 20 53 6f 66 74 77 61 72 65 2e 0a 3b 3b 20 0a 3b   Software..;; .;
02e0: 3b 20 54 48 45 20 53 4f 46 54 57 41 52 45 20 49  ; THE SOFTWARE I
02f0: 53 20 50 52 4f 56 49 44 45 44 20 41 53 49 53 2c  S PROVIDED ASIS,
0300: 20 57 49 54 48 4f 55 54 20 57 41 52 52 41 4e 54   WITHOUT WARRANT
0310: 59 20 4f 46 20 41 4e 59 20 4b 49 4e 44 2c 0a 3b  Y OF ANY KIND,.;
0320: 3b 20 45 58 50 52 45 53 53 20 4f 52 20 49 4d 50  ; EXPRESS OR IMP
0330: 4c 49 45 44 2c 20 49 4e 43 4c 55 44 49 4e 47 20  LIED, INCLUDING 
0340: 42 55 54 20 4e 4f 54 20 4c 49 4d 49 54 45 44 20  BUT NOT LIMITED 
0350: 54 4f 20 54 48 45 20 57 41 52 52 41 4e 54 49 45  TO THE WARRANTIE
0360: 53 20 4f 46 0a 3b 3b 20 4d 45 52 43 48 41 4e 54  S OF.;; MERCHANT
0370: 41 42 49 4c 49 54 59 2c 20 46 49 54 4e 45 53 53  ABILITY, FITNESS
0380: 20 46 4f 52 20 41 20 50 41 52 54 49 43 55 4c 41   FOR A PARTICULA
0390: 52 20 50 55 52 50 4f 53 45 20 41 4e 44 0a 3b 3b  R PURPOSE AND.;;
03a0: 20 4e 4f 4e 49 4e 46 52 49 4e 47 45 4d 45 4e 54   NONINFRINGEMENT
03b0: 2e 20 49 4e 20 4e 4f 20 45 56 45 4e 54 20 53 48  . IN NO EVENT SH
03c0: 41 4c 4c 20 54 48 45 20 41 55 54 48 4f 52 53 20  ALL THE AUTHORS 
03d0: 4f 52 20 43 4f 50 59 52 49 47 48 54 20 48 4f 4c  OR COPYRIGHT HOL
03e0: 44 45 52 53 0a 3b 3b 20 42 45 20 4c 49 41 42 4c  DERS.;; BE LIABL
03f0: 45 20 46 4f 52 20 41 4e 59 20 43 4c 41 49 4d 2c  E FOR ANY CLAIM,
0400: 20 44 41 4d 41 47 45 53 20 4f 52 20 4f 54 48 45   DAMAGES OR OTHE
0410: 52 20 4c 49 41 42 49 4c 49 54 59 2c 20 57 48 45  R LIABILITY, WHE
0420: 54 48 45 52 20 49 4e 20 41 4e 0a 3b 3b 20 41 43  THER IN AN.;; AC
0430: 54 49 4f 4e 20 4f 46 20 43 4f 4e 54 52 41 43 54  TION OF CONTRACT
0440: 2c 20 54 4f 52 54 20 4f 52 20 4f 54 48 45 52 57  , TORT OR OTHERW
0450: 49 53 45 2c 20 41 52 49 53 49 4e 47 20 46 52 4f  ISE, ARISING FRO
0460: 4d 2c 20 4f 55 54 20 4f 46 20 4f 52 20 49 4e 0a  M, OUT OF OR IN.
0470: 3b 3b 20 43 4f 4e 4e 45 43 54 49 4f 4e 20 57 49  ;; CONNECTION WI
0480: 54 48 20 54 48 45 20 53 4f 46 54 57 41 52 45 20  TH THE SOFTWARE 
0490: 4f 52 20 54 48 45 20 55 53 45 20 4f 52 20 4f 54  OR THE USE OR OT
04a0: 48 45 52 20 44 45 41 4c 49 4e 47 53 20 49 4e 20  HER DEALINGS IN 
04b0: 54 48 45 0a 3b 3b 20 53 4f 46 54 57 41 52 45 2e  THE.;; SOFTWARE.
04c0: 0a 0a 3b 3b 3b 20 4d 65 73 73 61 67 65 20 62 61  ..;;; Message ba
04d0: 73 65 20 74 79 70 65 0a 0a 28 64 65 66 69 6e 65  se type..(define
04e0: 2d 72 65 63 6f 72 64 2d 74 79 70 65 20 6d 65 73  -record-type mes
04f0: 73 61 67 65 0a 20 20 25 6d 61 6b 65 2d 6d 65 73  sage.  %make-mes
0500: 73 61 67 65 20 23 74 0a 20 20 74 79 70 65 20 68  sage #t.  type h
0510: 65 61 64 65 72 73 0a 20 20 62 6f 64 79 29 0a 0a  eaders.  body)..
0520: 28 64 65 66 69 6e 65 20 28 6d 61 6b 65 2d 6d 65  (define (make-me
0530: 73 73 61 67 65 0a 09 20 62 6f 64 79 20 23 21 6b  ssage.. body #!k
0540: 65 79 0a 09 20 28 74 79 70 65 20 22 61 70 70 6c  ey.. (type "appl
0550: 69 63 61 74 69 6f 6e 2f 6f 63 74 65 74 2d 73 74  ication/octet-st
0560: 72 65 61 6d 22 29 20 28 68 65 61 64 65 72 73 20  ream") (headers 
0570: 27 28 29 29 29 0a 20 20 28 25 6d 61 6b 65 2d 6d  '())).  (%make-m
0580: 65 73 73 61 67 65 20 74 79 70 65 20 68 65 61 64  essage type head
0590: 65 72 73 20 62 6f 64 79 29 29 0a 0a 28 64 65 66  ers body))..(def
05a0: 69 6e 65 20 6d 65 73 73 61 67 65 2d 74 65 78 74  ine message-text
05b0: 0a 20 20 28 6c 65 74 20 28 28 74 65 78 74 2f 70  .  (let ((text/p
05c0: 6c 61 69 6e 2d 72 78 20 28 69 72 72 65 67 65 78  lain-rx (irregex
05d0: 20 27 28 3a 20 62 6f 73 20 22 74 65 78 74 2f 70   '(: bos "text/p
05e0: 6c 61 69 6e 22 20 28 6f 72 20 22 3b 22 20 65 6f  lain" (or ";" eo
05f0: 73 29 29 29 29 29 0a 20 20 20 20 28 6c 61 6d 62  s))))).    (lamb
0600: 64 61 20 28 6d 73 67 29 0a 20 20 20 20 20 20 28  da (msg).      (
0610: 61 6e 64 20 28 69 72 72 65 67 65 78 2d 73 65 61  and (irregex-sea
0620: 72 63 68 20 74 65 78 74 2f 70 6c 61 69 6e 2d 72  rch text/plain-r
0630: 78 20 28 6d 65 73 73 61 67 65 2d 74 79 70 65 20  x (message-type 
0640: 6d 73 67 29 29 0a 09 20 20 20 28 6d 65 73 73 61  msg))..   (messa
0650: 67 65 2d 62 6f 64 79 20 6d 73 67 29 29 29 29 29  ge-body msg)))))
0660: 0a 0a 28 64 65 66 69 6e 65 20 28 77 72 69 74 65  ..(define (write
0670: 2d 6d 65 73 73 61 67 65 20 6d 73 67 20 23 21 6f  -message msg #!o
0680: 70 74 69 6f 6e 61 6c 20 28 70 6f 72 74 20 28 63  ptional (port (c
0690: 75 72 72 65 6e 74 2d 6f 75 74 70 75 74 2d 70 6f  urrent-output-po
06a0: 72 74 29 29 29 0a 20 20 28 6c 65 74 20 28 28 74  rt))).  (let ((t
06b0: 79 70 65 20 28 6d 65 73 73 61 67 65 2d 74 79 70  ype (message-typ
06c0: 65 20 6d 73 67 29 29 0a 09 28 62 6f 64 79 20 28  e msg))..(body (
06d0: 6d 65 73 73 61 67 65 2d 62 6f 64 79 20 6d 73 67  message-body msg
06e0: 29 29 29 0a 20 20 20 20 28 77 68 65 6e 20 74 79  ))).    (when ty
06f0: 70 65 0a 20 20 20 20 20 20 28 66 70 72 69 6e 74  pe.      (fprint
0700: 66 20 70 6f 72 74 20 22 43 6f 6e 74 65 6e 74 2d  f port "Content-
0710: 74 79 70 65 3a 20 7e 61 5c 72 5c 6e 22 20 74 79  type: ~a\r\n" ty
0720: 70 65 29 29 0a 20 20 20 20 28 77 68 65 6e 20 62  pe)).    (when b
0730: 6f 64 79 0a 20 20 20 20 20 20 28 66 70 72 69 6e  ody.      (fprin
0740: 74 66 20 70 6f 72 74 20 22 43 6f 6e 74 65 6e 74  tf port "Content
0750: 2d 6c 65 6e 67 74 68 3a 20 7e 61 5c 72 5c 6e 22  -length: ~a\r\n"
0760: 20 28 73 74 72 69 6e 67 2d 6c 65 6e 67 74 68 20   (string-length 
0770: 62 6f 64 79 29 29 29 0a 20 20 20 20 28 66 6f 72  body))).    (for
0780: 2d 65 61 63 68 0a 20 20 20 20 20 28 6c 61 6d 62  -each.     (lamb
0790: 64 61 20 28 68 65 61 64 65 72 29 0a 20 20 20 20  da (header).    
07a0: 20 20 20 28 63 61 6c 6c 2d 77 69 74 68 2d 76 61     (call-with-va
07b0: 6c 75 65 73 20 28 63 75 74 20 63 61 72 2b 63 64  lues (cut car+cd
07c0: 72 20 68 65 61 64 65 72 29 0a 09 20 28 63 75 74  r header).. (cut
07d0: 20 66 70 72 69 6e 74 66 20 70 6f 72 74 20 22 7e   fprintf port "~
07e0: 61 3a 20 7e 61 5c 72 5c 6e 22 20 3c 3e 20 3c 3e  a: ~a\r\n" <> <>
07f0: 29 29 29 0a 20 20 20 20 20 28 6d 65 73 73 61 67  ))).     (messag
0800: 65 2d 68 65 61 64 65 72 73 20 6d 73 67 29 29 0a  e-headers msg)).
0810: 20 20 20 20 28 64 69 73 70 6c 61 79 20 22 5c 72      (display "\r
0820: 5c 6e 22 20 70 6f 72 74 29 0a 20 20 20 20 28 77  \n" port).    (w
0830: 68 65 6e 20 62 6f 64 79 0a 20 20 20 20 20 20 28  hen body.      (
0840: 64 69 73 70 6c 61 79 20 62 6f 64 79 20 70 6f 72  display body por
0850: 74 29 29 29 29 0a 0a 3b 3b 3b 20 52 65 71 75 65  t))))..;;; Reque
0860: 73 74 20 70 72 6f 63 65 73 73 69 6e 67 20 69 6e  st processing in
0870: 66 72 61 73 74 72 75 63 74 75 72 65 0a 0a 28 64  frastructure..(d
0880: 65 66 69 6e 65 20 6d 61 78 2d 72 65 71 75 65 73  efine max-reques
0890: 74 2d 73 69 7a 65 0a 20 20 28 6d 61 6b 65 2d 70  t-size.  (make-p
08a0: 61 72 61 6d 65 74 65 72 20 23 78 66 66 66 66 29  arameter #xffff)
08b0: 29 0a 0a 28 64 65 66 69 6e 65 2d 76 61 6c 75 65  )..(define-value
08c0: 73 20 28 72 65 71 75 65 73 74 2d 6d 65 74 68 6f  s (request-metho
08d0: 64 2d 68 61 6e 64 6c 65 72 20 68 61 6e 64 6c 65  d-handler handle
08e0: 64 2d 72 65 71 75 65 73 74 2d 6d 65 74 68 6f 64  d-request-method
08f0: 73 29 0a 20 20 28 6c 65 74 20 28 28 68 61 6e 64  s).  (let ((hand
0900: 6c 65 72 73 20 28 6d 61 6b 65 2d 68 61 73 68 2d  lers (make-hash-
0910: 74 61 62 6c 65 20 23 3a 74 65 73 74 20 73 74 72  table #:test str
0920: 69 6e 67 2d 63 69 3d 3f 20 23 3a 68 61 73 68 20  ing-ci=? #:hash 
0930: 73 74 72 69 6e 67 2d 63 69 2d 68 61 73 68 29 29  string-ci-hash))
0940: 29 0a 20 20 20 20 28 76 61 6c 75 65 73 0a 20 20  ).    (values.  
0950: 20 20 20 28 63 61 73 65 2d 6c 61 6d 62 64 61 0a     (case-lambda.
0960: 20 20 20 20 20 20 20 28 28 6e 61 6d 65 29 0a 09         ((name)..
0970: 28 68 61 73 68 2d 74 61 62 6c 65 2d 72 65 66 2f  (hash-table-ref/
0980: 64 65 66 61 75 6c 74 20 68 61 6e 64 6c 65 72 73  default handlers
0990: 20 6e 61 6d 65 20 23 66 29 29 0a 20 20 20 20 20   name #f)).     
09a0: 20 20 28 28 6e 61 6d 65 20 70 72 6f 63 29 0a 09    ((name proc)..
09b0: 28 68 61 73 68 2d 74 61 62 6c 65 2d 73 65 74 21  (hash-table-set!
09c0: 20 68 61 6e 64 6c 65 72 73 20 6e 61 6d 65 20 70   handlers name p
09d0: 72 6f 63 29 29 29 0a 20 20 20 20 20 28 63 75 74  roc))).     (cut
09e0: 20 68 61 73 68 2d 74 61 62 6c 65 2d 6b 65 79 73   hash-table-keys
09f0: 20 68 61 6e 64 6c 65 72 73 29 29 29 29 0a 0a 28   handlers))))..(
0a00: 64 65 66 69 6e 65 20 72 65 71 75 65 73 74 2d 62  define request-b
0a10: 6f 64 79 2d 68 61 6e 64 6c 65 72 0a 20 20 28 6c  ody-handler.  (l
0a20: 65 74 20 28 28 68 61 6e 64 6c 65 72 73 20 28 6d  et ((handlers (m
0a30: 61 6b 65 2d 68 61 73 68 2d 74 61 62 6c 65 20 23  ake-hash-table #
0a40: 3a 74 65 73 74 20 73 74 72 69 6e 67 2d 63 69 3d  :test string-ci=
0a50: 3f 20 23 3a 68 61 73 68 20 73 74 72 69 6e 67 2d  ? #:hash string-
0a60: 63 69 2d 68 61 73 68 29 29 29 0a 20 20 20 20 28  ci-hash))).    (
0a70: 63 61 73 65 2d 6c 61 6d 62 64 61 0a 20 20 20 20  case-lambda.    
0a80: 20 20 28 28 6e 61 6d 65 29 0a 20 20 20 20 20 20    ((name).      
0a90: 20 28 68 61 73 68 2d 74 61 62 6c 65 2d 72 65 66   (hash-table-ref
0aa0: 2f 64 65 66 61 75 6c 74 20 68 61 6e 64 6c 65 72  /default handler
0ab0: 73 20 6e 61 6d 65 20 23 66 29 29 0a 20 20 20 20  s name #f)).    
0ac0: 20 20 28 28 6e 61 6d 65 20 70 72 6f 63 29 0a 20    ((name proc). 
0ad0: 20 20 20 20 20 20 28 68 61 73 68 2d 74 61 62 6c        (hash-tabl
0ae0: 65 2d 73 65 74 21 20 68 61 6e 64 6c 65 72 73 20  e-set! handlers 
0af0: 6e 61 6d 65 20 70 72 6f 63 29 29 29 29 29 0a 0a  name proc)))))..
0b00: 28 64 65 66 69 6e 65 20 72 65 71 75 65 73 74 2d  (define request-
0b10: 70 61 72 61 6d 65 74 65 72 2d 68 61 6e 64 6c 65  parameter-handle
0b20: 72 0a 20 20 28 6c 65 74 20 28 28 68 61 6e 64 6c  r.  (let ((handl
0b30: 65 72 0a 09 20 28 6c 61 6d 62 64 61 20 28 70 61  er.. (lambda (pa
0b40: 72 61 6d 65 74 65 72 73 20 6b 65 79 20 6d 73 67  rameters key msg
0b50: 29 0a 09 20 20 20 28 68 61 73 68 2d 74 61 62 6c  )..   (hash-tabl
0b60: 65 2d 75 70 64 61 74 65 21 2f 64 65 66 61 75 6c  e-update!/defaul
0b70: 74 0a 09 20 20 20 20 70 61 72 61 6d 65 74 65 72  t..    parameter
0b80: 73 20 6b 65 79 20 28 63 75 74 20 61 70 70 65 6e  s key (cut appen
0b90: 64 21 20 3c 3e 20 28 6c 69 73 74 20 6d 73 67 29  d! <> (list msg)
0ba0: 29 20 27 28 29 29 29 29 29 0a 20 20 20 20 28 63  ) '())))).    (c
0bb0: 61 73 65 2d 6c 61 6d 62 64 61 0a 20 20 20 20 20  ase-lambda.     
0bc0: 28 28 29 0a 20 20 20 20 20 20 68 61 6e 64 6c 65  (().      handle
0bd0: 72 29 0a 20 20 20 20 20 28 28 70 72 6f 63 29 0a  r).     ((proc).
0be0: 20 20 20 20 20 20 28 73 65 74 21 20 68 61 6e 64        (set! hand
0bf0: 6c 65 72 20 70 72 6f 63 29 29 29 29 29 0a 0a 28  ler proc)))))..(
0c00: 64 65 66 69 6e 65 20 28 70 61 72 61 6d 65 74 65  define (paramete
0c10: 72 2d 6c 69 73 74 2d 72 65 66 20 70 61 72 61 6d  r-list-ref param
0c20: 65 74 65 72 73 20 6b 65 79 20 23 21 6f 70 74 69  eters key #!opti
0c30: 6f 6e 61 6c 20 28 63 6f 6e 76 65 72 74 20 6d 65  onal (convert me
0c40: 73 73 61 67 65 2d 74 65 78 74 29 29 0a 20 20 28  ssage-text)).  (
0c50: 6d 61 70 20 63 6f 6e 76 65 72 74 20 28 68 61 73  map convert (has
0c60: 68 2d 74 61 62 6c 65 2d 72 65 66 2f 64 65 66 61  h-table-ref/defa
0c70: 75 6c 74 20 70 61 72 61 6d 65 74 65 72 73 20 6b  ult parameters k
0c80: 65 79 20 27 28 29 29 29 29 0a 0a 28 64 65 66 69  ey '())))..(defi
0c90: 6e 65 20 28 70 61 72 61 6d 65 74 65 72 2d 72 65  ne (parameter-re
0ca0: 66 20 70 61 72 61 6d 65 74 65 72 73 20 6b 65 79  f parameters key
0cb0: 20 23 21 6f 70 74 69 6f 6e 61 6c 20 28 63 6f 6e   #!optional (con
0cc0: 76 65 72 74 20 6d 65 73 73 61 67 65 2d 74 65 78  vert message-tex
0cd0: 74 29 29 0a 20 20 28 61 6e 64 2d 6c 65 74 2a 20  t)).  (and-let* 
0ce0: 28 28 76 73 20 28 68 61 73 68 2d 74 61 62 6c 65  ((vs (hash-table
0cf0: 2d 72 65 66 2f 64 65 66 61 75 6c 74 20 70 61 72  -ref/default par
0d00: 61 6d 65 74 65 72 73 20 6b 65 79 20 27 28 29 29  ameters key '())
0d10: 29 0a 09 20 20 20 20 20 28 28 70 61 69 72 3f 20  )..     ((pair? 
0d20: 76 73 29 29 29 0a 20 20 20 20 28 63 6f 6e 76 65  vs))).    (conve
0d30: 72 74 20 28 63 61 72 20 76 73 29 29 29 29 0a 0a  rt (car vs))))..
0d40: 3b 3b 3b 20 52 65 73 70 6f 6e 73 65 20 70 72 6f  ;;; Response pro
0d50: 63 65 73 73 69 6e 67 20 69 6e 66 72 61 73 74 72  cessing infrastr
0d60: 75 63 74 75 72 65 0a 0a 28 64 65 66 69 6e 65 2d  ucture..(define-
0d70: 72 65 63 6f 72 64 2d 74 79 70 65 20 72 65 73 6f  record-type reso
0d80: 75 72 63 65 2d 63 6f 6e 74 65 78 74 0a 20 20 25  urce-context.  %
0d90: 6d 61 6b 65 2d 72 65 73 6f 75 72 63 65 2d 63 6f  make-resource-co
0da0: 6e 74 65 78 74 20 23 74 0a 20 20 67 65 74 65 6e  ntext #t.  geten
0db0: 76 20 6d 65 74 68 6f 64 20 70 61 74 68 29 0a 0a  v method path)..
0dc0: 28 64 65 66 69 6e 65 20 63 75 72 72 65 6e 74 2d  (define current-
0dd0: 72 65 73 6f 75 72 63 65 2d 63 6f 6e 74 65 78 74  resource-context
0de0: 0a 20 20 28 6d 61 6b 65 2d 70 61 72 61 6d 65 74  .  (make-paramet
0df0: 65 72 20 23 66 29 29 0a 0a 28 64 65 66 69 6e 65  er #f))..(define
0e00: 20 73 74 61 74 75 73 2d 74 61 62 6c 65 0a 20 20   status-table.  
0e10: 28 61 6c 69 73 74 2d 3e 68 61 73 68 2d 74 61 62  (alist->hash-tab
0e20: 6c 65 0a 20 20 20 27 28 28 31 30 30 20 2e 20 22  le.   '((100 . "
0e30: 43 6f 6e 74 69 6e 75 65 22 29 0a 20 20 20 20 20  Continue").     
0e40: 28 31 30 31 20 2e 20 22 53 77 69 74 63 68 69 6e  (101 . "Switchin
0e50: 67 20 50 72 6f 74 6f 63 6f 6c 73 22 29 0a 20 20  g Protocols").  
0e60: 20 20 20 28 32 30 30 20 2e 20 22 4f 6b 22 29 0a     (200 . "Ok").
0e70: 20 20 20 20 20 28 32 30 31 20 2e 20 22 43 72 65       (201 . "Cre
0e80: 61 74 65 64 22 29 0a 20 20 20 20 20 28 32 30 32  ated").     (202
0e90: 20 2e 20 22 41 63 63 65 70 74 65 64 22 29 0a 20   . "Accepted"). 
0ea0: 20 20 20 20 28 32 30 33 20 2e 20 22 4e 6f 6e 2d      (203 . "Non-
0eb0: 41 75 74 68 6f 72 69 74 61 74 69 76 65 20 49 6e  Authoritative In
0ec0: 66 6f 72 6d 61 74 69 6f 6e 22 29 0a 20 20 20 20  formation").    
0ed0: 20 28 32 30 34 20 2e 20 22 4e 6f 20 43 6f 6e 74   (204 . "No Cont
0ee0: 65 6e 74 22 29 0a 20 20 20 20 20 28 32 30 35 20  ent").     (205 
0ef0: 2e 20 22 52 65 73 65 74 20 43 6f 6e 74 65 6e 74  . "Reset Content
0f00: 22 29 0a 20 20 20 20 20 28 32 30 36 20 2e 20 22  ").     (206 . "
0f10: 50 61 72 74 69 61 6c 20 43 6f 6e 74 65 6e 74 22  Partial Content"
0f20: 29 0a 20 20 20 20 20 28 33 30 30 20 2e 20 22 4d  ).     (300 . "M
0f30: 75 6c 74 69 70 6c 65 20 43 68 6f 69 63 65 73 22  ultiple Choices"
0f40: 29 0a 20 20 20 20 20 28 33 30 31 20 2e 20 22 4d  ).     (301 . "M
0f50: 6f 76 65 64 20 50 65 72 6d 61 6e 65 6e 74 6c 79  oved Permanently
0f60: 22 29 0a 20 20 20 20 20 28 33 30 32 20 2e 20 22  ").     (302 . "
0f70: 46 6f 75 6e 64 22 29 0a 20 20 20 20 20 28 33 30  Found").     (30
0f80: 33 20 2e 20 22 53 65 65 20 4f 74 68 65 72 22 29  3 . "See Other")
0f90: 0a 20 20 20 20 20 28 33 30 34 20 2e 20 22 4e 6f  .     (304 . "No
0fa0: 74 20 4d 6f 64 69 66 69 65 64 22 29 0a 20 20 20  t Modified").   
0fb0: 20 20 28 33 30 35 20 2e 20 22 55 73 65 20 50 72    (305 . "Use Pr
0fc0: 6f 78 79 22 29 0a 20 20 20 20 20 28 33 30 37 20  oxy").     (307 
0fd0: 2e 20 22 54 65 6d 70 6f 72 61 72 79 20 52 65 64  . "Temporary Red
0fe0: 69 72 65 63 74 22 29 0a 20 20 20 20 20 28 34 30  irect").     (40
0ff0: 30 20 2e 20 22 42 61 64 20 52 65 71 75 65 73 74  0 . "Bad Request
1000: 22 29 0a 20 20 20 20 20 28 34 30 31 20 2e 20 22  ").     (401 . "
1010: 55 6e 61 75 74 68 6f 72 69 7a 65 64 22 29 0a 20  Unauthorized"). 
1020: 20 20 20 20 28 34 30 32 20 2e 20 22 50 61 79 6d      (402 . "Paym
1030: 65 6e 74 20 52 65 71 75 69 72 65 64 22 29 0a 20  ent Required"). 
1040: 20 20 20 20 28 34 30 33 20 2e 20 22 46 6f 72 62      (403 . "Forb
1050: 69 64 64 65 6e 22 29 0a 20 20 20 20 20 28 34 30  idden").     (40
1060: 34 20 2e 20 22 4e 6f 74 20 46 6f 75 6e 64 22 29  4 . "Not Found")
1070: 0a 20 20 20 20 20 28 34 30 35 20 2e 20 22 4d 65  .     (405 . "Me
1080: 74 68 6f 64 20 4e 6f 74 20 41 6c 6c 6f 77 65 64  thod Not Allowed
1090: 22 29 0a 20 20 20 20 20 28 34 30 36 20 2e 20 22  ").     (406 . "
10a0: 4e 6f 74 20 41 63 63 65 70 74 61 62 6c 65 22 29  Not Acceptable")
10b0: 0a 20 20 20 20 20 28 34 30 37 20 2e 20 22 50 72  .     (407 . "Pr
10c0: 6f 78 79 20 41 75 74 68 65 6e 74 69 63 61 74 69  oxy Authenticati
10d0: 6f 6e 20 52 65 71 75 69 72 65 64 22 29 0a 20 20  on Required").  
10e0: 20 20 20 28 34 30 38 20 2e 20 22 52 65 71 75 65     (408 . "Reque
10f0: 73 74 20 54 69 6d 65 6f 75 74 22 29 0a 20 20 20  st Timeout").   
1100: 20 20 28 34 30 39 20 2e 20 22 43 6f 6e 66 6c 69    (409 . "Confli
1110: 63 74 22 29 0a 20 20 20 20 20 28 34 31 30 20 2e  ct").     (410 .
1120: 20 22 47 6f 6e 65 22 29 0a 20 20 20 20 20 28 34   "Gone").     (4
1130: 31 31 20 2e 20 22 4c 65 6e 67 74 68 20 52 65 71  11 . "Length Req
1140: 75 69 72 65 64 22 29 0a 20 20 20 20 20 28 34 31  uired").     (41
1150: 32 20 2e 20 22 50 72 65 63 6f 6e 64 69 74 69 6f  2 . "Preconditio
1160: 6e 20 46 61 69 6c 65 64 22 29 0a 20 20 20 20 20  n Failed").     
1170: 28 34 31 33 20 2e 20 22 52 65 71 75 65 73 74 20  (413 . "Request 
1180: 45 6e 74 69 74 79 20 54 6f 6f 20 4c 61 72 67 65  Entity Too Large
1190: 22 29 0a 20 20 20 20 20 28 34 31 34 20 2e 20 22  ").     (414 . "
11a0: 52 65 71 75 65 73 74 2d 55 52 49 20 54 6f 6f 20  Request-URI Too 
11b0: 4c 6f 6e 67 22 29 0a 20 20 20 20 20 28 34 31 35  Long").     (415
11c0: 20 2e 20 22 55 6e 73 75 70 70 6f 72 74 65 64 20   . "Unsupported 
11d0: 4d 65 64 69 61 20 54 79 70 65 22 29 0a 20 20 20  Media Type").   
11e0: 20 20 28 34 31 36 20 2e 20 22 52 65 71 75 65 73    (416 . "Reques
11f0: 74 65 64 20 52 61 6e 67 65 20 4e 6f 74 20 53 61  ted Range Not Sa
1200: 74 69 73 66 69 61 62 6c 65 22 29 0a 20 20 20 20  tisfiable").    
1210: 20 28 34 31 37 20 2e 20 22 45 78 70 65 63 74 61   (417 . "Expecta
1220: 74 69 6f 6e 20 46 61 69 6c 65 64 22 29 0a 20 20  tion Failed").  
1230: 20 20 20 28 35 30 30 20 2e 20 22 49 6e 74 65 72     (500 . "Inter
1240: 6e 61 6c 20 53 65 72 76 65 72 20 45 72 72 6f 72  nal Server Error
1250: 22 29 0a 20 20 20 20 20 28 35 30 31 20 2e 20 22  ").     (501 . "
1260: 4e 6f 74 20 49 6d 70 6c 65 6d 65 6e 74 65 64 22  Not Implemented"
1270: 29 0a 20 20 20 20 20 28 35 30 32 20 2e 20 22 42  ).     (502 . "B
1280: 61 64 20 47 61 74 65 77 61 79 22 29 0a 20 20 20  ad Gateway").   
1290: 20 20 28 35 30 33 20 2e 20 22 53 65 72 76 69 63    (503 . "Servic
12a0: 65 20 55 6e 61 76 61 69 6c 61 62 6c 65 22 29 0a  e Unavailable").
12b0: 20 20 20 20 20 28 35 30 34 20 2e 20 22 47 61 74       (504 . "Gat
12c0: 65 77 61 79 20 54 69 6d 65 6f 75 74 22 29 0a 20  eway Timeout"). 
12d0: 20 20 20 20 28 35 30 35 20 2e 20 22 48 54 54 50      (505 . "HTTP
12e0: 20 56 65 72 73 69 6f 6e 20 4e 6f 74 20 53 75 70   Version Not Sup
12f0: 70 6f 72 74 65 64 22 29 29 0a 20 20 20 23 3a 74  ported")).   #:t
1300: 65 73 74 20 3d 20 23 3a 68 61 73 68 20 6e 75 6d  est = #:hash num
1310: 62 65 72 2d 68 61 73 68 29 29 0a 0a 28 64 65 66  ber-hash))..(def
1320: 69 6e 65 2d 72 65 63 6f 72 64 2d 74 79 70 65 20  ine-record-type 
1330: 28 72 65 73 70 6f 6e 73 65 20 6d 65 73 73 61 67  (response messag
1340: 65 29 0a 20 20 25 6d 61 6b 65 2d 72 65 73 70 6f  e).  %make-respo
1350: 6e 73 65 20 23 74 0a 20 20 73 74 61 74 75 73 20  nse #t.  status 
1360: 73 74 61 74 75 73 2d 6d 65 73 73 61 67 65 29 0a  status-message).
1370: 0a 28 64 65 66 69 6e 65 20 28 6d 61 6b 65 2d 72  .(define (make-r
1380: 65 73 70 6f 6e 73 65 0a 09 20 73 74 61 74 75 73  esponse.. status
1390: 20 62 6f 64 79 20 23 21 6b 65 79 0a 09 20 28 74   body #!key.. (t
13a0: 79 70 65 20 28 61 6e 64 20 62 6f 64 79 20 22 61  ype (and body "a
13b0: 70 70 6c 69 63 61 74 69 6f 6e 2f 6f 63 74 65 74  pplication/octet
13c0: 2d 73 74 72 65 61 6d 22 29 29 0a 09 20 28 68 65  -stream")).. (he
13d0: 61 64 65 72 73 20 27 28 29 29 0a 09 20 28 73 74  aders '()).. (st
13e0: 61 74 75 73 2d 6d 65 73 73 61 67 65 0a 09 20 20  atus-message..  
13f0: 28 68 61 73 68 2d 74 61 62 6c 65 2d 72 65 66 2f  (hash-table-ref/
1400: 64 65 66 61 75 6c 74 20 73 74 61 74 75 73 2d 74  default status-t
1410: 61 62 6c 65 20 73 74 61 74 75 73 20 22 55 6e 6b  able status "Unk
1420: 6e 6f 77 6e 22 29 29 29 0a 20 20 28 25 6d 61 6b  nown"))).  (%mak
1430: 65 2d 72 65 73 70 6f 6e 73 65 0a 20 20 20 74 79  e-response.   ty
1440: 70 65 20 68 65 61 64 65 72 73 20 62 6f 64 79 0a  pe headers body.
1450: 20 20 20 73 74 61 74 75 73 20 73 74 61 74 75 73     status status
1460: 2d 6d 65 73 73 61 67 65 29 29 0a 0a 28 64 65 66  -message))..(def
1470: 69 6e 65 20 28 63 6f 6c 6c 65 63 74 2d 72 65 73  ine (collect-res
1480: 70 6f 6e 73 65 0a 09 20 73 74 61 74 75 73 20 74  ponse.. status t
1490: 68 75 6e 6b 20 23 21 6b 65 79 0a 09 20 28 74 79  hunk #!key.. (ty
14a0: 70 65 20 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f  pe "application/
14b0: 6f 63 74 65 74 2d 73 74 72 65 61 6d 22 29 0a 09  octet-stream")..
14c0: 20 28 68 65 61 64 65 72 73 20 27 28 29 29 0a 09   (headers '())..
14d0: 20 28 73 74 61 74 75 73 2d 6d 65 73 73 61 67 65   (status-message
14e0: 0a 09 20 20 28 68 61 73 68 2d 74 61 62 6c 65 2d  ..  (hash-table-
14f0: 72 65 66 2f 64 65 66 61 75 6c 74 20 73 74 61 74  ref/default stat
1500: 75 73 2d 74 61 62 6c 65 20 73 74 61 74 75 73 20  us-table status 
1510: 22 55 6e 6b 6e 6f 77 6e 22 29 29 29 0a 20 20 28  "Unknown"))).  (
1520: 25 6d 61 6b 65 2d 72 65 73 70 6f 6e 73 65 0a 20  %make-response. 
1530: 20 20 74 79 70 65 20 68 65 61 64 65 72 73 20 28    type headers (
1540: 77 69 74 68 2d 6f 75 74 70 75 74 2d 74 6f 2d 73  with-output-to-s
1550: 74 72 69 6e 67 20 74 68 75 6e 6b 29 0a 20 20 20  tring thunk).   
1560: 73 74 61 74 75 73 20 73 74 61 74 75 73 2d 6d 65  status status-me
1570: 73 73 61 67 65 29 29 0a 0a 28 64 65 66 69 6e 65  ssage))..(define
1580: 20 28 6d 61 6b 65 2d 68 74 6d 6c 2d 72 65 73 70   (make-html-resp
1590: 6f 6e 73 65 0a 09 20 73 74 61 74 75 73 20 68 74  onse.. status ht
15a0: 6d 6c 20 23 21 6b 65 79 0a 09 20 28 73 74 61 74  ml #!key.. (stat
15b0: 75 73 2d 6d 65 73 73 61 67 65 0a 09 20 20 28 68  us-message..  (h
15c0: 61 73 68 2d 74 61 62 6c 65 2d 72 65 66 2f 64 65  ash-table-ref/de
15d0: 66 61 75 6c 74 20 73 74 61 74 75 73 2d 74 61 62  fault status-tab
15e0: 6c 65 20 73 74 61 74 75 73 20 22 55 6e 6b 6e 6f  le status "Unkno
15f0: 77 6e 22 29 29 0a 09 20 28 68 65 61 64 65 72 73  wn")).. (headers
1600: 20 27 28 29 29 29 0a 20 20 28 25 6d 61 6b 65 2d   '())).  (%make-
1610: 72 65 73 70 6f 6e 73 65 0a 20 20 20 22 74 65 78  response.   "tex
1620: 74 2f 68 74 6d 6c 22 20 68 65 61 64 65 72 73 20  t/html" headers 
1630: 28 63 61 6c 6c 2d 77 69 74 68 2d 6f 75 74 70 75  (call-with-outpu
1640: 74 2d 73 74 72 69 6e 67 20 28 63 75 74 20 77 72  t-string (cut wr
1650: 69 74 65 2d 68 74 6d 6c 20 68 74 6d 6c 20 3c 3e  ite-html html <>
1660: 29 29 0a 20 20 20 73 74 61 74 75 73 20 73 74 61  )).   status sta
1670: 74 75 73 2d 6d 65 73 73 61 67 65 29 29 0a 0a 28  tus-message))..(
1680: 64 65 66 69 6e 65 20 28 6d 61 6b 65 2d 65 72 72  define (make-err
1690: 6f 72 2d 72 65 73 70 6f 6e 73 65 0a 09 20 73 74  or-response.. st
16a0: 61 74 75 73 20 6d 65 73 73 61 67 65 20 23 21 6b  atus message #!k
16b0: 65 79 0a 09 20 28 73 74 61 74 75 73 2d 6d 65 73  ey.. (status-mes
16c0: 73 61 67 65 0a 09 20 20 28 68 61 73 68 2d 74 61  sage..  (hash-ta
16d0: 62 6c 65 2d 72 65 66 2f 64 65 66 61 75 6c 74 20  ble-ref/default 
16e0: 73 74 61 74 75 73 2d 74 61 62 6c 65 20 73 74 61  status-table sta
16f0: 74 75 73 20 22 55 6e 6b 6e 6f 77 6e 22 29 29 0a  tus "Unknown")).
1700: 09 20 28 68 65 61 64 65 72 73 20 27 28 29 29 29  . (headers '()))
1710: 0a 20 20 28 6d 61 6b 65 2d 68 74 6d 6c 2d 72 65  .  (make-html-re
1720: 73 70 6f 6e 73 65 0a 20 20 20 73 74 61 74 75 73  sponse.   status
1730: 0a 20 20 20 28 6c 65 74 20 28 28 73 74 61 74 75  .   (let ((statu
1740: 73 2d 6c 69 6e 65 20 28 73 70 72 69 6e 74 66 20  s-line (sprintf 
1750: 22 7e 61 20 7e 61 22 20 73 74 61 74 75 73 20 73  "~a ~a" status s
1760: 74 61 74 75 73 2d 6d 65 73 73 61 67 65 29 29 29  tatus-message)))
1770: 0a 20 20 20 20 20 60 28 68 74 6d 6c 0a 20 20 20  .     `(html.   
1780: 20 20 20 20 28 68 65 61 64 0a 09 28 6d 65 74 61      (head..(meta
1790: 20 28 28 6e 61 6d 65 20 22 72 6f 62 6f 74 73 22   ((name "robots"
17a0: 29 20 28 63 6f 6e 74 65 6e 74 20 22 6e 6f 69 6e  ) (content "noin
17b0: 64 65 78 22 29 29 29 0a 09 28 74 69 74 6c 65 20  dex")))..(title 
17c0: 2c 73 74 61 74 75 73 2d 6c 69 6e 65 29 29 0a 20  ,status-line)). 
17d0: 20 20 20 20 20 20 28 62 6f 64 79 0a 09 28 68 31        (body..(h1
17e0: 20 2c 73 74 61 74 75 73 2d 6c 69 6e 65 29 0a 09   ,status-line)..
17f0: 28 70 20 2c 6d 65 73 73 61 67 65 29 29 29 29 0a  (p ,message)))).
1800: 20 20 20 23 3a 73 74 61 74 75 73 2d 6d 65 73 73     #:status-mess
1810: 61 67 65 20 73 74 61 74 75 73 2d 6d 65 73 73 61  age status-messa
1820: 67 65 0a 20 20 20 23 3a 68 65 61 64 65 72 73 20  ge.   #:headers 
1830: 68 65 61 64 65 72 73 29 29 0a 0a 28 64 65 66 69  headers))..(defi
1840: 6e 65 20 6d 61 6b 65 2d 72 65 64 69 72 65 63 74  ne make-redirect
1850: 2d 72 65 73 70 6f 6e 73 65 0a 20 20 28 63 61 73  -response.  (cas
1860: 65 2d 6c 61 6d 62 64 61 0a 20 20 20 28 28 73 74  e-lambda.   ((st
1870: 61 74 75 73 20 74 61 72 67 65 74 29 0a 20 20 20  atus target).   
1880: 20 28 6d 61 6b 65 2d 65 72 72 6f 72 2d 72 65 73   (make-error-res
1890: 70 6f 6e 73 65 0a 20 20 20 20 20 73 74 61 74 75  ponse.     statu
18a0: 73 20 60 28 61 20 28 28 68 72 65 66 20 2c 74 61  s `(a ((href ,ta
18b0: 72 67 65 74 29 29 20 2c 74 61 72 67 65 74 29 0a  rget)) ,target).
18c0: 20 20 20 20 20 23 3a 68 65 61 64 65 72 73 20 60       #:headers `
18d0: 28 28 22 4c 6f 63 61 74 69 6f 6e 22 20 2e 20 2c  (("Location" . ,
18e0: 74 61 72 67 65 74 29 29 29 29 0a 20 20 20 28 28  target)))).   ((
18f0: 74 61 72 67 65 74 29 0a 20 20 20 20 28 6d 61 6b  target).    (mak
1900: 65 2d 65 72 72 6f 72 2d 72 65 73 70 6f 6e 73 65  e-error-response
1910: 0a 20 20 20 20 20 33 30 32 20 60 28 61 20 28 28  .     302 `(a ((
1920: 68 72 65 66 20 2c 74 61 72 67 65 74 29 29 20 2c  href ,target)) ,
1930: 74 61 72 67 65 74 29 0a 20 20 20 20 20 23 3a 68  target).     #:h
1940: 65 61 64 65 72 73 20 60 28 28 22 4c 6f 63 61 74  eaders `(("Locat
1950: 69 6f 6e 22 20 2e 20 2c 74 61 72 67 65 74 29 29  ion" . ,target))
1960: 29 29 29 29 0a 0a 28 64 65 66 69 6e 65 20 28 77  ))))..(define (w
1970: 72 69 74 65 2d 72 65 73 70 6f 6e 73 65 20 72 73  rite-response rs
1980: 70 20 23 21 6f 70 74 69 6f 6e 61 6c 20 28 70 6f  p #!optional (po
1990: 72 74 20 28 63 75 72 72 65 6e 74 2d 6f 75 74 70  rt (current-outp
19a0: 75 74 2d 70 6f 72 74 29 29 29 0a 20 20 28 66 70  ut-port))).  (fp
19b0: 72 69 6e 74 66 0a 20 20 20 70 6f 72 74 20 22 53  rintf.   port "S
19c0: 74 61 74 75 73 3a 20 7e 61 20 7e 61 5c 72 5c 6e  tatus: ~a ~a\r\n
19d0: 22 0a 20 20 20 28 72 65 73 70 6f 6e 73 65 2d 73  ".   (response-s
19e0: 74 61 74 75 73 20 72 73 70 29 20 28 72 65 73 70  tatus rsp) (resp
19f0: 6f 6e 73 65 2d 73 74 61 74 75 73 2d 6d 65 73 73  onse-status-mess
1a00: 61 67 65 20 72 73 70 29 29 0a 20 20 28 77 72 69  age rsp)).  (wri
1a10: 74 65 2d 6d 65 73 73 61 67 65 20 72 73 70 20 70  te-message rsp p
1a20: 6f 72 74 29 29 0a 0a 28 64 65 66 69 6e 65 20 72  ort))..(define r
1a30: 65 73 6f 75 72 63 65 2d 68 61 6e 64 6c 65 72 0a  esource-handler.
1a40: 20 20 28 6c 65 74 20 28 28 68 61 6e 64 6c 65 72    (let ((handler
1a50: 73 20 28 6d 61 6b 65 2d 68 61 73 68 2d 74 61 62  s (make-hash-tab
1a60: 6c 65 29 29 29 0a 20 20 20 20 28 63 61 73 65 2d  le))).    (case-
1a70: 6c 61 6d 62 64 61 0a 20 20 20 20 20 20 28 28 70  lambda.      ((p
1a80: 61 74 68 29 0a 20 20 20 20 20 20 20 28 6c 65 74  ath).       (let
1a90: 20 6e 65 78 74 20 28 28 68 61 6e 64 6c 65 72 73   next ((handlers
1aa0: 20 68 61 6e 64 6c 65 72 73 29 20 28 61 72 67 73   handlers) (args
1ab0: 20 27 28 29 29 20 28 70 61 74 68 20 70 61 74 68   '()) (path path
1ac0: 29 29 0a 09 20 28 69 66 20 28 70 61 69 72 3f 20  )).. (if (pair? 
1ad0: 70 61 74 68 29 0a 09 20 20 20 20 20 28 6c 65 74  path)..     (let
1ae0: 2d 76 61 6c 75 65 73 20 28 28 28 73 74 65 70 20  -values (((step 
1af0: 70 61 74 68 29 20 28 63 61 72 2b 63 64 72 20 70  path) (car+cdr p
1b00: 61 74 68 29 29 29 0a 09 20 20 20 20 20 20 20 28  ath)))..       (
1b10: 63 6f 6e 64 0a 09 09 28 28 68 61 73 68 2d 74 61  cond...((hash-ta
1b20: 62 6c 65 2d 72 65 66 2f 64 65 66 61 75 6c 74 20  ble-ref/default 
1b30: 68 61 6e 64 6c 65 72 73 20 73 74 65 70 20 23 66  handlers step #f
1b40: 29 0a 09 09 20 3d 3e 20 28 63 75 74 20 6e 65 78  )... => (cut nex
1b50: 74 20 3c 3e 20 61 72 67 73 20 70 61 74 68 29 29  t <> args path))
1b60: 0a 09 09 28 28 68 61 73 68 2d 74 61 62 6c 65 2d  ...((hash-table-
1b70: 72 65 66 2f 64 65 66 61 75 6c 74 20 68 61 6e 64  ref/default hand
1b80: 6c 65 72 73 20 23 66 20 23 66 29 0a 09 09 20 3d  lers #f #f)... =
1b90: 3e 20 28 63 75 74 20 6e 65 78 74 20 3c 3e 20 28  > (cut next <> (
1ba0: 63 6f 6e 73 20 73 74 65 70 20 61 72 67 73 29 20  cons step args) 
1bb0: 70 61 74 68 29 29 0a 09 09 28 65 6c 73 65 0a 09  path))...(else..
1bc0: 09 20 23 66 29 29 29 0a 09 20 20 20 20 20 28 63  . #f)))..     (c
1bd0: 6f 6e 64 0a 09 20 20 20 20 20 20 28 28 68 61 73  ond..      ((has
1be0: 68 2d 74 61 62 6c 65 2d 72 65 66 2f 64 65 66 61  h-table-ref/defa
1bf0: 75 6c 74 20 68 61 6e 64 6c 65 72 73 20 23 74 20  ult handlers #t 
1c00: 23 66 29 0a 09 20 20 20 20 20 20 20 3d 3e 20 28  #f)..       => (
1c10: 6c 61 6d 62 64 61 20 28 70 72 6f 63 29 0a 09 09  lambda (proc)...
1c20: 20 20 20 20 28 6c 61 6d 62 64 61 20 28 70 61 72      (lambda (par
1c30: 61 6d 65 74 65 72 73 29 0a 09 09 20 20 20 20 20  ameters)...     
1c40: 20 28 61 70 70 6c 79 20 70 72 6f 63 20 28 72 65   (apply proc (re
1c50: 76 65 72 73 65 21 20 28 63 6f 6e 73 2a 20 70 61  verse! (cons* pa
1c60: 72 61 6d 65 74 65 72 73 20 61 72 67 73 29 29 29  rameters args)))
1c70: 29 29 29 0a 09 20 20 20 20 20 20 28 65 6c 73 65  )))..      (else
1c80: 0a 09 20 20 20 20 20 20 20 23 66 29 29 29 29 29  ..       #f)))))
1c90: 0a 20 20 20 20 20 20 28 28 70 61 74 68 20 70 72  .      ((path pr
1ca0: 6f 63 29 0a 20 20 20 20 20 20 20 28 6c 65 74 20  oc).       (let 
1cb0: 6e 65 78 74 20 28 28 68 61 6e 64 6c 65 72 73 20  next ((handlers 
1cc0: 68 61 6e 64 6c 65 72 73 29 20 28 70 61 74 68 20  handlers) (path 
1cd0: 70 61 74 68 29 29 0a 09 20 28 69 66 20 28 70 61  path)).. (if (pa
1ce0: 69 72 3f 20 70 61 74 68 29 0a 09 20 20 20 20 20  ir? path)..     
1cf0: 28 6c 65 74 2d 76 61 6c 75 65 73 20 28 28 28 73  (let-values (((s
1d00: 74 65 70 20 70 61 74 68 29 20 28 63 61 72 2b 63  tep path) (car+c
1d10: 64 72 20 70 61 74 68 29 29 29 0a 09 20 20 20 20  dr path)))..    
1d20: 20 20 20 28 68 61 73 68 2d 74 61 62 6c 65 2d 75     (hash-table-u
1d30: 70 64 61 74 65 21 0a 09 09 68 61 6e 64 6c 65 72  pdate!...handler
1d40: 73 20 73 74 65 70 20 28 63 75 74 20 6e 65 78 74  s step (cut next
1d50: 20 3c 3e 20 70 61 74 68 29 20 6d 61 6b 65 2d 68   <> path) make-h
1d60: 61 73 68 2d 74 61 62 6c 65 29 29 0a 09 20 20 20  ash-table))..   
1d70: 20 20 28 68 61 73 68 2d 74 61 62 6c 65 2d 73 65    (hash-table-se
1d80: 74 21 20 68 61 6e 64 6c 65 72 73 20 23 74 20 70  t! handlers #t p
1d90: 72 6f 63 29 29 0a 09 20 68 61 6e 64 6c 65 72 73  roc)).. handlers
1da0: 29 0a 20 20 20 20 20 20 20 28 76 6f 69 64 29 29  ).       (void))
1db0: 29 29 29 0a 0a 28 64 65 66 69 6e 65 2d 73 79 6e  )))..(define-syn
1dc0: 74 61 78 20 64 65 66 69 6e 65 2d 72 65 73 6f 75  tax define-resou
1dd0: 72 63 65 0a 20 20 28 73 79 6e 74 61 78 2d 72 75  rce.  (syntax-ru
1de0: 6c 65 73 20 28 29 0a 20 20 20 20 28 28 64 65 66  les ().    ((def
1df0: 69 6e 65 2d 72 65 73 6f 75 72 63 65 20 28 6e 61  ine-resource (na
1e00: 6d 65 20 73 74 65 70 2f 61 72 67 20 2e 2e 2e 20  me step/arg ... 
1e10: 70 61 72 61 6d 65 74 65 72 73 29 0a 20 20 20 20  parameters).    
1e20: 20 20 20 65 78 70 72 20 2e 2e 2e 29 0a 20 20 20     expr ...).   
1e30: 20 20 28 62 65 67 69 6e 0a 20 20 20 20 20 20 20    (begin.       
1e40: 28 64 65 66 69 6e 65 20 6e 61 6d 65 0a 09 20 28  (define name.. (
1e50: 6c 65 74 2d 73 79 6e 74 61 78 20 28 28 70 61 74  let-syntax ((pat
1e60: 68 0a 09 09 20 20 20 20 20 20 20 28 69 72 2d 6d  h...       (ir-m
1e70: 61 63 72 6f 2d 74 72 61 6e 73 66 6f 72 6d 65 72  acro-transformer
1e80: 0a 09 09 09 28 6c 61 6d 62 64 61 20 28 73 74 78  ....(lambda (stx
1e90: 20 69 6e 6a 65 63 74 20 69 64 3d 3f 29 0a 09 09   inject id=?)...
1ea0: 09 20 20 28 6c 65 74 20 28 28 73 74 65 70 73 20  .  (let ((steps 
1eb0: 28 63 64 72 20 73 74 78 29 29 29 0a 09 09 09 20  (cdr stx))).... 
1ec0: 20 20 20 60 28 6c 69 73 74 20 2c 40 28 6d 61 70     `(list ,@(map
1ed0: 0a 09 09 09 09 20 20 20 20 20 20 28 6c 61 6d 62  .....      (lamb
1ee0: 64 61 20 28 73 74 65 70 29 0a 09 09 09 09 09 28  da (step)......(
1ef0: 61 6e 64 20 28 73 74 72 69 6e 67 3f 20 73 74 65  and (string? ste
1f00: 70 29 20 73 74 65 70 29 29 0a 09 09 09 09 20 20  p) step)).....  
1f10: 20 20 20 20 73 74 65 70 73 29 29 29 29 29 29 0a      steps)))))).
1f20: 09 09 20 20 20 20 20 20 28 70 61 74 68 2d 6c 61  ..      (path-la
1f30: 6d 62 64 61 0a 09 09 20 20 20 20 20 20 20 28 69  mbda...       (i
1f40: 72 2d 6d 61 63 72 6f 2d 74 72 61 6e 73 66 6f 72  r-macro-transfor
1f50: 6d 65 72 0a 09 09 09 28 6c 61 6d 62 64 61 20 28  mer....(lambda (
1f60: 73 74 78 20 69 6e 6a 65 63 74 20 69 64 3d 3f 29  stx inject id=?)
1f70: 0a 09 09 09 20 20 28 6c 65 74 20 28 28 73 74 65  ....  (let ((ste
1f80: 70 73 20 28 63 61 64 72 20 73 74 78 29 29 0a 09  ps (cadr stx))..
1f90: 09 09 09 28 62 6f 64 79 20 28 63 64 64 72 20 73  ...(body (cddr s
1fa0: 74 78 29 29 29 0a 09 09 09 20 20 20 20 60 28 6c  tx)))....    `(l
1fb0: 61 6d 62 64 61 20 2c 28 66 69 6c 74 65 72 2d 6d  ambda ,(filter-m
1fc0: 61 70 0a 09 09 09 09 20 20 20 20 20 20 20 28 6c  ap.....       (l
1fd0: 61 6d 62 64 61 20 28 73 74 65 70 29 0a 09 09 09  ambda (step)....
1fe0: 09 09 20 28 61 6e 64 20 28 73 79 6d 62 6f 6c 3f  .. (and (symbol?
1ff0: 20 73 74 65 70 29 20 73 74 65 70 29 29 0a 09 09   step) step))...
2000: 09 09 20 20 20 20 20 20 20 73 74 65 70 73 29 0a  ..       steps).
2010: 09 09 09 20 20 20 20 20 20 20 2c 40 62 6f 64 79  ...       ,@body
2020: 29 29 29 29 29 29 0a 09 20 20 20 28 65 78 74 65  ))))))..   (exte
2030: 6e 64 2d 70 72 6f 63 65 64 75 72 65 0a 09 20 20  nd-procedure..  
2040: 20 20 28 70 61 74 68 2d 6c 61 6d 62 64 61 20 28    (path-lambda (
2050: 73 74 65 70 2f 61 72 67 20 2e 2e 2e 20 70 61 72  step/arg ... par
2060: 61 6d 65 74 65 72 73 29 0a 09 20 20 20 20 20 20  ameters)..      
2070: 65 78 70 72 20 2e 2e 2e 29 0a 09 20 20 20 20 28  expr ...)..    (
2080: 70 61 74 68 20 73 74 65 70 2f 61 72 67 20 2e 2e  path step/arg ..
2090: 2e 29 29 29 29 0a 20 20 20 20 20 20 20 28 72 65  .)))).       (re
20a0: 73 6f 75 72 63 65 2d 68 61 6e 64 6c 65 72 20 28  source-handler (
20b0: 70 72 6f 63 65 64 75 72 65 2d 64 61 74 61 20 6e  procedure-data n
20c0: 61 6d 65 29 20 6e 61 6d 65 29 29 29 29 29 0a 0a  ame) name)))))..
20d0: 28 64 65 66 69 6e 65 20 28 77 72 69 74 65 2d 75  (define (write-u
20e0: 72 69 2d 73 74 65 70 20 73 74 65 70 20 70 6f 72  ri-step step por
20f0: 74 29 0a 20 20 28 66 70 72 69 6e 74 66 20 70 6f  t).  (fprintf po
2100: 72 74 20 22 2f 7e 61 22 20 28 75 72 69 2d 65 6e  rt "/~a" (uri-en
2110: 63 6f 64 65 20 73 74 65 70 29 29 29 0a 0a 28 64  code step)))..(d
2120: 65 66 69 6e 65 20 28 72 65 73 6f 75 72 63 65 2d  efine (resource-
2130: 75 72 69 20 72 65 73 20 2e 20 61 72 67 73 29 0a  uri res . args).
2140: 20 20 28 63 61 6c 6c 2d 77 69 74 68 2d 6f 75 74    (call-with-out
2150: 70 75 74 2d 73 74 72 69 6e 67 0a 20 20 20 28 6c  put-string.   (l
2160: 61 6d 62 64 61 20 28 70 6f 72 74 29 0a 20 20 20  ambda (port).   
2170: 20 20 28 66 6f 72 2d 65 61 63 68 0a 20 20 20 20    (for-each.    
2180: 20 20 28 63 75 74 20 77 72 69 74 65 2d 75 72 69    (cut write-uri
2190: 2d 73 74 65 70 20 3c 3e 20 70 6f 72 74 29 0a 20  -step <> port). 
21a0: 20 20 20 20 20 28 73 74 72 69 6e 67 2d 73 70 6c       (string-spl
21b0: 69 74 0a 20 20 20 20 20 20 20 28 6f 72 20 28 28  it.       (or ((
21c0: 72 65 73 6f 75 72 63 65 2d 63 6f 6e 74 65 78 74  resource-context
21d0: 2d 67 65 74 65 6e 76 20 28 63 75 72 72 65 6e 74  -getenv (current
21e0: 2d 72 65 73 6f 75 72 63 65 2d 63 6f 6e 74 65 78  -resource-contex
21f0: 74 29 29 20 22 53 43 52 49 50 54 5f 4e 41 4d 45  t)) "SCRIPT_NAME
2200: 22 29 0a 09 20 20 20 22 22 29 0a 20 20 20 20 20  ")..   "").     
2210: 20 20 22 2f 22 29 29 0a 20 20 20 20 20 28 6c 65    "/")).     (le
2220: 74 20 6e 65 78 74 20 28 28 73 74 65 70 73 20 28  t next ((steps (
2230: 70 72 6f 63 65 64 75 72 65 2d 64 61 74 61 20 72  procedure-data r
2240: 65 73 29 29 20 28 61 72 67 73 20 61 72 67 73 29  es)) (args args)
2250: 29 0a 20 20 20 20 20 20 20 28 69 66 20 28 70 61  ).       (if (pa
2260: 69 72 3f 20 73 74 65 70 73 29 0a 09 20 20 20 28  ir? steps)..   (
2270: 6c 65 74 2d 76 61 6c 75 65 73 20 28 28 28 73 74  let-values (((st
2280: 65 70 20 73 74 65 70 73 29 20 28 63 61 72 2b 63  ep steps) (car+c
2290: 64 72 20 73 74 65 70 73 29 29 29 0a 09 20 20 20  dr steps)))..   
22a0: 20 20 28 69 66 20 73 74 65 70 0a 09 09 20 28 62    (if step... (b
22b0: 65 67 69 6e 0a 09 09 20 20 20 28 77 72 69 74 65  egin...   (write
22c0: 2d 75 72 69 2d 73 74 65 70 20 73 74 65 70 20 70  -uri-step step p
22d0: 6f 72 74 29 0a 09 09 20 20 20 28 6e 65 78 74 20  ort)...   (next 
22e0: 73 74 65 70 73 20 61 72 67 73 29 29 0a 09 09 20  steps args))... 
22f0: 28 69 66 20 28 70 61 69 72 3f 20 61 72 67 73 29  (if (pair? args)
2300: 0a 09 09 20 20 20 20 20 28 6c 65 74 2d 76 61 6c  ...     (let-val
2310: 75 65 73 20 28 28 28 61 72 67 20 61 72 67 73 29  ues (((arg args)
2320: 20 28 63 61 72 2b 63 64 72 20 61 72 67 73 29 29   (car+cdr args))
2330: 29 0a 09 09 20 20 20 20 20 20 20 28 77 72 69 74  )...       (writ
2340: 65 2d 75 72 69 2d 73 74 65 70 20 61 72 67 20 70  e-uri-step arg p
2350: 6f 72 74 29 0a 09 09 20 20 20 20 20 20 20 28 6e  ort)...       (n
2360: 65 78 74 20 73 74 65 70 73 20 61 72 67 73 29 29  ext steps args))
2370: 0a 09 09 20 20 20 20 20 28 65 72 72 6f 72 20 27  ...     (error '
2380: 72 65 73 6f 75 72 63 65 2d 75 72 69 20 22 74 6f  resource-uri "to
2390: 6f 20 66 65 77 20 61 72 67 75 6d 65 6e 74 73 22  o few arguments"
23a0: 29 29 29 29 0a 09 20 20 20 28 75 6e 6c 65 73 73  ))))..   (unless
23b0: 20 28 6e 75 6c 6c 3f 20 61 72 67 73 29 0a 09 20   (null? args).. 
23c0: 20 20 20 20 28 65 72 72 6f 72 20 27 72 65 73 6f      (error 'reso
23d0: 75 72 63 65 2d 75 72 69 20 22 74 6f 6f 20 6d 61  urce-uri "too ma
23e0: 6e 79 20 61 72 67 75 6d 65 6e 74 73 22 20 61 72  ny arguments" ar
23f0: 67 73 29 29 29 29 29 29 29 0a 0a 3b 3b 3b 20 50  gs)))))))..;;; P
2400: 72 65 2d 69 6e 73 74 61 6c 6c 65 64 20 64 65 66  re-installed def
2410: 61 75 6c 74 20 68 61 6e 64 6c 65 72 73 20 28 61  ault handlers (a
2420: 6e 64 20 64 69 72 65 63 74 6c 79 20 72 65 6c 61  nd directly rela
2430: 74 65 64 20 73 74 75 66 66 29 0a 09 0a 28 64 65  ted stuff)...(de
2440: 66 69 6e 65 20 28 68 61 6e 64 6c 65 2d 71 75 65  fine (handle-que
2450: 72 79 2d 70 61 72 61 6d 65 74 65 72 73 20 70 61  ry-parameters pa
2460: 72 61 6d 65 74 65 72 73 20 71 75 65 72 79 29 0a  rameters query).
2470: 20 20 28 66 6f 72 2d 65 61 63 68 0a 20 20 20 28    (for-each.   (
2480: 6c 61 6d 62 64 61 20 28 6b 65 79 2b 76 61 6c 75  lambda (key+valu
2490: 65 29 0a 20 20 20 20 20 28 6c 65 74 2d 6f 70 74  e).     (let-opt
24a0: 69 6f 6e 61 6c 73 20 28 6d 61 70 20 75 72 69 2d  ionals (map uri-
24b0: 64 65 63 6f 64 65 20 28 73 74 72 69 6e 67 2d 73  decode (string-s
24c0: 70 6c 69 74 20 6b 65 79 2b 76 61 6c 75 65 20 22  plit key+value "
24d0: 3d 22 29 29 0a 09 09 20 20 20 20 28 28 6b 65 79  ="))...    ((key
24e0: 20 23 66 29 20 28 76 61 6c 75 65 20 22 22 29 29   #f) (value ""))
24f0: 0a 20 20 20 20 20 20 20 28 77 68 65 6e 20 6b 65  .       (when ke
2500: 79 0a 09 20 28 28 72 65 71 75 65 73 74 2d 70 61  y.. ((request-pa
2510: 72 61 6d 65 74 65 72 2d 68 61 6e 64 6c 65 72 29  rameter-handler)
2520: 0a 09 20 20 70 61 72 61 6d 65 74 65 72 73 20 6b  ..  parameters k
2530: 65 79 0a 09 20 20 28 6d 61 6b 65 2d 6d 65 73 73  ey..  (make-mess
2540: 61 67 65 20 76 61 6c 75 65 20 23 3a 74 79 70 65  age value #:type
2550: 20 22 74 65 78 74 2f 70 6c 61 69 6e 22 29 29 29   "text/plain")))
2560: 29 29 0a 20 20 20 28 73 74 72 69 6e 67 2d 73 70  )).   (string-sp
2570: 6c 69 74 20 71 75 65 72 79 20 22 26 3b 22 29 29  lit query "&;"))
2580: 0a 20 20 23 66 29 0a 0a 28 72 65 71 75 65 73 74  .  #f)..(request
2590: 2d 62 6f 64 79 2d 68 61 6e 64 6c 65 72 20 22 61  -body-handler "a
25a0: 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77  pplication/x-www
25b0: 2d 66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64  -form-urlencoded
25c0: 22 0a 20 20 28 6c 61 6d 62 64 61 20 28 70 61 72  ".  (lambda (par
25d0: 61 6d 65 74 65 72 73 20 74 79 70 65 20 73 69 7a  ameters type siz
25e0: 65 20 70 6f 72 74 29 0a 20 20 20 20 28 68 61 6e  e port).    (han
25f0: 64 6c 65 2d 71 75 65 72 79 2d 70 61 72 61 6d 65  dle-query-parame
2600: 74 65 72 73 20 70 61 72 61 6d 65 74 65 72 73 20  ters parameters 
2610: 28 72 65 61 64 2d 73 74 72 69 6e 67 20 73 69 7a  (read-string siz
2620: 65 20 70 6f 72 74 29 29 29 29 0a 0a 28 72 65 71  e port))))..(req
2630: 75 65 73 74 2d 62 6f 64 79 2d 68 61 6e 64 6c 65  uest-body-handle
2640: 72 20 22 6d 75 6c 74 69 70 61 72 74 2f 66 6f 72  r "multipart/for
2650: 6d 2d 64 61 74 61 22 0a 20 20 28 6c 65 74 72 65  m-data".  (letre
2660: 63 20 28 28 62 6f 75 6e 64 61 72 79 2d 72 78 0a  c ((boundary-rx.
2670: 09 20 20 20 20 28 69 72 72 65 67 65 78 20 27 28  .    (irregex '(
2680: 3a 20 62 6f 77 20 22 62 6f 75 6e 64 61 72 79 3d  : bow "boundary=
2690: 22 20 28 24 20 28 2b 20 28 7e 20 28 22 20 3b 5c  " ($ (+ (~ (" ;\
26a0: 6e 5c 72 5c 74 22 29 29 29 29 29 29 29 0a 09 20  n\r\t"))))))).. 
26b0: 20 20 28 6d 75 6c 74 69 70 61 72 74 2d 62 6f 75    (multipart-bou
26c0: 6e 64 61 72 79 0a 09 20 20 20 20 28 6c 61 6d 62  ndary..    (lamb
26d0: 64 61 20 28 73 29 0a 09 20 20 20 20 20 20 28 63  da (s)..      (c
26e0: 6f 6e 64 0a 09 20 20 20 20 20 20 20 28 28 69 72  ond..       ((ir
26f0: 72 65 67 65 78 2d 73 65 61 72 63 68 20 62 6f 75  regex-search bou
2700: 6e 64 61 72 79 2d 72 78 20 73 29 0a 09 09 3d 3e  ndary-rx s)...=>
2710: 20 28 63 75 74 20 69 72 72 65 67 65 78 2d 6d 61   (cut irregex-ma
2720: 74 63 68 2d 73 75 62 73 74 72 69 6e 67 20 3c 3e  tch-substring <>
2730: 20 31 29 29 0a 09 20 20 20 20 20 20 20 28 65 6c   1))..       (el
2740: 73 65 0a 09 09 23 66 29 29 29 29 0a 09 20 20 20  se...#f))))..   
2750: 28 68 65 61 64 65 72 2d 72 78 0a 09 20 20 20 20  (header-rx..    
2760: 28 69 72 72 65 67 65 78 20 27 28 3a 20 28 24 20  (irregex '(: ($ 
2770: 28 2b 20 28 7e 20 23 5c 3a 29 29 29 20 23 5c 3a  (+ (~ #\:))) #\:
2780: 20 28 2a 20 73 70 61 63 65 29 20 28 24 20 28 2a   (* space) ($ (*
2790: 3f 20 61 6e 79 29 29 0a 09 09 09 20 28 6f 72 20  ? any)).... (or 
27a0: 22 5c 72 5c 6e 22 20 65 6f 73 29 29 29 29 0a 09  "\r\n" eos))))..
27b0: 20 20 20 28 73 70 65 63 69 61 6c 2b 72 65 67 75     (special+regu
27c0: 6c 61 72 2d 68 65 61 64 65 72 73 0a 09 20 20 20  lar-headers..   
27d0: 20 28 6c 61 6d 62 64 61 20 28 73 20 73 74 61 72   (lambda (s star
27e0: 74 20 65 6e 64 20 73 70 65 63 69 61 6c 29 0a 09  t end special)..
27f0: 20 20 20 20 20 20 28 70 61 72 74 69 74 69 6f 6e        (partition
2800: 0a 09 20 20 20 20 20 20 20 28 6c 61 6d 62 64 61  ..       (lambda
2810: 20 28 6b 65 79 2b 76 61 6c 75 65 29 0a 09 09 20   (key+value)... 
2820: 28 6d 65 6d 62 65 72 20 28 63 61 72 20 6b 65 79  (member (car key
2830: 2b 76 61 6c 75 65 29 20 73 70 65 63 69 61 6c 20  +value) special 
2840: 73 74 72 69 6e 67 2d 63 69 3d 3f 29 29 0a 09 20  string-ci=?)).. 
2850: 20 20 20 20 20 20 28 69 72 72 65 67 65 78 2d 66        (irregex-f
2860: 6f 6c 64 0a 09 09 68 65 61 64 65 72 2d 72 78 0a  old...header-rx.
2870: 09 09 28 6c 61 6d 62 64 61 20 28 73 74 61 72 74  ..(lambda (start
2880: 20 6d 20 73 65 65 64 29 0a 09 09 20 20 28 63 6f   m seed)...  (co
2890: 6e 73 20 28 63 6f 6e 73 20 28 69 72 72 65 67 65  ns (cons (irrege
28a0: 78 2d 6d 61 74 63 68 2d 73 75 62 73 74 72 69 6e  x-match-substrin
28b0: 67 20 6d 20 31 29 0a 09 09 09 20 20 20 20 20 20  g m 1)....      
28c0: 28 69 72 72 65 67 65 78 2d 6d 61 74 63 68 2d 73  (irregex-match-s
28d0: 75 62 73 74 72 69 6e 67 20 6d 20 32 29 29 0a 09  ubstring m 2))..
28e0: 09 09 73 65 65 64 29 29 0a 09 09 27 28 29 20 73  ..seed))...'() s
28f0: 0a 09 09 28 6c 61 6d 62 64 61 20 28 73 74 61 72  ...(lambda (star
2900: 74 20 73 65 65 64 29 0a 09 09 20 20 28 72 65 76  t seed)...  (rev
2910: 65 72 73 65 21 20 73 65 65 64 29 29 0a 09 09 73  erse! seed))...s
2920: 74 61 72 74 20 65 6e 64 29 29 29 29 0a 09 20 20  tart end))))..  
2930: 20 28 6e 61 6d 65 2d 72 78 0a 09 20 20 20 20 28   (name-rx..    (
2940: 69 72 72 65 67 65 78 20 27 28 3a 20 62 6f 77 20  irregex '(: bow 
2950: 22 6e 61 6d 65 3d 22 20 23 5c 22 20 28 24 20 28  "name=" #\" ($ (
2960: 2a 3f 20 28 7e 20 23 5c 22 29 29 29 20 23 5c 22  *? (~ #\"))) #\"
2970: 29 29 29 0a 09 20 20 20 28 64 69 73 70 6f 73 69  )))..   (disposi
2980: 74 69 6f 6e 2d 6e 61 6d 65 0a 09 20 20 20 20 28  tion-name..    (
2990: 6c 61 6d 62 64 61 20 28 73 20 64 65 66 61 75 6c  lambda (s defaul
29a0: 74 29 0a 09 20 20 20 20 20 20 28 63 6f 6e 64 0a  t)..      (cond.
29b0: 09 20 20 20 20 20 20 20 28 28 69 72 72 65 67 65  .       ((irrege
29c0: 78 2d 73 65 61 72 63 68 20 6e 61 6d 65 2d 72 78  x-search name-rx
29d0: 20 73 29 0a 09 09 3d 3e 20 28 63 75 74 20 69 72   s)...=> (cut ir
29e0: 72 65 67 65 78 2d 6d 61 74 63 68 2d 73 75 62 73  regex-match-subs
29f0: 74 72 69 6e 67 20 3c 3e 20 31 29 29 0a 09 20 20  tring <> 1))..  
2a00: 20 20 20 20 20 28 65 6c 73 65 0a 09 20 20 20 20       (else..    
2a10: 20 20 20 20 64 65 66 61 75 6c 74 29 29 29 29 0a      default)))).
2a20: 09 20 20 20 28 68 61 6e 64 6c 65 2d 6d 65 73 73  .   (handle-mess
2a30: 61 67 65 73 0a 09 20 20 20 20 28 6c 61 6d 62 64  ages..    (lambd
2a40: 61 20 28 70 61 72 61 6d 65 74 65 72 73 20 6e 61  a (parameters na
2a50: 6d 65 20 64 61 74 61 20 62 6f 75 6e 64 61 72 79  me data boundary
2a60: 29 0a 09 20 20 20 20 20 20 28 6c 65 74 20 28 28  )..      (let ((
2a70: 62 6f 75 6e 64 61 72 79 2d 72 78 0a 09 09 20 20  boundary-rx...  
2a80: 20 20 20 28 69 72 72 65 67 65 78 20 60 28 3a 20     (irregex `(: 
2a90: 28 6f 72 20 62 6f 73 20 22 5c 72 5c 6e 22 29 20  (or bos "\r\n") 
2aa0: 22 2d 2d 22 0a 09 09 09 09 20 20 2c 62 6f 75 6e  "--".....  ,boun
2ab0: 64 61 72 79 0a 09 09 09 09 20 20 28 3f 20 22 2d  dary.....  (? "-
2ac0: 2d 22 29 20 22 5c 72 5c 6e 22 29 29 29 29 0a 09  -") "\r\n"))))..
2ad0: 09 28 69 72 72 65 67 65 78 2d 66 6f 6c 64 0a 09  .(irregex-fold..
2ae0: 09 20 62 6f 75 6e 64 61 72 79 2d 72 78 0a 09 09  . boundary-rx...
2af0: 20 28 6c 61 6d 62 64 61 20 28 73 74 61 72 74 20   (lambda (start 
2b00: 6d 20 73 6b 69 70 3f 29 0a 09 09 20 20 20 28 61  m skip?)...   (a
2b10: 6e 64 2d 6c 65 74 2a 20 28 28 28 6e 6f 74 20 73  nd-let* (((not s
2b20: 6b 69 70 3f 29 29 0a 09 09 09 20 20 20 20 20 20  kip?))....      
2b30: 28 65 6e 64 0a 09 09 09 20 20 20 20 20 20 20 28  (end....       (
2b40: 69 72 72 65 67 65 78 2d 6d 61 74 63 68 2d 73 74  irregex-match-st
2b50: 61 72 74 2d 69 6e 64 65 78 20 6d 29 29 0a 09 09  art-index m))...
2b60: 09 20 20 20 20 20 20 28 68 65 61 64 65 72 2d 65  .      (header-e
2b70: 6e 64 0a 09 09 09 20 20 20 20 20 20 20 28 73 74  nd....       (st
2b80: 72 69 6e 67 2d 63 6f 6e 74 61 69 6e 73 20 64 61  ring-contains da
2b90: 74 61 20 22 5c 72 5c 6e 5c 72 5c 6e 22 20 73 74  ta "\r\n\r\n" st
2ba0: 61 72 74 20 65 6e 64 29 29 0a 09 09 09 20 20 20  art end))....   
2bb0: 20 20 20 28 62 6f 64 79 0a 09 09 09 20 20 20 20     (body....    
2bc0: 20 20 20 28 73 75 62 73 74 72 69 6e 67 2f 73 68     (substring/sh
2bd0: 61 72 65 64 20 64 61 74 61 20 28 2b 20 68 65 61  ared data (+ hea
2be0: 64 65 72 2d 65 6e 64 20 34 29 20 65 6e 64 29 29  der-end 4) end))
2bf0: 29 0a 09 09 20 20 20 20 20 28 6c 65 74 2d 76 61  )...     (let-va
2c00: 6c 75 65 73 20 28 28 28 73 70 65 63 69 61 6c 73  lues (((specials
2c10: 20 68 65 61 64 65 72 73 29 0a 09 09 09 09 20 20   headers).....  
2c20: 20 28 73 70 65 63 69 61 6c 2b 72 65 67 75 6c 61   (special+regula
2c30: 72 2d 68 65 61 64 65 72 73 0a 09 09 09 09 20 20  r-headers.....  
2c40: 20 20 64 61 74 61 20 73 74 61 72 74 20 68 65 61    data start hea
2c50: 64 65 72 2d 65 6e 64 0a 09 09 09 09 20 20 20 20  der-end.....    
2c60: 27 28 22 43 6f 6e 74 65 6e 74 2d 74 79 70 65 22  '("Content-type"
2c70: 20 22 43 6f 6e 74 65 6e 74 2d 6c 65 6e 67 74 68   "Content-length
2c80: 22 29 29 29 29 0a 09 09 20 20 20 20 20 20 20 28  "))))...       (
2c90: 6c 65 74 20 28 28 74 79 70 65 0a 09 09 09 20 20  let ((type....  
2ca0: 20 20 20 20 28 61 6c 69 73 74 2d 72 65 66 0a 09      (alist-ref..
2cb0: 09 09 20 20 20 20 20 20 20 22 43 6f 6e 74 65 6e  ..       "Conten
2cc0: 74 2d 74 79 70 65 22 20 73 70 65 63 69 61 6c 73  t-type" specials
2cd0: 20 73 74 72 69 6e 67 2d 63 69 3d 3f 0a 09 09 09   string-ci=?....
2ce0: 20 20 20 20 20 20 20 22 74 65 78 74 2f 70 6c 61         "text/pla
2cf0: 69 6e 22 29 29 0a 09 09 09 20 20 20 20 20 28 6e  in"))....     (n
2d00: 61 6d 65 0a 09 09 09 20 20 20 20 20 20 28 64 69  ame....      (di
2d10: 73 70 6f 73 69 74 69 6f 6e 2d 6e 61 6d 65 0a 09  sposition-name..
2d20: 09 09 20 20 20 20 20 20 20 28 61 6c 69 73 74 2d  ..       (alist-
2d30: 72 65 66 0a 09 09 09 09 22 43 6f 6e 74 65 6e 74  ref....."Content
2d40: 2d 64 69 73 70 6f 73 69 74 69 6f 6e 22 20 68 65  -disposition" he
2d50: 61 64 65 72 73 20 73 74 72 69 6e 67 2d 63 69 3d  aders string-ci=
2d60: 3f 29 0a 09 09 09 20 20 20 20 20 20 20 6e 61 6d  ?)....       nam
2d70: 65 29 29 29 0a 09 09 09 20 28 77 68 65 6e 20 6e  e))).... (when n
2d80: 61 6d 65 0a 09 09 09 20 20 20 28 63 6f 6e 64 0a  ame....   (cond.
2d90: 09 09 09 20 20 20 20 28 28 6d 75 6c 74 69 70 61  ...    ((multipa
2da0: 72 74 2d 62 6f 75 6e 64 61 72 79 20 74 79 70 65  rt-boundary type
2db0: 29 0a 09 09 09 20 20 20 20 20 3d 3e 20 28 63 75  )....     => (cu
2dc0: 74 20 68 61 6e 64 6c 65 2d 6d 65 73 73 61 67 65  t handle-message
2dd0: 73 20 70 61 72 61 6d 65 74 65 72 73 20 6e 61 6d  s parameters nam
2de0: 65 20 62 6f 64 79 20 3c 3e 29 29 0a 09 09 09 20  e body <>)).... 
2df0: 20 20 20 28 65 6c 73 65 0a 09 09 09 20 20 20 20     (else....    
2e00: 20 28 28 72 65 71 75 65 73 74 2d 70 61 72 61 6d   ((request-param
2e10: 65 74 65 72 2d 68 61 6e 64 6c 65 72 29 0a 09 09  eter-handler)...
2e20: 09 20 20 20 20 20 20 70 61 72 61 6d 65 74 65 72  .      parameter
2e30: 73 20 6e 61 6d 65 0a 09 09 09 20 20 20 20 20 20  s name....      
2e40: 28 6d 61 6b 65 2d 6d 65 73 73 61 67 65 0a 09 09  (make-message...
2e50: 09 20 20 20 20 20 20 20 62 6f 64 79 20 23 3a 74  .       body #:t
2e60: 79 70 65 20 74 79 70 65 20 23 3a 68 65 61 64 65  ype type #:heade
2e70: 72 73 20 68 65 61 64 65 72 73 29 29 29 29 29 29  rs headers))))))
2e80: 29 29 0a 09 09 20 20 20 23 66 29 0a 09 09 20 23  ))...   #f)... #
2e90: 74 20 64 61 74 61 29 29 0a 09 20 20 20 20 20 20  t data))..      
2ea0: 23 66 29 29 29 0a 20 20 20 20 28 6c 61 6d 62 64  #f))).    (lambd
2eb0: 61 20 28 70 61 72 61 6d 65 74 65 72 73 20 74 79  a (parameters ty
2ec0: 70 65 20 73 69 7a 65 20 70 6f 72 74 29 0a 20 20  pe size port).  
2ed0: 20 20 20 20 28 63 6f 6e 64 0a 20 20 20 20 20 20      (cond.      
2ee0: 20 28 28 6d 75 6c 74 69 70 61 72 74 2d 62 6f 75   ((multipart-bou
2ef0: 6e 64 61 72 79 20 74 79 70 65 29 0a 09 3d 3e 20  ndary type)..=> 
2f00: 28 63 75 74 20 68 61 6e 64 6c 65 2d 6d 65 73 73  (cut handle-mess
2f10: 61 67 65 73 0a 09 09 70 61 72 61 6d 65 74 65 72  ages...parameter
2f20: 73 20 23 66 20 28 72 65 61 64 2d 73 74 72 69 6e  s #f (read-strin
2f30: 67 20 73 69 7a 65 20 70 6f 72 74 29 20 3c 3e 29  g size port) <>)
2f40: 29 0a 20 20 20 20 20 20 20 28 65 6c 73 65 0a 09  ).       (else..
2f50: 28 6d 61 6b 65 2d 65 72 72 6f 72 2d 72 65 73 70  (make-error-resp
2f60: 6f 6e 73 65 0a 09 20 35 30 31 20 22 54 68 65 20  onse.. 501 "The 
2f70: 73 65 72 76 65 72 20 64 6f 65 73 6e 27 74 20 6b  server doesn't k
2f80: 6e 6f 77 20 68 6f 77 20 74 6f 20 70 61 72 73 65  now how to parse
2f90: 20 72 65 71 75 65 73 74 20 70 61 72 61 6d 65 74   request paramet
2fa0: 65 72 73 20 66 72 6f 6d 20 74 68 65 20 63 6f 6e  ers from the con
2fb0: 74 65 6e 74 20 74 79 70 65 20 73 65 6e 74 2e 22  tent type sent."
2fc0: 29 29 29 29 29 29 0a 0a 28 72 65 71 75 65 73 74  ))))))..(request
2fd0: 2d 6d 65 74 68 6f 64 2d 68 61 6e 64 6c 65 72 20  -method-handler 
2fe0: 22 47 45 54 22 0a 20 20 28 6c 61 6d 62 64 61 20  "GET".  (lambda 
2ff0: 28 70 61 72 61 6d 65 74 65 72 73 20 6d 65 74 68  (parameters meth
3000: 6f 64 20 67 65 74 65 6e 76 20 70 6f 72 74 29 0a  od getenv port).
3010: 20 20 20 20 28 68 61 6e 64 6c 65 2d 71 75 65 72      (handle-quer
3020: 79 2d 70 61 72 61 6d 65 74 65 72 73 20 70 61 72  y-parameters par
3030: 61 6d 65 74 65 72 73 20 28 6f 72 20 28 67 65 74  ameters (or (get
3040: 65 6e 76 20 22 51 55 45 52 59 5f 53 54 52 49 4e  env "QUERY_STRIN
3050: 47 22 29 20 22 22 29 29 29 29 0a 20 20 0a 28 72  G") "")))).  .(r
3060: 65 71 75 65 73 74 2d 6d 65 74 68 6f 64 2d 68 61  equest-method-ha
3070: 6e 64 6c 65 72 20 22 50 4f 53 54 22 0a 20 20 28  ndler "POST".  (
3080: 6c 61 6d 62 64 61 20 28 70 61 72 61 6d 65 74 65  lambda (paramete
3090: 72 73 20 6d 65 74 68 6f 64 20 67 65 74 65 6e 76  rs method getenv
30a0: 20 70 6f 72 74 29 0a 20 20 20 20 28 6f 72 0a 20   port).    (or. 
30b0: 20 20 20 20 28 68 61 6e 64 6c 65 2d 71 75 65 72      (handle-quer
30c0: 79 2d 70 61 72 61 6d 65 74 65 72 73 20 70 61 72  y-parameters par
30d0: 61 6d 65 74 65 72 73 20 28 6f 72 20 28 67 65 74  ameters (or (get
30e0: 65 6e 76 20 22 51 55 45 52 59 5f 53 54 52 49 4e  env "QUERY_STRIN
30f0: 47 22 29 20 22 22 29 29 0a 20 20 20 20 20 28 6c  G") "")).     (l
3100: 65 74 20 28 28 74 79 70 65 20 28 6f 72 0a 09 09  et ((type (or...
3110: 20 20 28 67 65 74 65 6e 76 20 22 43 4f 4e 54 45    (getenv "CONTE
3120: 4e 54 5f 54 59 50 45 22 29 0a 09 09 20 20 22 61  NT_TYPE")...  "a
3130: 70 70 6c 69 63 61 74 69 6f 6e 2f 6f 63 74 65 74  pplication/octet
3140: 2d 73 74 72 65 61 6d 22 29 29 0a 09 20 20 20 28  -stream"))..   (
3150: 73 69 7a 65 20 28 63 6f 6e 64 0a 09 09 20 20 28  size (cond...  (
3160: 28 67 65 74 65 6e 76 20 22 43 4f 4e 54 45 4e 54  (getenv "CONTENT
3170: 5f 4c 45 4e 47 54 48 22 29 0a 09 09 20 20 20 3d  _LENGTH")...   =
3180: 3e 20 73 74 72 69 6e 67 2d 3e 6e 75 6d 62 65 72  > string->number
3190: 29 0a 09 09 20 20 28 65 6c 73 65 0a 09 09 20 20  )...  (else...  
31a0: 20 23 66 29 29 29 29 0a 20 20 20 20 20 20 20 28   #f)))).       (
31b0: 63 6f 6e 64 0a 09 28 28 6e 6f 74 20 73 69 7a 65  cond..((not size
31c0: 29 0a 09 20 28 6d 61 6b 65 2d 65 72 72 6f 72 2d  ).. (make-error-
31d0: 72 65 73 70 6f 6e 73 65 0a 09 20 20 34 31 31 20  response..  411 
31e0: 22 54 68 65 20 73 65 72 76 65 72 20 72 65 66 75  "The server refu
31f0: 73 65 73 20 70 72 6f 63 65 73 73 69 6e 67 20 61  ses processing a
3200: 73 20 6e 6f 20 63 6f 6e 74 65 6e 74 20 6c 65 6e  s no content len
3210: 67 74 68 20 77 61 73 20 73 65 6e 74 20 77 69 74  gth was sent wit
3220: 68 20 74 68 65 20 72 65 71 75 65 73 74 2e 22 29  h the request.")
3230: 29 0a 09 28 28 63 6f 6e 64 20 28 28 6d 61 78 2d  )..((cond ((max-
3240: 72 65 71 75 65 73 74 2d 73 69 7a 65 29 20 3d 3e  request-size) =>
3250: 20 28 63 75 74 20 3e 20 73 69 7a 65 20 3c 3e 29   (cut > size <>)
3260: 29 20 28 65 6c 73 65 20 23 66 29 29 0a 09 20 28  ) (else #f)).. (
3270: 6d 61 6b 65 2d 65 72 72 6f 72 2d 72 65 73 70 6f  make-error-respo
3280: 6e 73 65 0a 09 20 20 34 31 33 20 22 54 68 65 20  nse..  413 "The 
3290: 73 65 72 76 65 72 20 72 65 66 75 73 65 73 20 70  server refuses p
32a0: 72 6f 63 65 73 73 69 6e 67 20 61 73 20 74 68 65  rocessing as the
32b0: 20 72 65 71 75 65 73 74 27 73 20 63 6f 6e 74 65   request's conte
32c0: 6e 74 20 6c 65 6e 67 74 68 20 69 73 20 74 6f 6f  nt length is too
32d0: 20 6c 61 72 67 65 2e 22 29 29 0a 09 28 28 72 65   large."))..((re
32e0: 71 75 65 73 74 2d 62 6f 64 79 2d 68 61 6e 64 6c  quest-body-handl
32f0: 65 72 20 28 73 75 62 73 74 72 69 6e 67 2f 73 68  er (substring/sh
3300: 61 72 65 64 0a 09 09 09 09 74 79 70 65 20 30 20  ared.....type 0 
3310: 28 6f 72 20 28 73 74 72 69 6e 67 2d 69 6e 64 65  (or (string-inde
3320: 78 20 74 79 70 65 20 23 5c 3b 29 0a 09 09 09 09  x type #\;).....
3330: 09 20 20 20 28 73 74 72 69 6e 67 2d 6c 65 6e 67  .   (string-leng
3340: 74 68 20 74 79 70 65 29 29 29 29 0a 09 20 3d 3e  th type)))).. =>
3350: 20 28 63 75 74 20 3c 3e 20 70 61 72 61 6d 65 74   (cut <> paramet
3360: 65 72 73 20 74 79 70 65 20 73 69 7a 65 20 70 6f  ers type size po
3370: 72 74 29 29 0a 09 28 65 6c 73 65 0a 09 20 28 6d  rt))..(else.. (m
3380: 61 6b 65 2d 65 72 72 6f 72 2d 72 65 73 70 6f 6e  ake-error-respon
3390: 73 65 0a 09 20 20 35 30 31 20 22 54 68 65 20 73  se..  501 "The s
33a0: 65 72 76 65 72 20 64 6f 65 73 6e 27 74 20 6b 6e  erver doesn't kn
33b0: 6f 77 20 68 6f 77 20 74 6f 20 70 61 72 73 65 20  ow how to parse 
33c0: 72 65 71 75 65 73 74 20 70 61 72 61 6d 65 74 65  request paramete
33d0: 72 73 20 66 72 6f 6d 20 74 68 65 20 63 6f 6e 74  rs from the cont
33e0: 65 6e 74 20 74 79 70 65 20 73 65 6e 74 2e 22 29  ent type sent.")
33f0: 29 29 29 29 29 29 0a 0a 3b 3b 3b 20 43 65 6e 74  ))))))..;;; Cent
3400: 72 61 6c 20 73 65 72 76 65 72 20 72 6f 75 74 69  ral server routi
3410: 6e 65 0a 0a 28 64 65 66 69 6e 65 20 28 68 61 6e  ne..(define (han
3420: 64 6c 65 2d 72 65 71 75 65 73 74 20 67 65 74 65  dle-request gete
3430: 6e 76 20 69 6e 70 75 74 2d 70 6f 72 74 20 77 72  nv input-port wr
3440: 69 74 65 2d 72 65 73 70 6f 6e 73 65 29 0a 20 20  ite-response).  
3450: 28 77 72 69 74 65 2d 72 65 73 70 6f 6e 73 65 0a  (write-response.
3460: 20 20 20 28 68 61 6e 64 6c 65 2d 65 78 63 65 70     (handle-excep
3470: 74 69 6f 6e 73 0a 20 20 20 20 65 78 6e 20 28 62  tions.    exn (b
3480: 65 67 69 6e 0a 09 20 20 28 77 68 65 6e 20 28 75  egin..  (when (u
3490: 6e 63 61 75 67 68 74 2d 65 78 63 65 70 74 69 6f  ncaught-exceptio
34a0: 6e 3f 20 65 78 6e 29 0a 09 20 20 20 20 28 73 65  n? exn)..    (se
34b0: 74 21 20 65 78 6e 20 28 75 6e 63 61 75 67 68 74  t! exn (uncaught
34c0: 2d 65 78 63 65 70 74 69 6f 6e 2d 72 65 61 73 6f  -exception-reaso
34d0: 6e 20 65 78 6e 29 29 29 0a 09 20 20 28 70 72 69  n exn)))..  (pri
34e0: 6e 74 2d 65 72 72 6f 72 2d 6d 65 73 73 61 67 65  nt-error-message
34f0: 0a 09 20 20 20 65 78 6e 20 28 63 75 72 72 65 6e  ..   exn (curren
3500: 74 2d 65 72 72 6f 72 2d 70 6f 72 74 29 0a 09 20  t-error-port).. 
3510: 20 20 28 73 70 72 69 6e 74 66 20 22 5b 7e 61 5d    (sprintf "[~a]
3520: 20 52 65 71 75 65 73 74 20 48 61 6e 64 6c 69 6e   Request Handlin
3530: 67 20 45 72 72 6f 72 22 20 28 63 75 72 72 65 6e  g Error" (curren
3540: 74 2d 73 65 63 6f 6e 64 73 29 29 29 0a 09 20 20  t-seconds)))..  
3550: 28 70 72 69 6e 74 2d 63 61 6c 6c 2d 63 68 61 69  (print-call-chai
3560: 6e 29 0a 09 20 20 28 6d 61 6b 65 2d 65 72 72 6f  n)..  (make-erro
3570: 72 2d 72 65 73 70 6f 6e 73 65 0a 09 20 20 20 35  r-response..   5
3580: 30 30 20 22 54 68 65 20 73 65 72 76 65 72 20 65  00 "The server e
3590: 6e 63 6f 75 6e 74 65 72 65 64 20 61 6e 20 69 6e  ncountered an in
35a0: 74 65 72 6e 61 6c 20 65 72 72 6f 72 20 68 61 6e  ternal error han
35b0: 64 6c 69 6e 67 20 74 68 65 20 72 65 71 75 65 73  dling the reques
35c0: 74 2e 22 29 29 0a 20 20 20 20 28 6c 65 74 20 28  t.")).    (let (
35d0: 28 70 61 72 61 6d 65 74 65 72 73 20 28 6d 61 6b  (parameters (mak
35e0: 65 2d 68 61 73 68 2d 74 61 62 6c 65 29 29 0a 09  e-hash-table))..
35f0: 20 20 28 6d 65 74 68 6f 64 20 28 6f 72 20 28 67    (method (or (g
3600: 65 74 65 6e 76 20 22 52 45 51 55 45 53 54 5f 4d  etenv "REQUEST_M
3610: 45 54 48 4f 44 22 29 20 22 47 45 54 22 29 29 0a  ETHOD") "GET")).
3620: 09 20 20 28 70 61 74 68 20 28 73 74 72 69 6e 67  .  (path (string
3630: 2d 73 70 6c 69 74 20 28 75 72 69 2d 64 65 63 6f  -split (uri-deco
3640: 64 65 20 28 6f 72 20 28 67 65 74 65 6e 76 20 22  de (or (getenv "
3650: 50 41 54 48 5f 49 4e 46 4f 22 29 20 22 22 29 29  PATH_INFO") ""))
3660: 20 22 2f 22 29 29 29 0a 20 20 20 20 20 20 28 6f   "/"))).      (o
3670: 72 0a 20 20 20 20 20 20 20 28 63 6f 6e 64 0a 09  r.       (cond..
3680: 28 28 72 65 71 75 65 73 74 2d 6d 65 74 68 6f 64  ((request-method
3690: 2d 68 61 6e 64 6c 65 72 20 6d 65 74 68 6f 64 29  -handler method)
36a0: 0a 09 20 3d 3e 20 28 63 75 74 20 3c 3e 20 70 61  .. => (cut <> pa
36b0: 72 61 6d 65 74 65 72 73 20 6d 65 74 68 6f 64 20  rameters method 
36c0: 67 65 74 65 6e 76 20 69 6e 70 75 74 2d 70 6f 72  getenv input-por
36d0: 74 29 29 0a 09 28 65 6c 73 65 0a 09 20 28 6d 61  t))..(else.. (ma
36e0: 6b 65 2d 65 72 72 6f 72 2d 72 65 73 70 6f 6e 73  ke-error-respons
36f0: 65 0a 09 20 20 34 30 35 20 22 54 68 65 20 61 63  e..  405 "The ac
3700: 63 65 73 73 20 6d 65 74 68 6f 64 20 75 73 65 64  cess method used
3710: 20 74 6f 20 72 65 71 75 65 73 74 20 74 68 65 20   to request the 
3720: 64 6f 63 75 6d 65 6e 74 20 69 73 20 6e 6f 74 20  document is not 
3730: 73 75 70 70 6f 72 74 65 64 2e 22 0a 09 20 20 23  supported."..  #
3740: 3a 68 65 61 64 65 72 73 0a 09 20 20 28 6c 69 73  :headers..  (lis
3750: 74 0a 09 20 20 20 28 63 6f 6e 73 20 22 41 6c 6c  t..   (cons "All
3760: 6f 77 22 20 28 73 74 72 69 6e 67 2d 6a 6f 69 6e  ow" (string-join
3770: 20 28 68 61 6e 64 6c 65 64 2d 72 65 71 75 65 73   (handled-reques
3780: 74 2d 6d 65 74 68 6f 64 73 29 20 22 2c 20 22 29  t-methods) ", ")
3790: 29 29 29 29 29 0a 20 20 20 20 20 20 20 28 63 6f  ))))).       (co
37a0: 6e 64 0a 09 28 28 72 65 73 6f 75 72 63 65 2d 68  nd..((resource-h
37b0: 61 6e 64 6c 65 72 20 70 61 74 68 29 0a 09 20 3d  andler path).. =
37c0: 3e 20 28 6c 61 6d 62 64 61 20 28 70 72 6f 63 29  > (lambda (proc)
37d0: 0a 09 20 20 20 20 20 20 28 77 69 74 68 2d 6c 69  ..      (with-li
37e0: 6d 69 74 65 64 2d 63 6f 6e 74 69 6e 75 61 74 69  mited-continuati
37f0: 6f 6e 0a 09 20 20 20 20 20 20 20 28 6c 61 6d 62  on..       (lamb
3800: 64 61 20 28 29 0a 09 09 20 28 63 75 72 72 65 6e  da ()... (curren
3810: 74 2d 72 65 73 6f 75 72 63 65 2d 63 6f 6e 74 65  t-resource-conte
3820: 78 74 0a 09 09 20 20 28 25 6d 61 6b 65 2d 72 65  xt...  (%make-re
3830: 73 6f 75 72 63 65 2d 63 6f 6e 74 65 78 74 20 67  source-context g
3840: 65 74 65 6e 76 20 6d 65 74 68 6f 64 20 70 61 74  etenv method pat
3850: 68 29 29 0a 09 09 20 28 70 72 6f 63 20 70 61 72  h))... (proc par
3860: 61 6d 65 74 65 72 73 29 29 29 29 29 0a 09 28 65  ameters)))))..(e
3870: 6c 73 65 0a 09 20 28 6d 61 6b 65 2d 65 72 72 6f  lse.. (make-erro
3880: 72 2d 72 65 73 70 6f 6e 73 65 0a 09 20 20 34 30  r-response..  40
3890: 34 20 22 54 68 65 20 72 65 71 75 65 73 74 65 64  4 "The requested
38a0: 20 72 65 73 6f 75 72 63 65 20 77 61 73 20 6e 6f   resource was no
38b0: 74 20 66 6f 75 6e 64 20 62 79 20 74 68 65 20 73  t found by the s
38c0: 65 72 76 65 72 2e 22 29 29 29 0a 20 20 20 20 20  erver."))).     
38d0: 20 20 28 6d 61 6b 65 2d 72 65 73 70 6f 6e 73 65    (make-response
38e0: 20 32 30 34 20 27 28 29 29 29 29 29 29 29 0a      204 '())))))).