I am trying to write an http client in OCaml:
module Connection = struct
let sock_fd =
let s_fd = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
Unix.setsockopt s_fd Unix.TCP_NODELAY true;
s_fd
let read_from_sock () =
let buffer = Bytes.create 512 in
let rec read_all request buffer =
let r = Unix.read sock_fd buffer 0 512 in
if r < 512 then request ^ buffer
else read_all (request ^ buffer) buffer in
read_all "" buffer
let write_to_sock str =
let len = String.length str in
let _ = Unix.write sock_fd str 0 len in ()
let make_request request serv_addr =
Unix.connect sock_fd serv_addr;
write_to_sock request
class connection address port =
object
val serv_addr = Unix.ADDR_INET (Unix.inet_addr_of_string address, port)
method get_response request =
let _ = make_request request serv_addr in
let rec wait_for_response () =
let response = read_from_sock () in
match String.length response with
| 0 -> wait_for_response ()
| _ -> Printf.printf "%s\n" response in
wait_for_response ();
Unix.shutdown sock_fd Unix.SHUTDOWN_ALL;
Unix.close sock_fd
end
let create address port = new connection address port
end
let connection = Connection.create "54.175.219.8" 80;;
connection#get_response "GET / HTTP/1.1\r\n"
The program simply hangs until it crashes when the connection is reset during the read. The funky part is, no other errors are thrown. Since OCaml doesn't return an int response like C, I'd assume if I did something wrong connecting or creating the socket that the runtime would throw an error.
If you're not familiar with OCaml, I'd assume the (extremely rough) pseudo-C equivalent of what I'm doing is this (perhaps this will help the debugging):
int sock_fd = socket(PF_INET, SOCK_STREAM);
setsockopt(sock_fd, TCP_NODELAY, 1);
serv_addr addr {"54.175.219.8", 80};
connect(sock_fd, &serv_addr);
write(sock_fd, "GET / HTTP/1.1\r\n");
char buffer[512];
while (buffer = read(sock_fd)) {
printf("%s\n", buffer);
}
shutdown(sock_fd, SHUTDOWN_ALL);
close(sock_fd);
If that is not helpful, ignore it. I just figured I'd summarize in pseudo-code. Are there any glaring issues? (Aside from not reading the int response from socket/connect/write in the C because OCaml's runtime should? take care of throwing errors here.)