]> matita.cs.unibo.it Git - helm.git/commitdiff
added http_client module
authorStefano Zacchiroli <zack@upsilon.cc>
Tue, 16 Dec 2003 16:17:52 +0000 (16:17 +0000)
committerStefano Zacchiroli <zack@upsilon.cc>
Tue, 16 Dec 2003 16:17:52 +0000 (16:17 +0000)
helm/DEVEL/ocaml-http/Makefile
helm/DEVEL/ocaml-http/http_client.ml [new file with mode: 0644]
helm/DEVEL/ocaml-http/http_client.mli [new file with mode: 0644]

index 488ae4082a11f47a9a23c20bc3b8e7866d09d76e..10585692654232084918ec6131f097c2a409e203 100644 (file)
@@ -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 (file)
index 0000000..e0f9d0f
--- /dev/null
@@ -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 (file)
index 0000000..3029936
--- /dev/null
@@ -0,0 +1,2 @@
+val http_get_iter_buf: callback:(string -> unit) -> string -> unit
+val http_get: string -> string