Reputation: 1937
I'm making a simple http server. So far socket works for html files, now I'm trying to make work images.
This is how I read files:
char * fbuffer = 0;
long length;
FILE *f;
if ((f = fopen(file, "r")) == NULL)
{
perror("Error opening file");
exit(1);
}
fseek (f, 0, SEEK_END);
length = ftell(f);
fseek (f, 0, SEEK_SET);
fbuffer = malloc(length);
int total = 0;
if (fbuffer)
{
while (total != length)
{
total += fread(fbuffer, 1, length, f);
}
}
fclose (f);
Then I just send data to socket:
char response[20048];
snprintf(response, sizeof(response), "HTTP/1.1 200 OK\nContent-Type: %s\nContent-Length: %i\n\n%s", type, (int) strlen(fbuffer), fbuffer);
n = send(newsockfd, response, strlen(response)+1, 0);
Why it doesn't work for images? Browser is showing an error The image “http://127.0.0.1:1050/image.gif” cannot be displayed because it contains errors.
Http response is:
Content-Length: 7
Content-Type: image/gif
The image has 247 bytes. In variables length and total are values 247. Variable fbuffer contains GIF89a(+one char -> some binary square with values 0 0 1 0).
What am I doing wrong?
Thanks.
Upvotes: 1
Views: 3103
Reputation: 225087
The issue here is that fbuffer
contains binary data, but you're attempting to treat is as a string by using functions like strlen
and using the %s
format specifier to print it.
Since binary data may contain a null byte, this prevents string functions from working on them since they use a null byte to mark the end of a string.
You should instead use functions like memcpy
to put data into your output buffer.
char response[20048];
int hlen;
hlen = snprintf(response, sizeof(response),
"HTTP/1.1 200 OK\nContent-Type: %s\nContent-Length: %d\n\n", type, length);
memcpy(response + hlen, fbuffer, length);
n = send(newsockfd, response, hlen + length, 0);
Upvotes: 2
Reputation: 123541
A string in C ends with the \0
character. It is likely that the binary representation of your image contains this character somewhere inside the data. This means any use if %s
, strlen(..)
etc will simply stop at the \0
character and thus cannot be used for binary data.
Upvotes: 2