Geesh_SO
Geesh_SO

Reputation: 2206

How do I send an image over HTTP protocol in C?

I'm a student doing a web server exercise and I need a bit of help.

I have my web server working fine for text pages but whenever the brower sends a ---GET /img.jpg HTTP/1.1 request, I don't know how to handle it. I've heard the HTTP protocol is text based, so how do I send an image in my HTTP response?

Here is a segment where I create my normal HTTP response, I plan to use readresult == 2 to signal an image.

if(readresult == 1){
    sprintf(toreturn, "%s\r\n%s\r\n%s\r\n\r\n%s", "HTTP/1.1 200 OK", "Content-Type: text/html", "Connection: close", readpagestring);
    returnflag = 1;
}
else if(readresult == 2){
    returnflag = 2;
}
else{
    sprintf(toreturn, "%s\r\n%s\r\n%s\r\n\r\n%s", "HTTP/1.1 404 Not Found", "Content-Type: text/html", "Connection: close", readpagestring);
    returnflag = 0;
}

And the function it calls

int readpage(char *readaddress, char *pagereturn){
    FILE *inputfile = (FILE *)calloc(1,sizeof(FILE));
    int flag;
    int c;
    int n = 0;
    readaddress++;
    inputfile=fopen(readaddress,"r");
    if (inputfile==NULL){
        FILE *missingfile;
        missingfile=fopen("404.html","r");
        while ((c = fgetc (missingfile)) != EOF){
            *(pagereturn+n) = c;
            n++;
        }
        flag = 0;
        fclose (missingfile);
    }
    else{
        while ((c = fgetc (inputfile)) != EOF){
            *(pagereturn+n) = c;
            n++;
        }
        flag = 1;
        fclose (inputfile);
    }
    return flag;
}

Upvotes: 6

Views: 31028

Answers (3)

Shaowen Zhu
Shaowen Zhu

Reputation: 105

Like Davide Berra has said you need to do this below:

HTTP/1.1 200 OK\r\n
Content-Type: image/gif\r\n
Content-Length: [length in bytes of the image]\r\n
\r\n
[binary data of your image]

So you need to get the length of your image file. And there are some functions would help:

size_t file_size(const char* file_path) {
    FILE* fin = fopen(file_path, "rb");
    if (fin == NULL) {
        printf("open %s failed.", file_path);
        exit(0);
    }

    fseek(fin, 0L, SEEK_END);
    size_t size = ftell(fin);
    fclose(fin);
    return size;
}
void read_file(unsigned char* buffer, size_t size, const char* file_path) {
    FILE* fin = fopen(file_path, "rb");  // r for read, b for binary
    if (fin == NULL) {
        printf("open %s failed.", file_path);
        return;
    }

    fread(buffer, sizeof(unsigned char), size, fin); // read sizeof(buffer) elements to our buffer
}

Upvotes: 1

Davide Berra
Davide Berra

Reputation: 6568

You have to return a HTTP response like this: (very minimal, you can add all the headers you need anyway)

HTTP/1.1 200 OK\r\n
Content-Type: image/gif\r\n
Content-Length: [length in bytes of the image]\r\n
\r\n
[binary data of your image]

Obviously you also have to set the content type accordingly to the type of your image.

You can build the headers with a sprintf, then memcpy the binary data of the image just after the last \r\n

Ensure that toreturn buffer is large enough.

Upvotes: 15

Sjoerd
Sjoerd

Reputation: 75578

The image data is sent to the client. It is not converted to text or anything. If you use the correct content-type, your example probably already works for images.

Upvotes: 1

Related Questions