Using OCaml to write web scripts - 2

Yesterday I have explained how to use an OCaml .ml script as an executable, and how to display a web page written in OCaml. I'll explain here how to parse a querystring.

The querystring is passed as the environment variable QUERY_STRING. I'll use the following module to fetch the querystring and parse it :

module Get =
  struct
    let query_string = try String.lowercase (Sys.getenv "QUERY_STRING") with
    Not_found -> ""

    let _Hash =
      let return = Hashtbl.create 23 in
      let rec split c = function
          "" -> []
        |s when s.[0] = c -> ""::(split c (String.sub s 1 ((String.length s)-1)))
        |s ->
          begin
            match (split c (String.sub s 1 ((String.length s)-1))) with
               [] -> [String.make 1 (s.[0])]
            |t::q -> ((String.make 1 (s.[0]))^t)::q
          end
      in
      let query_list = split ‘&’ query_string in
      let rec q2h = function
        [] -> ()
       |t::q ->  (
         q2h q;
         match (split ‘=’ t) with
            [] -> ()
          | arg::[] -> Hashtbl.add return arg ""
          | arg::value::_ -> Hashtbl.add return arg value;) in
      q2h query_list;
      return
    let arg x = try Hashtbl.find _Hash x with Not_found -> ""
    let iter f = Hashtbl.iter f _Hash
  end

This is a simple module which allows us to do some simple stuff. Speeking of which, here is a simple example :

let e s = print_string s

let print_arg_val x y = e ("<i>"^x^"</i> : "^y^"<br/>\n")

let fibo n =
  try
    let rec fibo = function
      0 -> 1
     |1 -> 1
     |n -> fibo (n-1) + fibo (n-2)
    in
    string_of_int (fibo (int_of_string n))
  with _ -> ""

let _ =
  e "Content-type: text/html\n\n";

  e "<a href=\"test.ml?arg1=val1&arg2=val2&arg3=val3&n=15\">Examples</a><br/><br/>\n";
 
  e "<b>Get.query_string</b> : <br/>\n";
  e (Get.query_string^"<br/>\n");
  e "<br/>\n";

  e "<b>Get.arg \"arg2\"</b> : <br/>\n ";
  e ((Get.arg "arg2")^"<br/>\n");
  e "<br/>\n";

  e "<b>fibo (Get.arg \"n\")</b> :<br/>\n";
  e (fibo (Get.arg "n"));
  e "<br/>\n";
  e "<br/>\n";

  e "<b>Get.iter print_arg_val</b> : <br/>\n";
  Get.iter print_arg_val;

Those are only simple examples, and there are a lot of things to improve in order to use this in a real website (for example the conversion of url encoded characters, etc.).

But as I stated previously, I did not aim to write a CGI module for OCaml : use ocamlcgi instead, this one was really written to be used in real life.

Moreover, the following module might be useful if you want to plug a MySQL database to a web app writtent in ocaml : ocaml-mysql.

Last, by using camlp4, it should be possible to write scripts which look more like some PHP, using (for example) this kind of syntax : <?caml () ?> (everything which is not between those should just be sent of the output).

As a conclusion, it is possible to write dynamic web pages in OCaml, but is it really useful ? OCaml's strong typing can be a real pain in such context (no

echo

function ala PHP, etc.) but someone might find something useful to it.

Downloaded : 138 times
File : ocaml_script_cgi.tar.gz
Size: 1.3 ko

Leave a Reply