Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
}
like image 326
Geesh_SO Avatar asked Feb 06 '13 11:02

Geesh_SO


3 Answers

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.

like image 132
Davide Berra Avatar answered Nov 19 '22 11:11

Davide Berra


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.

like image 41
Sjoerd Avatar answered Nov 19 '22 10:11

Sjoerd


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
}
like image 1
Shaowen Zhu Avatar answered Nov 19 '22 10:11

Shaowen Zhu