Trying to get an image to show up on an HTML file in a C web server

Viewed 30

I'm trying to get more familiar with C by writing a web server, and I managed to get a method to create HTTP headers for html files yesterday but I have been unable to get images within that html file to load.

Right now I generate my header by opening the html file, and creating a file stream to write the start of the header, the size of it, and then I loop through the file to send each character to the stream. I them send that stream as a char pointer back to the main method which sends it as a response over the socket.

I'm imagining that there is some more work I need to do here, but I haven't been able to find a good solution or anything too helpful to point me in the right direction of how exactly to get it to display. I appreciate any responses/insight.

test.html

<!DOCTYPE html>
<html>
<head>
    <title>Nick's test website</title>
</head>
<body>

<h1>Welcome to my website programmed from scratch in C</h1>
<p>I'm doing this project to practice C</p>

<table>
    <tr>
        <td>test1</td>
        <td>test2</td>
        <td>test2</td>
    </tr>
</table>

<img src="pic.jpg"/>

</body>
</html>

headermaker.c

char * headermaker(char * file_name){
    char ch;
    FILE * fp;
    fp = fopen(file_name, "r");


    if(fp == NULL){
        perror("Error while opening file.\n");
        exit(-1);
    }

    //print/save size of file
    fseek(fp, 0, SEEK_END);
    int size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    printf("File size is %d\n", size);


   //create filestream
    FILE * stream;
    char * buf;
    size_t len;
    stream = open_memstream(&buf, &len);

    //start header
    fprintf(stream, "HTTP/1.1 200 OK\\nDate: Sun, 28 Aug 2022 01:07:00 GMT\\nServer: Apache/2.2.14 (Win32)\\nLast-Modified: Sun, 28 Aug 2022 19:15:56 GMT\\nContent-Length: ");
    fprintf(stream, "%d\n", size);
    fprintf(stream, "Content-Type: text/html\n\n");


    //loop through each character
    while((ch = fgetc(fp)) != EOF)
        fprintf(stream, "%c", ch);

    fclose(stream);

    fclose(fp);
    return buf;
}
1 Answers

Using a modified version of provided code to setup a web server using netcat and needed to see explanation of how to send jpeg using netcat

./one | nc -l 45231 ; { ./two && cat pic.jpeg; }  | nc -l 45231;

Chrome browser can open http://localhost:45231 and will show the web page with an image. Also, can observe the network request - response sequence using "View->Developer->Developer Tools".

The code was built like this:

gcc -DONE -o one main.c && gcc -DTWO -o two main.c

The modified code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char * headermaker(char * file_name, char * content_type ){
    char ch;
    FILE * fp;
    fp = fopen(file_name, "r");


    if(fp == NULL){
        perror("Error while opening file.\n");
        exit(-1);
    }

    //print/save size of file
    fseek(fp, 0, SEEK_END);
    int size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    //printf("File size is %d\n", size);


   //create filestream
    FILE * stream;
    char * buf;
    size_t len;
    stream = open_memstream(&buf, &len);

    //start header
    fprintf(stream, "HTTP/1.1 200 OK\n");
    fprintf(stream, "Server: netcat!\n");
    fprintf(stream, "Content-Type: %s\n",content_type);
    fprintf(stream, "Content-Length: %d\n", size);
    fprintf(stream, "\n");


    //loop through each character
#ifdef ONE
    while((ch = fgetc(fp)) != EOF)
        fprintf(stream, "%c", ch);
#endif //#ifdef ONE

    fclose(stream);

    fclose(fp);
    return buf;
}

int main( )
{
  #ifdef ONE
  char *buf = headermaker( "test.html", "text/html" );
  printf( "%s", buf );
  free(buf);
  #endif //#ifdef ONE

  #ifdef TWO
  char *buf = headermaker( "pic.jpeg", "image/jpeg" );
  printf( "%s", buf );
  free(buf);
  #endif //#ifdef TWO

  return 0;
}

Another helpful debug tool was curl:

curl -vvv localhost:45231 > page.html
curl -vvv localhost:45231 > image.jpeg
Related