Next: , Previous: , Up: Top   [Contents][Index]


9 (www server-utils filesystem)

The (www server-utils filesystem) module provides procedures for cleaning filenames, checking filesystem access, and mapping from a URL path to a filename.

Procedure: cleanup-filename name

Return a new filename made from cleaning up filename name. Cleaning up is a transform that collapses each of these, in order:

into a single slash (‘/’), everywhere in name, plus some fixups. The transform normally preserves the trailing slash (if any) in name, and does not change any leading ‘..’ components if name is relative, i.e., does not begin with slash. Due to proper ‘/foo/../’ cancellation for relative name, however, the result may be the empty string. (Here, proper means that foo is not ‘..’, but a normal filename component.)

Following is a fairly comprehensive list of the cleanup-filename edge cases, paired by name and result. The numbers represent string lengths.

  0                     ;; empty string
  0                     ;; result is empty string

  1  /
  1  /

  2  ok
  2  ok

  3  ok/
  3  ok/

  3  /ok
  3  /ok

  4  /ok/
  4  /ok/

  1  .                  ;; relative name
  0                     ;; result is empty string

  2  ./                 ;; likewise
  0                     ;; note, end-slash not preserved

  2  /.
  1  /

  3  /./
  1  /

  2  ..                 ;; relative, with leading double-dot
  2  ..                 ;; unchanged

  3  ../                ;; likewise
  3  ../

  3  /..                ;; absolute
  1  /                  ;; can’t go higher than root

  4  /../
  1  /

  4  ./..               ;; next 8 are like the previous 4;
  2  ..                 ;;  they show that . makes no difference

  5  ./../
  3  ../

  5  /./..
  1  /

  6  /./../
  1  /

  4  ../.
  2  ..

  5  .././
  3  ../

  5  /../.
  1  /

  6  /.././
  1  /

  5  ../..              ;; relative
  5  ../..              ;; leading .. sequences unchanged

  6  ../../
  6  ../../

  6  /../..             ;; absolute
  1  /                  ;; can’t go higher than root

  7  /../../
  1  /

  4  z/..               ;; relative
  0                     ;; only dir cancelledempty string

  5  z/../              ;; likewise
  0

  5  /z/..              ;; absolute
  1  /

  6  /z/../
  1  /

  6  z/../o             ;; next 4 like previous 4, with trailing component
  1  o

  7  z/../o/
  2  o/

  7  /z/../o
  2  /o

  8  /z/../o/
  3  /o/

  8  z/./../o           ;; next 4 like previous 4;
  1  o                  ;;  they show that . makes no difference

  9  z/./../o/
  2  o/

  9  /z/./../o
  2  /o

 10  /z/./../o/
  3  /o/

  9  z/../../o          ;; relative, more double-dot than parents
  4  ../o               ;; leftover double-dot preserved

 10  z/../../o/
  5  ../o/

 10  /z/../../o         ;; absolute, more double-dot than parents
  2  /o                 ;; all cancelled

 11  /z/../../o/
  3  /o/

 43  ../../abc/././bye0/./../def/bye1/bye2/../..        ;; bye bye-bye
 14  ../../abc/def/

 44  ../../abc/././bye0/./../def/bye1/bye2/../../
 14  ../../abc/def/

 44  /../../abc/././bye0/./../def/bye1/bye2/../..
  9  /abc/def/

 45  /../../abc/././bye0/./../def/bye1/bye2/../../
  9  /abc/def/
Procedure: access-forbidden?-proc docroot forbid-rx

Create and return a filesystem-access procedure based on docroot and forbid-rx. The returned procedure p takes a filename and returns #t if access to that file should be denied for any of the following reasons:

If forbid-rx is #f, the regular expression check is skipped. p returns #f if access should be granted.

Procedure: upath->filename-proc docroot [dir-indexes]

Create and return a url-path-to-filename mapping procedure based on docroot. The returned procedure p takes a (string) upath and returns a valid local filename path for the requested resource, or #f if that file cannot be found. Optional arg dir-indexes specifies an ordered list of filenames to try if the resolved filename path turns out to be a directory.

If no such files exist, return the directory name. As a special case, when p encounters a value of #f during iteration over dir-indexes, it returns #f immediately.

For example, presuming files /a/b/c.txt and /a/b/index.html both exist and are readable:

(define resolve (upath->filename-proc
                   "/a/b/"
                   '("index.shtml" "index.html")))

(resolve "/random") ⇒ #f
(resolve "/c.txt") ⇒ "/a/b/c.txt"
(resolve "/") ⇒ "/a/b/index.html"

Directory names are always returned with a trailing slash.

Procedure: filename->content-type filename [default]

Return a valid Content-Type string which matches filename best. Matching is done by comparing the extension (part of filename after the last "." if available) against a table. If none match, return "application/octet-stream". Optional arg default specifies another value to use instead of "application/octet-stream".

If there are multiple MIME types associated with the extension, return the first one.

See mime-types, proc put-mime-types!, for more info.


Next: , Previous: , Up: Top   [Contents][Index]