title: Sending images over http to browser in C
body: <p>A am new to C and I am trying to implement a web server in C. I can successfully send .txt and .html files to the browser. However, I can't send any images, although I have correct content-type header which recognises that the image is .jpg. 
  Here is the function I use to find the content-type:</p>
  
  <pre><code>char *find_content_type (char *filename) {
      char *p;  // pointer to the type found
      int i;
      char buf1[MAXFILENAME]; // used to store the extension of the file
      char buf2[MAXFILENAME];
  
      p = (char *)malloc(30);
      strcpy(buf1, filename);
      printf("name of file requested: %s \n", buf1);
  
      /* find the extension: */
      for (i = 0; i&lt;strlen(buf1); i++) {
          if ( buf1[i] == '.' ) {
              strcpy(buf2, &amp;buf1[i]);
          }
      }
      /* find the type: */
      if ( strcmp(buf2, ".html") == 0 || strcmp (buf2, ".hml") == 0) {
          strcpy (buf2, "Content-Type: text/html \r\n");
      }
  
      else if ( strcmp(buf2, ".txt") == 0) {
          strcpy (buf2, "Content-Type: text/plain \r\n");
      }
  
      else if ( strcmp(buf2, ".jpg") == 0 || strcmp (buf2, ".jpeg") == 0) {
          strcpy (buf2, "Content-Type: image/jpeg \r\n");
      }
  
      else if ( strcmp(buf2, ".gif") == 0) {
          strcpy (buf2, "Content-Type: image/gif \r\n");
      }
  
      else {
          strcpy (buf2, "Content-Type: application/octet-stream \r\n");
      }
  
       p = buf2;
      printf ("content-type: %s\n", p);
      //return "Content-type: image/jpeg\r\n";
      return p;
  }
  </code></pre>
  
  <p>I have function which parses the request and returns a pointer to the name of the file requested. In main I only accept requests and write to the browser, all data parsing and response constructing is outside main. The function below forms the response which will be sent to the browser:</p>
  
  <pre><code>char * response_generator (char *filename) {
      char *p; // pointer to the whole response
      char *content_type; // pointer to the content type
      char data [MAXLEN], data2[MAXLEN - 100], data3 [MAXLEN - 200];
      /* vars needed for finding the length of the file */
      struct stat filestat;
      FILE *fp;
      int fd;
      off_t size;
      char filesize[6], name[30]; 
  
      strcpy (name, filename);
      if ( ((fd = open (filename, O_RDONLY)) &lt; -1) || (fstat(fd, &amp;filestat) &lt; 0) ) {
          printf ("Error in measuring the size of the file");
      }
      if (filename == NULL) {
          // I have measured the length of my 400.html file
          strcpy (data, "HTTP/1.1 400 Bad Request\r\nContent-Length: 327\r\nContent-Type: text/html\r\n");
          fp = fopen ("400index.html", "r");
      }
      sprintf (filesize, "%d", filestat.st_size); // put the file size of buffer, so we can add it to the response header
  
      fp = fopen (name, "r");
      if (fp == NULL || strcmp (name,"404") == 0 ) {
           // I have measured the length of my 404.html file
           strcpy (data, "HTTP/1.1 404 Not Found\r\nContent-Length: 165\r\nContent-Type: text/html\r\n");
          fp = fopen ("404index.html", "r");
      }
      else if (fp != NULL) {
          strcpy (data, "HTTP/1.1 200 OK\r\nContent-Length: ");
          /* content-length: */
          strcat (data, filesize);
          strcat (data, "\r\n");
          /* content-type: */
          strcpy (data2, find_content_type (name));
          printf ("content-type: %s\n", find_content_type (name));
          strcat (data, data2);
      }
  
      else {
          // I have measured the length of my 500.html file
          strcpy (data, "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 190\r\nContent-Type: text/html\r\n");
          fp = fopen ("500index.html", "r");
      }      
  
      strcat (data, "Connection: keep-alive\r\n\r\n");
      fread (data3, sizeof(char), filestat.st_size + 150, fp); /* read the file in a data buffer: */
      strcat (data, data3);
      data[strlen(data)] = '\0';
      p = data;
      fclose(fp);
      return p;
  }
  </code></pre>
  
  <p>It is pretty long and heavy function, but it seems to work fine apart when I have to send images, as I mentioned. When I print the request to be send on the terminal what I get is:</p>
  
  <pre><code> HTTP/1.1 200 OK
   Content-Length: 49657
   Content-Type: image/jpeg 
   Connection: keep-alive
  
   ÿØÿà
  </code></pre>
  
  <p>If you have any idea, please tell me what I am doing wrong. Thank you!</p>