Minimal socket http server - sockets

I'm getting my feet wet with unix system programming, and am currently trying to implement a minimal http server with sockets.
Currently I have the following code (it's ocaml, the flow is the same as in any language)
let establish_server () =
let socket = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
Unix.bind socket (Unix.ADDR_INET ((Unix.inet_addr_of_string "127.0.0.1"), 8888));
Unix.listen socket 128;
print_endline "accepting now";
while true do
let (service_socket, addr) = Unix.accept socket in
print_endline "Something arrived!";
let b = Bytes.create 1024 in
let _ = Unix.recv service_socket b 0 1024 [Unix.MSG_PEEK] in
print_endline ## Bytes.to_string b;
let response = Bytes.of_string "HTTP/1.1 200 OK\n\nHey from Ocaml!" in
let _ = Unix.send service_socket response 0 (Bytes.length response) [Unix.MSG_PEEK] in
Unix.close service_socket;
done
Why do I have to close the socket to receive something in the browser when I visit 127.0.0.1:8888? If I don't close the socket on the last line, my browser keeps on spinning forever.
Can't you just send something to the other end of the socket? Why doesn't the browser show anything, if I don't close the socket?

There are (at least) three big things you need to do to be handling HTTP/1.1 properly:
1) You need to buffer input, because the browser's request might not arrive in a single packet. This means that the Unix.recv call may receive a partial request, and the next call will retrieve the rest of the request (or the next chunk). The simplest approach is to wrap the stream in some sort of reader that lets you request an entire line synchronously.
2) When sending a response, you have to supply a Content-Length header. Without this, the browser doesn't know when the data is finished -- and without it, the browser can't tell the difference between the response being completed and the connection being unexpected closed.
3) In HTTP 1.1, connections are assumed to be persistent unless the server explicitly tells the client that they aren't. Your server will perform better if you support Connection: keep-alive, but for a minimalist implementation, you should at least send a Connection: close response header.

Related

Play scala websocket - Hits websocket sequentially not In parallel

I have created a web socket that receives a single message, that will do some processing and returns the response message to the client. I have created web socket using Play framework. The code snippet is given below.
Code snippet:
def multi_request = WebSocket.tryAccept[String] {
request =>
val (out, channel) = Concurrent.broadcast[String]
val in = Iteratee.foreach[String] {
msg =>
channel push ("message " + msg +" request Time: " + System.currentTimeMillis()/1000)
if(msg.equals("1")) {
Thread.sleep(20000);
println(msg);
} else if(msg.equals("2")) {
Thread.sleep(10000);
println(msg);
} else {
println(msg);
}
channel push ("message " + msg +" response Time: " + System.currentTimeMillis()/1000)
}
Future.successful(Right(in, out))
}
I have tested my web socket from the http://www.websocket.org/echo.html.
I have connected my web socket and passed three messages sequentially as "1", 2" and "3". I got the below response while passing these messages.
SENT: 1
RESPONSE: message 1 request Time: 1457351625
SENT: 2
SENT: 3
RESPONSE: message 1 response Time: 1457351645
RESPONSE: message 2 request Time: 1457351646
RESPONSE: message 2 response Time: 1457351656
RESPONSE: message 3 request Time: 1457351656
RESPONSE: message 3 response Time: 1457351656
It seems that, the web socket request hits the server sequentially not In parallel. The three messages sent from the client immediately when I pass it. But it is not hitting server in parallel.
That is, the second request hits after the first response message. The third message hits after the second response message.
Is this the default web socket behaviour?
Or Do I want to implement multi-threading to handle this kind of request in Scala play Framework?
Or Did I miss anything in the code to handle multiple requests from the single client?
I understand this is web socket behaviour. This SO question explains in details how your web socket connection is uniquely identified by the pairs (IP,PORT) for both your client machine and the server as well as by the protocol used.
So basically you can have only one "physical websocket connection" (using the same port) between your client and your server. Looking at the documentation for accept, I read
If no pending connections are present on the queue, and the socket is not marked as nonblocking, accept() blocks the caller until a connection is present. If the socket is marked nonblocking and no pending connections are present on the queue, accept() fails with the error EAGAIN or EWOULDBLOCK.
I would love for someone more knowledgeable to confirm it, but I understand from this quote that since your potential connection is busy handling the first message, accept will tell your second request "try later", hence the sequential effect.
If you really need parallel websockets for one client, I guess opening connections on different ports would do the trick.

Receiving data from lua tcp socket without data size

I've been working in a socket tcp connection to a game server. The big problem here is that the game server send the data without any separators - since it sends the packet lenght inside the data -, making impossible to use socket:receive("*a") or "*l". The data received from the server does not have a static size and are sent in HEX format. I'm using this solution:
while true do
local rect, r, st = socket.select({_S.sockets.main, _S.sockets.bulle}, nil, 0.2)
for i, con in ipairs(rect) do
resp, err, part = con:receive(1)
if resp ~= nil then
dataRecv = dataRecv..resp
end
end
end
As you can see, I can only get all the data from the socket by reading one byte and appending it to a string, not a good way since I have two sockets to read. Is there a better way to receive data from this socket?
I don't think there is any other option; usually in a situation like this the client reads a packet of specific length to figure out how much it needs to read from the rest of the stream. Some protocols combine new line and the length; for example HTTP uses line separators for headers, with one of the headers specifying the length of the content that follows the headers.
Still, you don't need to read the stream one-by-one character as you can switch to non-blocking read and request any number of characters. If there is not enough to read, you'll get partially read content plus "timeout" signaled, which you can handle in your logic; from the documentation:
In case of error, the method returns nil followed by an error message
which can be the string 'closed' in case the connection was closed
before the transmission was completed or the string 'timeout' in case
there was a timeout during the operation. Also, after the error
message, the function returns the partial result of the transmission.

A Simple TCP Protocol to Transfer a "Large" Data File to a Server

MESSAGE TO DOWN VOTERS: Please read the question, I am working on a small embedded device. If you are not familar with the limitations of such a device, then please move onto another question instead of down voting!!!!
I am working with a small embedded device that has limited memory and I need to send a large file to a server from this device. Hence I cannot easily use HTTP POST which requires me to load the entire file into memory before sending.
The embedded device has UDP and TCP sockets, but to send a HTTP POST for example, I need to create a string that contains the HTTP HEADERS and the Data. As the device does not have the HTTP Protocol or other protocols available as APIs.
Can someone recommend a protocol I could use to perform the process of "streaming" or sending the data in parts to the server?
The protocol needs to be relatively simple and not use up many memory resources, and if you know of a library designed for small embedded device that would be good also. The protocol should also be simple to implement on the receiving server, preferable running .Net
I am working with a small embedded device that has limited memory and I need to send a large file to a server from this device. Hence I cannot easily use HTTP POST which requires me to load the entire file into memory before sending.
No, POST does not require that. All it requires is that the HTTP Content-Length header that you send matches the number of bytes that you send for the actual file data. Or you can use HTTP 1.1's chunked transfer encoding, which does not use the Content-Length header (so you don't need to know the file size ahead of time). POST (or HTTP, for that matter) has no concept of HOW you send the bytes in your code. So all would have to do is read the file data in a loop, using an appropriate-sized memory buffer, sending the content of that buffer over the socket after each read, until you hit EOF.
For example (pseudo-code):
sckt = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
connect(sckt, "hostname", 80)
send(sckt, "POST /resource HTTP/1.0\r\n")
send(sckt, "Content-Type: application/octet-stream\r\n"); // or the actual file type
send(sckt, "Content-Length: " + string(the file size) + "\r\n")
send(sckt, "\r\n")
byte buffer[256] // use whatever buffer size is appropriate for your device
do
{
numread = read(file, buffer, sizeof(buffer));
if (numread <= 0) break;
send(sckt, buffer, numread);
}
while (true);
read HTTP response from sckt ...
Or:
sckt = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
connect(sckt, "hostname", 80)
send(sckt, "POST /resource HTTP/1.1\r\n")
send(sckt, "Content-Type: application/octet-stream\r\n"); // or the actual file type
send(sckt, "Transfer-Encoding: chunked\r\n")
send(sckt, "\r\n")
byte buffer[256] // use whatever buffer size is appropriate for your device
char hex[12]
do
{
numread = read(file, buffer, sizeof(buffer));
if (numread <= 0) break;
sprintf(hex, "%x", numread);
send(sckt, string(hex) + "\r\n")
send(sckt, buffer, numread)
send(sckt, "\r\n")
}
while (true);
send(sckt, "0\r\n");
send(sckt, "\r\n");
read HTTP response from sckt ...
Even powerful desktop PCs have to do it this way, since an entire file usually cannot be put into the kernel buffer at one time anyway, so sending has to be looped accordingly.
The embedded device has UDP and TCP sockets, but to send a HTTP POST for example, I need to create a string that contains the HTTP HEADERS and the Data.
You DO NOT have to send everything at one time in a single string. You can break it up into multiple strings/sends as needed. TCP is a streaming transport, it doesn't care how many sends you perform, as long as the bytes you send are in the correct order. You could send 1 byte at a time for all it cares (though that would not be very efficient, but it would work).
As the device does not have the HTTP Protocol or other protocols available as APIs.
It doesn't need to. Since HTTP sits on top of TCP, and you have access to a TCP socket API, you can implement HTTP manually.
Can someone recommend a protocol I could use to perform the process of "streaming" or sending the data in parts to the server?
HTTP already does exactly that.
The protocol needs to be relatively simple and not use up many memory resources, and if you know of a library designed for small embedded device that would be good also. The protocol should also be simple to implement on the receiving server, preferable running .Net
HTTP is perfectly fine for that.

