comparison src/settings.sml @ 2211:ef766ef6e242

Merge.
author Ziv Scully <ziv@mit.edu>
date Sat, 13 Sep 2014 19:16:07 -0400
parents ced78ef1c82f
children 6b7749da1ddc 365727ff68f4
comparison
equal deleted inserted replaced
2210:69c0f36255cb 2211:ef766ef6e242
287 ("str1", "id"), 287 ("str1", "id"),
288 ("strsub", "sub"), 288 ("strsub", "sub"),
289 ("strsuffix", "suf"), 289 ("strsuffix", "suf"),
290 ("strlen", "slen"), 290 ("strlen", "slen"),
291 ("strindex", "sidx"), 291 ("strindex", "sidx"),
292 ("strsindex", "ssidx"),
292 ("strchr", "schr"), 293 ("strchr", "schr"),
293 ("substring", "ssub"), 294 ("substring", "ssub"),
294 ("strcspn", "sspn"), 295 ("strcspn", "sspn"),
295 ("strlenGe", "strlenGe"), 296 ("strlenGe", "strlenGe"),
296 ("mouseEvent", "uw_mouseEvent"), 297 ("mouseEvent", "uw_mouseEvent"),
463 f s andalso chk (!rules) 464 f s andalso chk (!rules)
464 end 465 end
465 466
466 val checkUrl = check (fn _ => true) url 467 val checkUrl = check (fn _ => true) url
467 468
468 val validMime = CharVector.all (fn ch => Char.isAlphaNum ch orelse ch = #"/" orelse ch = #"-" orelse ch = #".") 469 val validMime = CharVector.all (fn ch => Char.isAlphaNum ch orelse ch = #"/" orelse ch = #"-" orelse ch = #"." orelse ch = #"+")
469 val validEnv = CharVector.all (fn ch => Char.isAlphaNum ch orelse ch = #"_" orelse ch = #".") 470 val validEnv = CharVector.all (fn ch => Char.isAlphaNum ch orelse ch = #"_" orelse ch = #".")
470 471
471 val checkMime = check validMime mime 472 val checkMime = check validMime mime
472 val checkRequestHeader = check validMime request 473 val checkRequestHeader = check validMime request
473 val checkResponseHeader = check validMime response 474 val checkResponseHeader = check validMime response
741 742
742 val less = ref false 743 val less = ref false
743 fun setLessSafeFfi b = less := b 744 fun setLessSafeFfi b = less := b
744 fun getLessSafeFfi () = !less 745 fun getLessSafeFfi () = !less
745 746
747 structure SM = BinaryMapFn(struct
748 type ord_key = string
749 val compare = String.compare
750 end)
751
752 val noMimeFile = ref false
753
754 fun noMime () =
755 (TextIO.output (TextIO.stdErr, "WARNING: Error opening /etc/mime.types. Static files will be served with no suggested MIME types.\n");
756 noMimeFile := true;
757 SM.empty)
758
759 fun readMimeTypes () =
760 let
761 val inf = TextIO.openIn "/etc/mime.types"
762
763 fun loop m =
764 case TextIO.inputLine inf of
765 NONE => m
766 | SOME line =>
767 if size line > 0 andalso String.sub (line, 0) = #"#" then
768 loop m
769 else
770 case String.tokens Char.isSpace line of
771 typ :: exts =>
772 loop (foldl (fn (ext, m) => SM.insert (m, ext, typ)) m exts)
773 | _ => loop m
774 in
775 loop SM.empty
776 before TextIO.closeIn inf
777 end handle IO.Io _ => noMime ()
778 | OS.SysErr _ => noMime ()
779
780 val mimeTypes = ref (NONE : string SM.map option)
781
782 fun getMimeTypes () =
783 case !mimeTypes of
784 SOME m => m
785 | NONE =>
786 let
787 val m = readMimeTypes ()
788 in
789 mimeTypes := SOME m;
790 m
791 end
792
793 fun mimeTypeOf filename =
794 case OS.Path.ext filename of
795 NONE => (if !noMimeFile then
796 ()
797 else
798 TextIO.output (TextIO.stdErr, "WARNING: No extension found in filename '" ^ filename ^ "'. Header 'Content-Type' will be omitted in HTTP responses.\n");
799 NONE)
800 | SOME ext =>
801 let
802 val to = SM.find (getMimeTypes (), ext)
803 in
804 case to of
805 NONE => if !noMimeFile then
806 ()
807 else
808 TextIO.output (TextIO.stdErr, "WARNING: No MIME type known for extension '" ^ ext ^ "'. Header 'Content-Type' will be omitted in HTTP responses.\n")
809 | _ => ();
810 to
811 end
812
813 val files = ref (SM.empty : (string * {Uri : string, ContentType : string option, LastModified : Time.time, Bytes : Word8Vector.vector}) SM.map)
814
815 val filePath = ref "."
816
817 fun setFilePath path = filePath := path
818
819 fun addFile {Uri, LoadFromFilename} =
820 let
821 val path = OS.Path.joinDirFile {dir = !filePath, file = LoadFromFilename}
822 in
823 case SM.find (!files, Uri) of
824 SOME (path', _) =>
825 if path' = path then
826 ()
827 else
828 ErrorMsg.error ("Two different files requested for URI " ^ Uri)
829 | NONE =>
830 let
831 val inf = BinIO.openIn path
832 in
833 files := SM.insert (!files,
834 Uri,
835 (path,
836 {Uri = Uri,
837 ContentType = mimeTypeOf path,
838 LastModified = OS.FileSys.modTime path,
839 Bytes = BinIO.inputAll inf}));
840 BinIO.closeIn inf
841 end
842 end handle IO.Io _ =>
843 ErrorMsg.error ("Error loading file " ^ LoadFromFilename)
844 | OS.SysErr (s, _) =>
845 ErrorMsg.error ("Error loading file " ^ LoadFromFilename ^ " (" ^ s ^ ")")
846
847 fun listFiles () = map #2 (SM.listItems (!files))
848
746 end 849 end