How to format the HTTP response

12,756

I have found the problem. The Response is incorrect. There should not be any spaces between the header field name and colon(':'). Found this in http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 .

My correct response is

HTTP/1.1 200 OK\r\nCache-Control: no-cache, private\r\nContent-Length: 107\r\nDate: Mon, 24 Nov 2014 10:21:21 GMT\r\n\r\n

I have put a space between 'Content-Length' and ':' . That's the reason Firefox ignored the content length header and reading the socket. Chrome accepted the header fields with spaces, so the problem doesn't occurred in chrome.

After removing the space, program works fine.

Share:
12,756
smartkid
Author by

smartkid

Updated on June 07, 2022

Comments

  • smartkid
    smartkid almost 2 years

    I have written a socket program in C. I used this program as a chat server/client using TCP. I tried to change the chat server to use it as a HTTP server by changing the port to 80. I referred to the HTTP request/response format in http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Example_session , and made my program to reply with sample response. I tried the url

    http://127.0.0.1/ 
    

    in browser. My program read the request and replied with response. At first, I used google-chrome. Chrome didn't load the page correctly until i added the correct data length in Content-Length header. After setting content length header, chrome loaded the page correctly. But, firefox doesn't load the page. Firefox doesn't showed any errors, but still loading the page like it is still waiting for some data. Only When i stop the server or close the socket, complete page is loaded. I tried to follow rfc2616 https://www.rfc-editor.org/rfc/rfc2616 , and made the response exactly , but the still the results are same.

    Request:

    GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nUser-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:33.0) Gecko/20100101 Firefox/33.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive\r\n\r\n

    For the above request, my program write to the socket with following response & content.

    Response:

    HTTP/1.1 200 OK\r\nCache-Control : no-cache, private\r\nContent-Length : 107\r\nDate : Mon, 24 Nov 2014 10:21:21 GMT\r\n\r\n

    Content:

    <html><head><title></title></head><body>TIME : 1416824843 <br>DATE: Mon Nov 24 15:57:23 2014 </body></html>
    

    This response is loading in Chrome, but not in firefox. Chrome is loading the page instantly whereas firefox is waiting for data. Note that the data length 107 is specified in the header. I donot have any addons enabled in firefox. My firefox version is in the request. Chrome version: Version 38.0.2125.111 (64-bit).

    Code:

    void *socket_read(void *args)
    {
        int socket,*s,length;
        char buf[1024];
        s=(int *)args;
        socket=*s;
        while(1){
            buf[0]='\0';
            length=read(socket,buf,1024);
            if(length==0)
                break;
            else if(length==-1){
                perror("Read");
                return;
            }
            else{
                printf("Request: %s\n",buf);
                send_response(socket);
            }       
        }
        printf("End of read thread [%d]\n",socket);
    }
    int start_accept(int port)
    {
        int socket,csocket;
        pthread_t thread;
        struct sockaddr_in client;
        socklen_t addrlen=sizeof(client);
        pthread_attr_t attr;
        socket=create_socket(port);
        while(1){
            if((csocket=accept(socket,(struct sockaddr *)&client,&addrlen))==-1)
            {   
                perror("Accept");
                break;
            }
            pthread_attr_init(&attr);
            if(0!=pthread_create(&thread,&attr,socket_read,&csocket))
            {
                perror("Read thread");
                return;
            }
            usleep(10000);
        }
    }
    void send_response(int socket)
    {
        char buf1[1024];
        int content_length;
        char buf2[1024]="<html><head><title></title></head><body>TIME : 1416824843 <br>DATE: Mon Nov 24 15:57:23 2014 </body></html>";
        content_length=strlen(buf2);
        sprintf(buf1,"HTTP/1.1 200 OK\r\nCache-Control : no-cache, private\r\nContent-Length : %d\r\nDate : Mon, 24 Nov 2014 12:03:43 GMT\r\n\r\n",content_length);
        printf("Written: %d \n",write(socket,buf1,strlen(buf1)));
        fflush(stdout);
        printf("Written: %d \n",write(socket,buf2,content_length));
        fflush(stdout);
    }