How to write a proxy in go (golang) using tcp connections

I apologize before hand if some of these questions might be obvious for expert network programmers. I have researched and read about coding in networking and it is still not clear to me how to do this.
Assume that I want to write a tcp proxy (in go) with the connection between some TCP client and some TCP server. Something like this:
First assume that these connection are semi-permanent (will be closed after a long long while) and I need the data to arrive in order.
The idea that I want to implement is the following: whenever I get a request from the client, I want to forward that request to the backend server and wait (and do nothing) until the backend server responds to me (the proxy) and then forward that response to the client (assume that both TCP connection will be maintained in the common case).
There is one main problem that I am not sure how to solve. When I forward the request from the proxy to the server, and get the response, how do I know when the server has sent me all the information that I need if I do not know beforehand the format of the data being sent from the server to the proxy (i.e. I don't know if the response from the server is of the form of type-length-value scheme nor do I know if `\r\n\ indicates the end of the message form the server). I was told that I should assume that I get all the data from the server connection whenever my read size from the tcp connection is zero or smaller than the read size that I expected. However, this does not seem correct to me. The reason it might not be correct in general is the following:
Assume that the server for some reason is only writing to its socket one byte at a time but the total length of the response to the "real" client is much much much longer. Therefore, isn't it possible that when the proxy reads the tcp socket connected to the server, that the proxy only reads one byte and if it loops fast enough (to do a read before it receives more data), then read zero and incorrectly concludes that It got all the message that the client intended to receive?
One way to fix this might be to wait after each read from the socket, so that the proxy doesn't loop faster than it gets bytes. The reason that I am worried is, assume there is a network partition and i can't talk to the server anymore. However, it is not disconnected from me long enough to timeout the TCP connection. Thus, isn't it possible that I try to read from the tcp socket to the server again (faster than I get data) and read zero and incorrectly conclude that its all the data and then send it pack to the client? (remember, the promise I want to keep is that I only send whole messages to the client when i write to the client connection. Thus, its illegal to consider correct behaviour if the proxy goes, reads the connection again at a later time after it already wrote to the client, and sends the missing chunk at a later time, maybe during the response of a different request).
The code that I have written is in go-playground.
The analogy that I like to use to explain why I think this method doesn't work is the following:
Say we have a cup and the proxy is drinking half the cup every time it does a read from the server, but the server only puts 1 teaspoon at a time. Thus, if the proxy drinks faster than it gets teaspoons it might reach zero too soon and conclude that its socket is empty and that its ok to move on! Which is wrong if we want to guarantee we are sending full messages every time. Either, this analogy is wrong and some "magic" from TCP makes it work or the algorithm that assumes until the socket is empty is just plain wrong.
A question that deals with a similar problems here suggests to read until EOF. However, I am unsure why that would be correct. Does reading EOF mean that I got the indented message? Is an EOF sent each time someone writes a chunk of bytes to a tcp socket (i.e. I am worried that if the server writes one byte at a time, that it sends 1 EOF per bytes)? However, EOF might be some of the "magic" of how a TCP connection really works? Does sending EOF's close the connection? If it does its not a method that I want to use. Also, I have no control of what the server might be doing (i.e. I do not know how often it wants to write to the socket to send data to the proxy, however, its reasonable to assume it writes to the socket with some "standard/normal writing algorithm to sockets"). I am just not convinced that reading till EOF from the socket from server is correct. Why would it? When can I even read to EOF? Are EOFs part of the data or are they in the TCP header?
Also, the idea that I wrote about putting a wait just epsilon bellow the time-out, would that work in the worst-case or only on average? I was also thinking, I realized that if the Wait() call is longer than the time-out, then if you return to the tcp connection and it doesn't have anything, then its safe to move on. However, if it doesn't have anything and we don't know what happened to the server, then we would time out. So its safe to close the connection (because the timeout would have done that anyway). Thus, I think if the Wait call is at least as long as the timeout, this procedure does work! What do people think?
I am also interested in an answer that can justify maybe why this algorithm work on some cases. For example, I was thinking, even if the server only write a byte at a time, if the scenario of deployment is a tight data centre, then on average, because delays are really small and the wait call is almost certainly enough, then wouldn't this algorithm be fine?
Also, are there any risks of the code I wrote getting into a "deadlock"?
package main
import (
"fmt"
"net"
)
type Proxy struct {
ServerConnection *net.TCPConn
ClientConnection *net.TCPConn
}
func (p *Proxy) Proxy() {
fmt.Println("Running proxy...")
for {
request := p.receiveRequestClient()
p.sendClientRequestToServer(request)
response := p.receiveResponseFromServer() //<--worried about this one.
p.sendServerResponseToClient(response)
}
}
func (p *Proxy) receiveRequestClient() (request []byte) {
//assume this function is a black box and that it works.
//maybe we know that the messages from the client always end in \r\n or they
//they are length prefixed.
return
}
func (p *Proxy) sendClientRequestToServer(request []byte) {
//do
bytesSent := 0
bytesToSend := len(request)
for bytesSent < bytesToSend {
n, _ := p.ServerConnection.Write(request)
bytesSent += n
}
return
}
// Intended behaviour: waits until ALL of the response from backend server is obtained.
// What it does though, assumes that if it reads zero, that the server has not yet
// written to the proxy and therefore waits. However, once the first byte has been read,
// keeps writting until it extracts all the data from the server and the socket is "empty".
// (Signaled by reading zero from the second loop)
func (p *Proxy) receiveResponseFromServer() (response []byte) {
bytesRead, _ := p.ServerConnection.Read(response)
for bytesRead == 0 {
bytesRead, _ = p.ServerConnection.Read(response)
}
for bytesRead != 0 {
n, _ := p.ServerConnection.Read(response)
bytesRead += n
//Wait(n) could solve it here?
}
return
}
func (p *Proxy) sendServerResponseToClient(response []byte) {
bytesSent := 0
bytesToSend := len(request)
for bytesSent < bytesToSend {
n, _ := p.ServerConnection.Write(request)
bytesSent += n
}
return
}
func main() {
proxy := &Proxy{}
proxy.Proxy()
}
Unless you're working with a specific higher-level protocol, there is no "message" to read from the client to relay to the server. TCP is a stream protocol, and all you can do is shuttle bytes back and forth.
The good news is that this is amazingly easy in go, and the core part of this proxy will be:
go io.Copy(server, client)
io.Copy(client, server)
This is obviously missing error handling, and doesn't shut down cleanly, but clearly shows how the core data transfer is handled.

Time Gap Between Socket Calls ie. Accept() and recv/send calls

I am implementing a server in which i listen for the client to connect using the accept socket call.
After the accept happens and I receive the socket, i wait for around 10-15 seconds before making the first recv/send call.
The send calls to the client fails with errno = 32 i.e broken pipe.
Since i don't control the client, i have set socket option *SO_KEEPALIVE* in the accepted socket.
const int keepAlive = 1;
acceptsock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_length)
if (setsockopt( acceptsock, SOL_SOCKET, SO_KEEPALIVE, &keepAlive, sizeof(keepAlive)) < 0 )
{
print(" SO_KEEPALIVE fails");
}
Could anyone please tell what may be going wrong here and how can we prevent the client socket from closing ?
NOTE
One thing that i want to add here is that if there is no time gap or less than 5 seconds between the accept and send/recv calls, the client server communication occurs as expected.
connect(2) and send(2) are two separate system calls the client makes. The first initiates TCP three-way handshake, the second actually queues application data for transmission.
On the server side though, you can start send(2)-ing data to the connected socket immediately after successful accept(2) (i.e. don't forget to check acceptsock against -1).
After the accept happens and I receive the socket, i wait for around 10-15 seconds before making the first recv/send call.
Why? Do you mean that the client takes that long to send the data? or that you just futz around in the server for 10-15s between accept() and recv(), and if so why?
The send calls to the client fails with errno = 32 i.e broken pipe.
So the client has closed the connection.
Since I don't control the client, i have set socket option SO_KEEPALIVE in the accepted socket.
That won't stop the client closing the connection.
Could anyone please tell what may be going wrong here
The client is closing the connection.
and how can we prevent the client socket from closing ?
You can't.