/_sitemap.rss for COCANWIKI.
[cocanwiki.git] / scripts / image.ml
1 (* COCANWIKI - a wiki written in Objective CAML.
2  * Written by Richard W.M. Jones <rich@merjis.com>.
3  * Copyright (C) 2004 Merjis Ltd.
4  * $Id: image.ml,v 1.17 2006/08/01 14:50:47 rich Exp $
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; see the file COPYING.  If not, write to
18  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *)
21
22 open Apache
23 open Registry
24 open Cgi
25 open Printf
26
27 open ExtString
28
29 open Cocanwiki
30
31 let run r (q : cgi) dbh hostid {hostname = hostname} _ =
32   let image = q#param "image" in
33   let is_thumbnail = q#param_true "thumbnail" in
34   let version =
35     try Some (Int32.of_string (q#param "version")) with Not_found -> None in
36
37   (* Get the image and its MIME type. *)
38   let data, mime_type, deleted =
39     try
40       if not is_thumbnail then
41         List.hd (
42           match version with
43           | None ->
44               PGSQL(dbh) "select image, mime_type, name is null
45                             from images
46                            where hostid = $hostid and name = $image"
47           | Some version ->
48               PGSQL(dbh) "select image, mime_type, name is null
49                             from images
50                            where hostid = $hostid
51                              and (name = $image or name_deleted = $image)
52                              and id = $version"
53         )
54       else (
55         let data, mime_type, deleted =
56           List.hd (
57             match version with
58             | None ->
59                 PGSQL(dbh) "select thumbnail, tn_mime_type, name is null
60                               from images
61                              where hostid = $hostid and name = $image"
62             | Some version ->
63                 PGSQL(dbh) "select thumbnail, tn_mime_type, name is null
64                               from images
65                              where hostid = $hostid
66                                and (name = $image or name_deleted = $image)
67                                and id = $version"
68           ) in
69         Option.get data, Option.get mime_type, deleted
70       )
71     with
72       Not_found | ExtList.List.Empty_list | Failure "hd" ->
73         raise (HttpError cHTTP_NOT_FOUND) in
74
75   let deleted = Option.get deleted in
76
77   (* If deleted, refuse to serve this image except if shown on the site. *)
78   if deleted then (
79     let referer =
80       try Table.get (Request.headers_in r) "Referer" with Not_found -> "" in
81     let ok =
82       try ignore (String.find referer hostname); true
83       with Invalid_string -> false in
84
85     if not ok then (
86       prerr_endline "image.ml: bandwidth theft avoided";
87       raise (HttpError cHTTP_NOT_FOUND)
88     )
89   );
90
91   (* Set a medium-length expiry time on this resource. *)
92   Table.set (Request.headers_out r) "Expires" (Expires.medium ());
93
94   (* Content-length header. *)
95   Table.set (Request.headers_out r) "Content-Length"
96     (string_of_int (String.length data));
97
98   q#header ~content_type:mime_type ();
99   ignore (print_string r data)
100
101 let () =
102   register_script ~restrict:[CanView] run