// REFERENCE: System.Web.dll using Nemerle.Collections; using Nemerle.IO; module CGI_Ank { /** * Splits a string given a separator character. Checks if the split was * unique -- or, if the separator occured exactly once in the original * string. */ private split_unique_at (separator : char, str : string) : string * string * bool { def pos = str.IndexOf (separator); def (l, r) = if (pos != -1) (str.Substring (0, pos), str.Substring (pos + 1)) else (str, ""); def validity = l.IndexOf (separator) == -1 && r.IndexOf (separator) == -1; (l, r, validity) } /** * Parses a string of form: * * url?param_1=val_1¶m_2=val_2&...¶m_k=val_k * * Checks the validity of such a request. */ private parse_get_params (orig_url : string) : string * list [string * string] * bool { def (url, get_params, split_was_unique) = split_unique_at ('?', orig_url); def invalid = (orig_url, [], false); if (url.Length > 0 && split_was_unique) { // check the case for no GET parameters if (get_params.Length == 0) { (url, [], true) } else { def delimiter = array ['&']; def split = get_params.Split (delimiter); // check for the url?param special case if (split.Length == 1) { def (param, value, split_was_unique) = split_unique_at ('=', split [0]); if (split_was_unique) (url, [(param, value)], true) else invalid } else { mutable params_are_valid = true; mutable result = []; mutable index = 0; while (index < split.Length) { def (param, value, split_was_unique) = split_unique_at ('=', split [index]); def param = System.Web.HttpUtility.UrlDecode (param, System.Text.Encoding.UTF8); def value = System.Web.HttpUtility.UrlDecode (value, System.Text.Encoding.UTF8); unless (split_was_unique) params_are_valid = false; unless (param.Length == 0) result = (param, value) :: result; index = index + 1 }; if (params_are_valid) (url, List.Rev (result), true) else invalid } } } else invalid } /** * Retrieves the post data */ private parse_post_data () : list [string * string] * bool { def buf = array (50000); def count = System.Console.In.ReadBlock (buf, 0, buf.Length); def (_, post_params, validity) = parse_get_params ("post?" + System.String (buf, 0, count)); (post_params, validity) } public Main () : void { def (pp, val) = parse_post_data(); def env = [ "REMOTE_ADDR", "REMOTE_PORT", "REQUEST_METHOD", "REQUEST_URI" ]; if (val) { def guid = System.Guid.NewGuid ().ToString (); def f = System.IO.StreamWriter ("/home/services/httpd/cgi-spool/poll/" + guid); List.Iter (pp, fun (n, v) { f.Write (sprintf ("%s: '''%s'''\n", n, v)) }); List.Iter (env, fun (e) { def v = System.Environment.GetEnvironmentVariable (e); def v = if (v == null) "(null)" else v; f.Write (sprintf ("%s: '''%s'''\n", e, v)) }); f.Close (); printf ("Content-Type: text/html\n\n[html][body]Your remarks has been stored.\n"); } else printf ("Content-Type: text/html\n\n[html][body]Inalid request.\n"); } }