Thread: Header "malformed syntax"

  1. #1
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391

    Header "malformed syntax"

    Hey folks.

    Here are the details:
    Code:
    char ServerName[40] = "www.example.com";
    char FilePath[40] = "/index.html";
    .
    .
    .
    strcpy(storage,"GET ");
    strcat(storage, FilePath);
    strcat(storage, " HTTP/1.1\ Host: ");
    strcat(storage, ServerName);
    strcat(storage, " \r\n\r\n");
    
    iResult = recv(ConnectSocket,storage,STORAGE_LEN,0);
    And here is the server response:
    Code:
    HTTP/1.1 400 Bad Request
    Date: Wed, 11 Mar 2009 10:38:55 GMT
    Server: Apache/2.2.3 (CentOS)
    Content-Length: 306
    Connection: close
    Content-Type: text/html; charset=iso-8859-1
    
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html><head>
    <title>400 Bad Request</title>
    </head><body>
    <h1>Bad Request</h1>
    <p>Your browser sent a request that this server could not understand.<br />
    </p>
    <hr>
    <address>Apache/2.2.3 (CentOS) Server at www.example.com Port 80</address>
    </body>
    </html>
    I am getting this type of message from all servers that I have tried to connect to.

    A search on google shows that "HTTP/1.1 400 Bad Request" means the header has a "malformed syntax", but I have not been able to find a working solution.

    This code below works for some webpages with small amounts of content(a few hundred characters), but for lots of content(a whole page of text), the server resends parts of the content.

    Code:
    strcpy(storage, "GET / \r\n");
    strcat(storage, "HTTP 1.0 \r\n\r\n");
    Can someone please point me in the right direction?

    Thanks in advance.

    EDIT: If I was to use the above code, for www.example.com, here is the server response:
    Code:
    <HTML>
    <HEAD>
    <TITLE>Example Web Page</TITLE>
    </HEAD> 
    <body>  
    <p>You have reached this web page by typing &quot;example.com&quot;,
    &quot;example.net&quot;, or &quot;example.org&quot; into your web browser.</p>
    <p>These domain names are reserved for use in documentation and are not available 
     for registration. See <a href="http://www.rfc-editor.org/rfc/rfc2606.txt">RFC 
     2606</a>, Section 3.</p>
    </BODY>
    </HTML>
    But the server doesn't provide the time, or date, or bytes returned, or the server OS etc.
    Last edited by happyclown; 03-11-2009 at 07:12 AM.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    " HTTP/1.1\ Host: "

    After HTTP/1.1
    you need
    \r\n not \

    You always can use the Etheral/Wireshark to catch packets sent by the browser and your application and compare them to understand the problem
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Hi vart.

    I tried
    Code:
    " HTTP/1.1\r\n Host: "
    but the server still sends same the message.

    So I tried
    Code:
    char ServerName[40] = "Host: www.example.com";
    strcat(storage, " HTTP/1.1\r\n ");
    which results in a getaddrinfo() error.

    Are you saying Host should not be on the same line as HTTP/1.1?

    EDIT: I'll give wireshark a go.

    Thanks!
    Last edited by happyclown; 03-11-2009 at 12:16 PM.

  4. #4
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Well, Wireshark shows for a successful connection to www.example.com:
    Code:
    GET / HTTP/1.1\r\n
    
    User-Agent: Opera/9.27 (Windows NT 5.1; U; en)\r\n
    Host: www.example.com\r\n
    
    Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1\r\n
    Accept-Language: en-US,en;q=0.9\r\n
    Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n
    Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0\r\n
    Connection: Keep-Alive\r\n
    \r\n
    So I guess I'll have to hand code all this?!

    But if I am only using a console, instead of the opera browser, what do I put in the "User Agent" field?

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  6. #6
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Thanks Vart, I'll give it a go.

  7. #7
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Well, I couldn't find any windows console application user-agents in that list, so I just used Opera as the user-agent.
    Code:
    strcpy(storage,"GET / HTTP/1.1\r\n");
    strcat(storage, "User-Agent: Opera/9.27 (Windows NT 5.1; U; en)");
    strcat(storage, "\r\n");
    strcat(storage, "Host: www.example.com");
    strcat(storage, "\r\n");
    strcat(storage, "Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */ *;q=0.1");
    strcat(storage, "\r\n");
    strcat(storage, "Accept-Language: en-US,en;q=0.9\r\nAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1");
    strcat(storage, "\r\n");
    strcat(storage, "Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0");
    strcat(storage, "\r\n");
    strcat(storage, "Connection: Keep-Alive");
    strcat(storage, "\r\n\r\n");
    Server response:
    Code:
    HTTP/1.1 200 OK
    Date: Thu, 12 Mar 2009 01:26:34 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT
    ETag: "b80f4-1b6-80bfd280"
    Accept-Ranges: bytes
    Content-Length: 438
    Connection: close
    Content-Type: text/html; charset=UTF-8
    
    <HTML>
    <HEAD>
    <TITLE>Example Web Page</TITLE>
    </HEAD> 
    <body>  
    <p>You have reached this web page by typing &quot;example.com&quot;,
    &quot;example.net&quot;, or &quot;example.org&quot; into your web browser.</p>
    <p>These domain names are reserved for use in documentation and are not available 
    for registration. See <a href="http://www.rfc-editor.org/rfc/rfc2606.txt">RFC 2606</a>, Section 3.</p>
    </BODY>
    </HTML>

  8. #8
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    And here is my program, if any newbie wants to learn from it.

    Code:
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define STORAGE_LEN 1000
    #define DEFAULT_PORT "80"
    
    char storage[STORAGE_LEN];
    SOCKET ConnectSocket = INVALID_SOCKET;
    
    void write_to_file(char *storage)
    {
    	FILE *p_openfile = fopen("c:\\programs\\networking\\webpagecontent.txt" , "a+");
    	fprintf(p_openfile, "%s\n", storage);
    	fclose(p_openfile);
    }
    
    int main(void)
    {
    	
    	WSADATA wsaData;
    	char ServerName[40] = "www.example.com";
    //	char FilePath[40] = "/index.html";
    
    	int iResult;
    	struct addrinfo *result = NULL,
    				*ptr = NULL,
    				hints;
    
    	// Initialize Winsock
    	iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    	if(iResult != 0) {
    		printf("WSAStartup failed: %d\n", iResult);
    		return 1;
    	}
    
    	ZeroMemory(&hints, sizeof(hints));
    	hints.ai_family = AF_UNSPEC;
    	hints.ai_socktype = SOCK_STREAM;
    	hints.ai_protocol = IPPROTO_TCP;
    
    	// Resolve the server address and port
    	iResult = getaddrinfo(ServerName, DEFAULT_PORT, &hints, &result);
    	if(iResult != 0) {
    		printf("getaddrinfo failed: %d\n", iResult);
    		WSACleanup();
    		return 1;
    	}
    
    	// Attempt to connect to an address until one succeeds
    	for(ptr = result; ptr != NULL; ptr = ptr->ai_next) {
    		
    		// Create a socket for connecting to the server
    		ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
    		if(ConnectSocket == INVALID_SOCKET) {
    			printf("Error at socket(): %ld\n", WSAGetLastError());
    			freeaddrinfo(result);
    			WSACleanup();
    			return 1;
    		}
    
    	// Connect to server
    	iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
    	if(iResult == SOCKET_ERROR) {
    		closesocket(ConnectSocket);
    		ConnectSocket = INVALID_SOCKET;
    		continue;
    	}
    	break;
    }
    
    	freeaddrinfo(result);
    
    	if(ConnectSocket == INVALID_SOCKET) {
    		printf("Unable to connect to the server!\n");
    		return 1;
    	}
    
    	strcpy(storage,"GET / HTTP/1.1\r\n");
    	strcat(storage, "User-Agent: Opera/9.27 (Windows NT 5.1; U; en)");
    	strcat(storage, "\r\n");
    	strcat(storage, "Host: www.example.com");
    	strcat(storage, "\r\n");
    	strcat(storage, "Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */ *;q=0.1");
    	strcat(storage, "\r\n");
    	strcat(storage, "Accept-Language: en-US,en;q=0.9\r\nAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1");
    	strcat(storage, "\r\n");
    	strcat(storage, "Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0");
    	strcat(storage, "\r\n");
    	strcat(storage, "Connection: Keep-Alive");
    	strcat(storage, "\r\n\r\n");
    
    	printf("%s", storage);
    
    	// Send an initial buffer
    	
    	iResult = send(ConnectSocket,storage,sizeof(storage),0);
    	if (iResult == SOCKET_ERROR) {
            printf("send failed: %d\n", WSAGetLastError());
            closesocket(ConnectSocket);
            WSACleanup();
            return 1;
        }
    
    	printf("Bytes Sent: %ld\n", iResult);
    
    	// shutdown the connection since no more data will be sent
        iResult = shutdown(ConnectSocket, SD_SEND);
        if (iResult == SOCKET_ERROR) {
            printf("shutdown failed: %d\n", WSAGetLastError());
            closesocket(ConnectSocket);
            WSACleanup();
            return 1;
        }
    	
    	sprintf(storage, "shutdown = %d\n", iResult);
    	write_to_file(storage);
    
    	do {
    		iResult = recv(ConnectSocket,storage,STORAGE_LEN,0);
    		if ( iResult > 0 ) {
    			write_to_file(storage);
    			printf("Bytes received: %d\n", iResult);
    		}
    		else if ( iResult == 0 )
    			printf("Connection closed\n");
    		else
    			printf("recv failed: %d\n", WSAGetLastError());
    
        } while( iResult > 0 );
    
    	// cleanup
        closesocket(ConnectSocket);
        WSACleanup();
    
    	return 0;
    }

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by happyclown View Post
    Well, I couldn't find any windows console application user-agents in that list, so I just used Opera as the user-agent.
    If there were you would still be better off using "Opera" as the name -- some servers will reject requests from "all user-agents except XXX"
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Checking array for string
    By Ayreon in forum C Programming
    Replies: 87
    Last Post: 03-09-2009, 03:25 PM
  2. Obtaining source & destination IP,details of ICMP Header & each of field of it ???
    By cromologic in forum Networking/Device Communication
    Replies: 1
    Last Post: 04-29-2006, 02:49 PM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM