HadiRj
HadiRj

Reputation: 1015

Socket exception in sending HTTP request without Connection header using sockets

When I use the following code to send HTTP GET request using sockets in C#

    IPEndPoint RHost = new IPEndPoint(IPAddress.Parse("xxx.xxx.xxx.xxx"), 80);
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socket.Connect(RHost);
    String req = "GET / HTTP/1.1\r\nHost: awebsite.com\r\n\r\n";

    socket.Send(Encoding.ASCII.GetBytes(req), SocketFlags.None);
    int bytes = 0;
    byte[] buffer = new byte[256];
    var result = new StringBuilder();

    do
    {
        bytes = socket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
        result.Append(Encoding.ASCII.GetString(buffer, 0, bytes));
    }
    while (bytes > 0);

I get

System.Net.Sockets.SocketException: 'An existing connection was forcibly closed by the remote host'

and when I add Connection: Close header to the request, it is working without any problem. But using Repeater tool in the Burp Suite I am able to send and receive a response from the server without setting Connection: Close header.

Notes:

Upvotes: 3

Views: 1371

Answers (1)

Steffen Ullrich
Steffen Ullrich

Reputation: 123541

You are sending a HTTP/1.1 request. Without an explicit Connection: close there is an implicit Connection: keep-alive with HTTP/1.1 (different to HTTP/1.0). This means that the server might wait for new requests within the same TCP connection after the response is done and close the connection sometimes later if no new requests arrive. This later close might be done with a RST which results in the error you see.

But, your code expects the server to behave differently: it expects that the server closes the connection once the request is done and not to wait for more requests and not to close the idle connection with RST.

To fix this you have either to adapt your request so that the server behavior matches your expectations or to adjust the expectations.
The first can be done by either explicitly adding Connection: close header or by simply using HTTP/1.0 instead of HTTP/1.1. The latter one is recommended because this also results in simpler responses (no chunked response).
If you instead want to adjust your expectations you have to properly parse the servers response: first read the header, then check for Transfer-Encoding: chunked or Content-length and then read the response body based on what these headers say. For details see the HTTP standard.

Upvotes: 4

Related Questions