#line 493 "/home/travis/build/felix-lang/felix/src/packages/web.fdoc"
  include "web/__init__";
  
  publish """
  Implements default handlers for static content and error pages.
  Defines container http_hadler for use in constructing custom handlers
  for use in WebServer """
  class HTTPHandler {
    open HTTPResponse;
    open HTTPRequest;
    open HTTPConnection;
    open ServerConfig;
    open MIMEType;
    open Tord[mime_type];
  
    publish """ handles determines what requests are handleded by handler_fn.
    handler_fn handles http request and respons on http_connection """
    struct http_handler {
      handles: (server_config*http_request)->bool;
      handler_fn: (http_connection*http_request) -> void;
    }
  
    publish """ return option of the first element in a list mapped to type V satisfying
    the combined transformer and predicate xf """
  
   fun / (x:string, y:string) => Filename::join (x,y);
  
  fun find_and_map[T,V] (xf:T -> opt[V]) (xs:list[T]) : opt[V] =>
      match xs with
      | #Empty => None[V]
      | Cons (h,t) => match xf(h) with |Some (v) => Some(v) |_ => find_and_map xf t endmatch
      endmatch
    ;
  
  
  fun get_fs_path (config:server_config,request:http_request) =>
      match get_path_and_fname(request) with
        | Some(path,fname) => find_and_map[string,string] (fun (r:string):opt[string] => (let fs_path =
          Filename::join(Filename::join(r,path),fname) in
          if (FileStat::fileexists fs_path) then
            Some(fs_path)
          else
            None[string]
          endif)) (list(config.document_root,
            Filename::join(Filename::join(Filename::join(#Config::std_config.FLX_SHARE_DIR,"lib"),"web"),"html")))
        | _ => None[string]
      endmatch;
  
  
    fun txt2html (x:string) =
    {
      var out2 = "";
      var i:int;
      for i in 0 upto (int(len x) - 1) do
        var ch = x.[i];
        if ch == char "<" do out2+="&lt;";
        elif ch == char ">" do out2+="&gt;";
        elif ch == char "&" do out2+="&amp;";
        else out2+=ch;
        done
      done
     return out2;
    }
  
     gen handle_not_found(conn:http_connection, request:http_request) =  {
       var txt = "<div style='text-color:red;'>Page "+
         (match get_fname request with | Some(fname) => fname | _ => "NONE" endmatch)+
         " not found.</div>";
       val data = make_not_found txt;
       write(conn,data);
       return ;
     }
  
    proc do_handle_not_found(conn:http_connection, request:http_request) {
      handle_not_found(conn,request);
    }
  
    fun handle_not_found_route (config:server_config, request:http_request) => true;
  
    gen handle_css(conn:http_connection, request:http_request) = {
      match get_fs_path(conn.config,request) with
        | Some(file) => {
                         val txt = load (file);
        		       write(conn,(make_css txt));
                         }
        | _ => {do_handle_not_found(conn,request);}
     endmatch;
     return ;
    }
  
    fun handle_css_route (config:server_config, request:http_request) =>
      match (get_path_and_fname request) with
         | Some (p,f) => (match (mime_type_from_file f) with |text css => true | _ => false endmatch)
         | _ => false
       endmatch;
  
    gen handle_js(conn:http_connection, request:http_request) = {
      match get_fs_path(conn.config,request) with
        | Some(file) => {
                         val txt = load (file);
        		       write(conn,(make_js txt));
                         }
        | _ => {do_handle_not_found(conn,request);}
     endmatch;
     return ;
    }
  
    fun handle_js_route (config:server_config, request:http_request) =>
      match (get_path_and_fname request) with
        | Some (p,f) => (match (mime_type_from_file f) with
          |application javascript => true | _ => false endmatch)
        | _ => false
       endmatch;
  
    gen handle_image(conn:http_connection, request:http_request) = {
      match get_fs_path(conn.config,request) with
        | Some(file) => {
                         val txt = load (file);
        		       write(conn,make_image((mime_type_from_file file), txt));
                         }
        | _ => {do_handle_not_found(conn,request);}
     endmatch;
     return ;
    }
  
    fun handle_image_route (config:server_config,request:http_request) =>
       match (get_path_and_fname request) with
         | Some (p,f) => (match (mime_type_from_file f) with
              |image gif => true
              |image jpeg => true
              |image png => true
              |image tiff => true
              | _ => false endmatch)
         | _ => false
       endmatch;
  
    gen handle_html(conn:http_connection, request:http_request) = {
      if (request.uri == "/" and request.path == "/") do
        val txt = load (conn.config.document_root+"/index.html");
        write(conn,(make_html txt));
      else
        match get_fs_path(conn.config,request) with
          | Some(file) => {
                         val txt = load (file);
        		       write(conn,(make_html txt));
                         }
          | _ => {do_handle_not_found(conn,request);}
         endmatch;
      done
      return ;
    }
  
    fun handle_html_route (config:server_config,request:http_request):bool =>
       if (request.uri == "/" and request.path == "/") then
         true
       else
         match (get_path_and_fname request) with
           | Some (p,f) => (match (mime_type_from_file f) with |text html => true | _ => false endmatch)
           | _ => false
         endmatch
       endif;
  
    publish """ Returns list of Stock handlers """
    fun default_handlers() => list (
      http_handler(handle_html_route,handle_html),
  	  http_handler(handle_image_route,handle_image),
      http_handler(handle_css_route,handle_css),
  		http_handler(handle_js_route,handle_js),
      http_handler(handle_not_found_route,handle_not_found)
    );
  
  }