]> matita.cs.unibo.it Git - helm.git/blob - helm/http_getter/http_getter_cache.ml
- added TODO about cache expires control
[helm.git] / helm / http_getter / http_getter_cache.ml
1 (*
2  * Copyright (C) 2003:
3  *    Stefano Zacchiroli <zack@cs.unibo.it>
4  *    for the HELM Team http://helm.cs.unibo.it/
5  *
6  *  This file is part of HELM, an Hypertextual, Electronic
7  *  Library of Mathematics, developed at the Computer Science
8  *  Department, University of Bologna, Italy.
9  *
10  *  HELM is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU General Public License
12  *  as published by the Free Software Foundation; either version 2
13  *  of the License, or (at your option) any later version.
14  *
15  *  HELM is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with HELM; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23  *  MA  02111-1307, USA.
24  *
25  *  For details, see the HELM World-Wide-Web page,
26  *  http://helm.cs.unibo.it/
27  *)
28
29 (* TODO cache expires control!!! *)
30
31 open Http_getter_common;;
32 open Http_getter_misc;;
33 open Http_getter_types;;
34 open Printf;;
35
36 let resource_type_of_url = function
37   | url when Pcre.pmatch ~pat:"\\.xml\\.gz$" url -> Enc_gzipped
38   | url when Pcre.pmatch ~pat:"\\.xml$" url -> Enc_normal
39   | url -> raise (Http_getter_invalid_URL url)
40 let extension_of_resource_type = function
41   | Enc_normal -> "xml"
42   | Enc_gzipped -> "xml.gz"
43
44   (* basename = resource name without trailing ".gz", if any *)
45 let is_in_cache basename =
46   Sys.file_exists
47     (match Http_getter_env.cache_mode with
48     | Enc_normal -> basename
49     | Enc_gzipped -> basename ^ ".gz")
50
51 let respond_xml ?(enc = Enc_normal) ?(patch = true) ~url ~uri outchan =
52   let resource_type = resource_type_of_url url in
53   let extension = extension_of_resource_type resource_type in
54   let downloadname =
55     match http_getter_uri_of_string uri with  (* parse uri *)
56     | Xml_uri (Cic baseuri) | Xml_uri (Theory baseuri) ->
57           (* assumption: baseuri starts with "/" *)
58         sprintf "%s%s.%s" Http_getter_env.xml_dir baseuri extension
59     | Rdf_uri (prefix, ((Cic baseuri) as qbaseuri))
60     | Rdf_uri (prefix, ((Theory baseuri) as qbaseuri)) ->
61         let escaped_prefix =
62           (Pcre.replace ~pat:"/" ~templ:"_"
63             (Pcre.replace ~pat:"_" ~templ:"__"
64               (prefix ^
65               (match qbaseuri with
66               | Cic _ -> "//cic:"
67               | Theory _ -> "//theory:"))))
68         in
69         sprintf "%s/%s%s.%s"
70           Http_getter_env.rdf_dir escaped_prefix baseuri extension
71   in
72   let patch_fun =
73     if patch then Http_getter_common.patch_xml else (fun x -> x)
74   in
75   let basename = Pcre.replace ~pat:"\\.gz$" downloadname in
76   if not (is_in_cache basename) then begin (* download and fill cache *)
77     mkdir ~parents:true (Filename.dirname downloadname);
78     wget ~output:downloadname url;
79     match (resource_type, Http_getter_env.cache_mode) with
80     | Enc_normal, Enc_normal ->
81         (if enc = Enc_gzipped then gzip ~keep:true downloadname)
82     | Enc_gzipped, Enc_gzipped ->
83         (if enc = Enc_normal then gunzip ~keep:true downloadname)
84     | Enc_normal, Enc_gzipped -> gzip ~keep:(enc = Enc_normal) downloadname
85     | Enc_gzipped, Enc_normal -> gunzip ~keep:(enc = Enc_gzipped) downloadname
86   end else begin  (* resource already in cache *)
87     match (enc, Http_getter_env.cache_mode) with
88     | Enc_normal, Enc_normal | Enc_gzipped, Enc_gzipped -> ()
89     | Enc_normal, Enc_gzipped -> gunzip ~keep:true (basename ^ ".gz")
90     | Enc_gzipped, Enc_normal -> gzip ~keep:true basename
91   end;  (* now resource is in cache *)
92   (* invariant: file to be sent back to client is available on disk in the
93   format the client likes *)
94   (match enc with  (* send file to client *)
95   | Enc_normal ->
96       return_file ~fname:basename ~contype:"text/xml" ~patch_fun outchan
97   | Enc_gzipped ->
98       return_file
99         ~fname:(basename ^ ".gz") ~contype:"text/xml"  ~contenc:"x-gzip"
100         ~patch_fun outchan);
101   match (enc, Http_getter_env.cache_mode) with  (* remove temp files *)
102   | Enc_normal, Enc_normal | Enc_gzipped, Enc_gzipped -> ()
103   | Enc_normal, Enc_gzipped -> Sys.remove basename
104   | Enc_gzipped, Enc_normal -> Sys.remove (basename ^ ".gz")
105
106   (* TODO enc is not yet supported *)
107 let respond_xsl ?(enc = Enc_normal) ?(patch = true) ~url outchan =
108   let patch_fun =
109     if patch then Http_getter_common.patch_xsl else (fun x -> x)
110   in
111   let fname = tempfile () in
112   wget ~output:fname url;
113   return_file ~fname ~contype:"text/xml" ~patch_fun outchan;
114   Sys.remove fname
115
116   (* TODO enc is not yet supported *)
117 let respond_dtd ?(enc = Enc_normal) ?(patch = true) ~url outchan =
118   let patch_fun =
119     if patch then Http_getter_common.patch_dtd else (fun x -> x)
120   in
121   if Sys.file_exists url then
122     (* TODO check this: old getter here used text/xml *)
123     return_file ~fname:url ~contype:"text/plain" ~patch_fun outchan
124   else
125     return_html_error ("Can't find DTD: " ^ url) outchan
126