From 3a6f1747d3a6b445b9b8ba11a86e7a7e2b67be2f Mon Sep 17 00:00:00 2001 From: Stefano Zacchiroli Date: Tue, 16 Dec 2003 16:17:52 +0000 Subject: [PATCH] added http_client module --- helm/DEVEL/ocaml-http/Makefile | 12 +++--- helm/DEVEL/ocaml-http/http_client.ml | 55 +++++++++++++++++++++++++++ helm/DEVEL/ocaml-http/http_client.mli | 2 + 3 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 helm/DEVEL/ocaml-http/http_client.ml create mode 100644 helm/DEVEL/ocaml-http/http_client.mli diff --git a/helm/DEVEL/ocaml-http/Makefile b/helm/DEVEL/ocaml-http/Makefile index 488ae4082..105856926 100644 --- a/helm/DEVEL/ocaml-http/Makefile +++ b/helm/DEVEL/ocaml-http/Makefile @@ -1,14 +1,16 @@ include Makefile.defs -MODULES = \ - http_types http_constants http_parser_sanity http_misc http_common \ - http_tcp_server http_parser http_message http_request http_daemon \ - http_response +MODULES = \ + http_types http_constants http_parser_sanity http_misc http_common \ + http_tcp_server http_parser http_message http_request http_daemon \ + http_response http_client THREADED_SRV = http_threaded_tcp_server MODULES_MT = $(patsubst http_tcp_server, mt/$(THREADED_SRV) http_tcp_server, $(MODULES)) MODULES_NON_MT = $(patsubst http_tcp_server, non_mt/$(THREADED_SRV) http_tcp_server, $(MODULES)) -PUBLIC_MODULES = http_common http_message http_request http_daemon http_response +PUBLIC_MODULES = \ + http_common http_message http_request http_daemon http_response \ + http_client PUBLIC_IMPL = http_types OCAMLDOC_STUFF = *.mli $(patsubst %, %.ml, $(PUBLIC_IMPL)) DOCDIR = doc/html diff --git a/helm/DEVEL/ocaml-http/http_client.ml b/helm/DEVEL/ocaml-http/http_client.ml new file mode 100644 index 000000000..e0f9d0f11 --- /dev/null +++ b/helm/DEVEL/ocaml-http/http_client.ml @@ -0,0 +1,55 @@ + +open Printf + +let http_scheme_RE = Pcre.regexp ~flags:[`CASELESS] "^http://" +let url_RE = Pcre.regexp "^([\\w.-]+)(:(\\d+))?(/.*)?$" + +let tcp_bufsiz = 4096 (* for TCP I/O *) + +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 -> + failwith + (sprintf "Can't parse url: %s (exception: %s)" + url (Printexc.to_string exc)) + +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 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 HTTP/1.0\r\n\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 10240 in + http_get_iter_buf ~callback:(Buffer.add_string buf) url; + Buffer.contents buf + diff --git a/helm/DEVEL/ocaml-http/http_client.mli b/helm/DEVEL/ocaml-http/http_client.mli new file mode 100644 index 000000000..302993651 --- /dev/null +++ b/helm/DEVEL/ocaml-http/http_client.mli @@ -0,0 +1,2 @@ +val http_get_iter_buf: callback:(string -> unit) -> string -> unit +val http_get: string -> string -- 2.39.2