(* Ocaml - proxy - media files downloader Copyright (C) 2009 BODIN Antoine This program 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 3 of the License, or (at your option) any later version. This program 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 this program. If not, see . $ ocaml unix.cma str.cma proxy.ml *) open Unix open Str let proxy sin sout = let url = split_delim (regexp " ") (input_line sin) in let uri = "/"^ (List.nth (split_delim (regexp "http://[A-Za-z0-9._-]*\\(/\\|\\)") (List.nth url 1)) 1) in let domain = List.nth (split_delim (regexp "http://\\|/.*") (List.nth url 1)) 1 in let cin,cout = open_connection (ADDR_INET ( (gethostbyname domain).h_addr_list.(0), 80)) in let scan sockin sockout = let l = ref 0 in (try while true do match input_line sockin with "\r" -> output_string sockout "\r\n"; failwith "end" | c when string_match (regexp "Content-Length: [0-9]*\r") c 0 -> Scanf.sscanf c "Content-Length: %u" (fun x->l:=x); output_string sockout (c^"\n") | c -> output_string sockout (c^"\n") done with _ -> ()); !l in output_string cout ((List.nth url 0)^" "^uri^" "^(List.nth url 2)^"\n"); for i=1 to (scan sin cout) do output_byte cout (input_byte sin) done; flush cout; begin match scan cin sout with 0 -> (try while true do output_byte sout (input_byte cin) done with _ -> ()) | l -> match (let ty = String.make 3 ' ' in match (really_input cin ty 0 3; output sout ty 0 3; ty) with "FLV" | "ID3" -> (match (Printf.printf "# %s Media of %u bytes spoted, save ? [y/n]\n" ty l; read_line ()) with "y" -> ty | "n" -> "" | _ -> print_endline "# error : unbound command"; "") | _ -> "") with "" -> for i=1 to l-3 do output_byte sout (input_byte cin) done; | ty -> (let file = open_out (print_endline "# File name :"; read_line ()) in let percent = ref 0 in output file ty 0 3; for i=1 to l-3 do let b = (input_byte cin) in (match (100*((i+3)/100)/(l/100)) with n when n=(!percent) -> () | n -> (percent := n; Printf.printf "\r> downloading : %d %% %u / %u" n (i+3) l; flush Pervasives.stdout)); output_byte file b; output_byte sout b; done; print_endline "\n# saved"; close_out file) end; flush sout; shutdown_connection cin let _ = let inetaddr = ADDR_INET (inet_addr_any, match Array.length Sys.argv with 2 -> int_of_string Sys.argv.(1) | _ -> print_endline "using default port 9999"; 9999 ) in establish_server proxy inetaddr