]> matita.cs.unibo.it Git - helm.git/blob - helm/software/components/hbugs/hbugs_misc.ml
handles bad Appl
[helm.git] / helm / software / components / hbugs / hbugs_misc.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 (* $Id$ *)
30
31 open Printf;;
32
33 let rec hashtbl_remove_all tbl key =
34   if Hashtbl.mem tbl key then begin
35     Hashtbl.remove tbl key;
36     hashtbl_remove_all tbl key
37   end else
38     ()
39
40   (** follows cut and paste from zack's Http_client_smart module *)
41
42 exception Malformed_URL of string;;
43 exception Malformed_HTTP_response of string;;
44
45 let bufsiz = 16384;;
46 let tcp_bufsiz = 4096;;
47
48 let body_sep_RE = Pcre.regexp "\r\n\r\n";;
49 let http_scheme_RE = Pcre.regexp ~flags:[`CASELESS] "^http://";;
50 let url_RE = Pcre.regexp "^([\\w.]+)(:(\\d+))?(/.*)?$";;
51 let parse_url url =
52   try
53     let subs =
54       Pcre.extract ~rex:url_RE (Pcre.replace ~rex:http_scheme_RE url)
55     in
56     (subs.(1),
57     (if subs.(2) = "" then 80 else int_of_string subs.(3)),
58     (if subs.(4) = "" then "/" else subs.(4)))
59   with exc -> raise (Malformed_URL url)
60 ;;
61 let get_body answer =
62   match Pcre.split ~rex:body_sep_RE answer with
63   | [_; body] -> body
64   | _ -> raise (Malformed_HTTP_response answer)
65 ;;
66
67 let init_socket addr port =
68   let inet_addr = (Unix.gethostbyname addr).Unix.h_addr_list.(0) in
69   let sockaddr = Unix.ADDR_INET (inet_addr, port) in
70   let suck = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
71   Unix.connect suck sockaddr;
72   let outchan = Unix.out_channel_of_descr suck in
73   let inchan = Unix.in_channel_of_descr suck in
74   (inchan, outchan)
75 ;;
76 let rec retrieve inchan buf =
77   Buffer.add_string buf (input_line inchan ^ "\n");
78   retrieve inchan buf
79 ;;
80
81 let http_get_iter_buf ~callback url =
82   let (address, port, path) = parse_url url in
83   let buf = String.create tcp_bufsiz in
84   let (inchan, outchan) = init_socket address port in
85   output_string outchan (sprintf "GET %s\r\n" path);
86   flush outchan;
87   (try
88     while true do
89       match input inchan buf 0 tcp_bufsiz with
90       | 0 -> raise End_of_file
91       | bytes when bytes = tcp_bufsiz ->  (* buffer full, no need to slice it *)
92           callback buf
93       | bytes when bytes < tcp_bufsiz ->  (* buffer not full, slice it *)
94           callback (String.sub buf 0 bytes)
95       | _ -> (* ( bytes < 0 ) || ( bytes > tcp_bufsiz ) *)
96           assert false
97     done
98   with End_of_file -> ());
99   close_in inchan (* close also outchan, same fd *)
100 ;;
101
102 let http_get url =
103   let buf = Buffer.create (tcp_bufsiz * 10) in
104   http_get_iter_buf (fun data -> Buffer.add_string buf data) url;
105   get_body (Buffer.contents buf)
106 ;;
107
108 let http_post ?(body = "") url =
109   let (address, port, path) = parse_url url in
110   let (inchan, outchan) = init_socket address port in
111   output_string outchan (sprintf "POST %s HTTP/1.0\r\n" path);
112   output_string outchan (sprintf "Content-Length: %d\r\n" (String.length body));
113   output_string outchan "\r\n";
114   output_string outchan body;
115   flush outchan;
116   let buf = Buffer.create bufsiz in
117   (try
118     retrieve inchan buf
119   with End_of_file -> close_in inchan); (* close also outchan, same fd *)
120   get_body (Buffer.contents buf)
121 ;;
122