X-Git-Url: http://matita.cs.unibo.it/gitweb/?p=helm.git;a=blobdiff_plain;f=components%2Fhbugs%2Fhbugs_misc.ml;fp=components%2Fhbugs%2Fhbugs_misc.ml;h=32b8e8b4698288990ab50a59c21df25393cdc3f5;hp=0000000000000000000000000000000000000000;hb=f61af501fb4608cc4fb062a0864c774e677f0d76;hpb=58ae1809c352e71e7b5530dc41e2bfc834e1aef1 diff --git a/components/hbugs/hbugs_misc.ml b/components/hbugs/hbugs_misc.ml new file mode 100644 index 000000000..32b8e8b46 --- /dev/null +++ b/components/hbugs/hbugs_misc.ml @@ -0,0 +1,122 @@ +(* + * Copyright (C) 2003: + * Stefano Zacchiroli + * for the HELM Team http://helm.cs.unibo.it/ + * + * This file is part of HELM, an Hypertextual, Electronic + * Library of Mathematics, developed at the Computer Science + * Department, University of Bologna, Italy. + * + * HELM is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * HELM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HELM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + * + * For details, see the HELM World-Wide-Web page, + * http://helm.cs.unibo.it/ + *) + +(* $Id$ *) + +open Printf;; + +let rec hashtbl_remove_all tbl key = + if Hashtbl.mem tbl key then begin + Hashtbl.remove tbl key; + hashtbl_remove_all tbl key + end else + () + + (** follows cut and paste from zack's Http_client_smart module *) + +exception Malformed_URL of string;; +exception Malformed_HTTP_response of string;; + +let bufsiz = 16384;; +let tcp_bufsiz = 4096;; + +let body_sep_RE = Pcre.regexp "\r\n\r\n";; +let http_scheme_RE = Pcre.regexp ~flags:[`CASELESS] "^http://";; +let url_RE = Pcre.regexp "^([\\w.]+)(:(\\d+))?(/.*)?$";; +let parse_url url = + try + let subs = + Pcre.extract ~rex:url_RE (Pcre.replace ~rex:http_scheme_RE url) + in + (subs.(1), + (if subs.(2) = "" then 80 else int_of_string subs.(3)), + (if subs.(4) = "" then "/" else subs.(4))) + with exc -> raise (Malformed_URL url) +;; +let get_body answer = + match Pcre.split ~rex:body_sep_RE answer with + | [_; body] -> body + | _ -> raise (Malformed_HTTP_response answer) +;; + +let init_socket addr port = + let inet_addr = (Unix.gethostbyname addr).Unix.h_addr_list.(0) in + let sockaddr = Unix.ADDR_INET (inet_addr, port) in + let suck = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in + Unix.connect suck sockaddr; + let outchan = Unix.out_channel_of_descr suck in + let inchan = Unix.in_channel_of_descr suck in + (inchan, outchan) +;; +let rec retrieve inchan buf = + Buffer.add_string buf (input_line inchan ^ "\n"); + retrieve inchan buf +;; + +let http_get_iter_buf ~callback url = + let (address, port, path) = parse_url url in + let buf = String.create tcp_bufsiz in + let (inchan, outchan) = init_socket address port in + output_string outchan (sprintf "GET %s\r\n" path); + flush outchan; + (try + while true do + match input inchan buf 0 tcp_bufsiz with + | 0 -> raise End_of_file + | bytes when bytes = tcp_bufsiz -> (* buffer full, no need to slice it *) + callback buf + | bytes when bytes < tcp_bufsiz -> (* buffer not full, slice it *) + callback (String.sub buf 0 bytes) + | _ -> (* ( bytes < 0 ) || ( bytes > tcp_bufsiz ) *) + assert false + done + with End_of_file -> ()); + close_in inchan (* close also outchan, same fd *) +;; + +let http_get url = + let buf = Buffer.create (tcp_bufsiz * 10) in + http_get_iter_buf (fun data -> Buffer.add_string buf data) url; + get_body (Buffer.contents buf) +;; + +let http_post ?(body = "") url = + let (address, port, path) = parse_url url in + let (inchan, outchan) = init_socket address port in + output_string outchan (sprintf "POST %s HTTP/1.0\r\n" path); + output_string outchan (sprintf "Content-Length: %d\r\n" (String.length body)); + output_string outchan "\r\n"; + output_string outchan body; + flush outchan; + let buf = Buffer.create bufsiz in + (try + retrieve inchan buf + with End_of_file -> close_in inchan); (* close also outchan, same fd *) + get_body (Buffer.contents buf) +;; +