0

I wrote a program that was supposed to print the main web page of a BBC server. The BBC server host name is www.bbc.co.uk and its IP address is 38.160.150.31. When i send the HTTP GET command message to the server, i don't get the main web page of BBC, instead i get the following:

HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Connection: close
Content-Length: 685

<HTML><HEAD>
<TITLE>Appliance Error</TITLE>
</HEAD>
<BODY>
<FONT face="Helvetica">
<big><strong></strong></big><BR>
</FONT>
<blockquote>
<TABLE border=0 cellPadding=1 width="80%">
<TR><TD>
<FONT face="Helvetica">
<big>Appliance Error (internal_error)</big>
<BR>
<BR>
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica">
An unrecoverable error was encountered: ""
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica">
This problem is unexpected. Please use the contact information below to obtain assistance.
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica" SIZE=2>
<BR>
For assistance, contact your network support team.
</FONT>
</TD></TR>
</TABLE>
</blockquote>
</FONT>
</BODY></HTML>

My Code:

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <string.h>

int main()
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
        puts("Error: Cannot initialize winsock.");
        return 0;
    }
    SOCKET mainSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (mainSocket == INVALID_SOCKET || mainSocket == SOCKET_ERROR) {
        puts("Error: Cannot create socket.");
        return 0;
    }

    SOCKADDR_IN hostAddress;
    hostAddress.sin_family = AF_INET;
    hostAddress.sin_port = htons(80);
    hostAddress.sin_addr.S_un.S_addr = inet_addr("38.160.150.31");

    if (connect(mainSocket, (SOCKADDR*) &hostAddress, sizeof(hostAddress)) == SOCKET_ERROR) {
        printf("Cannot connect to the server. Error Code: %d\n", WSAGetLastError());
        return 0;
    }
    puts("Connected!");

    char *message = "GET HTTP/1.1\r\nHost: www.bbc.co.uk\r\n\r\n";
    int retval = send(mainSocket, message, strlen(message), 0);
    if (retval == 0) {
        puts("Error: Connection lost.");
        return 0;
    } else if (retval < 0) {
        printf("Error: Cannot send any message. Err #%d\n", WSAGetLastError());
        return 0;
    }
    char *serverReply = (char*) malloc(sizeof(char)*1000);
    if (serverReply == NULL) {
        puts("Error: Out of memory.");
        return 0;
    }
    puts("Recieved:");
    while (1) {
        retval = recv(mainSocket, serverReply, 999, 0);
        if (retval <= 0) break;
        serverReply[retval] = '\0';
        printf("%s", serverReply);
    }
    closesocket(mainSocket);
    puts("\nConnection closed.");
    WSACleanup();
    free(serverReply);
    return 1;
}

What is wrong with my code?

1 Answers1

2

In the line

char *message = "GET HTTP/1.1\r\nHost: www.bbc.co.uk\r\n\r\n";

the request target is missing.

3.1.1. Request Line

A request-line begins with a method token, followed by a single space (SP), the request-target, another single space (SP), the protocol version, and ends with CRLF.

request-line = method SP request-target SP HTTP-version CRLF

see https://www.rfc-editor.org/rfc/rfc7230#section-3.1.1

Therefore the code line should look like:

char* message = "GET / HTTP/1.1\r\nHost: www.bbc.co.uk\r\n\r\n";

Note the / after the GET.

Side Notes

nslookup www.bbc.co.uk returns a different IP address for me. Presumably the IP address is different for some users, probably depending on their geographical location or load balancing systems, among other things.

When the program is executed, it returns an HTTP status code 301, which means

The HyperText Transfer Protocol (HTTP) 301 Moved Permanently redirect status response code indicates that the resource requested has been definitively moved to the URL given by the Location headers.

see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301

The Location header is:

Location: https://www.bbc.co.uk/

Please note the https protocol.

So to get the content of the BBC website, you need to make an https request. You probably want to use a library for this, see for example this nice answer: https://stackoverflow.com/a/16255486/2331445

Community
  • 1
  • 1
Stephan Schlecht
  • 26,556
  • 1
  • 33
  • 47