title: HTTP Server - Serving up favicon.ico
body: <p>I'm playing around setting up my own java http server to better understand http servers and what goes on under the hood of the web. I've developed a pretty simple server and have been able to serve both html pages as well as data in JSON form. Then I saw the browser (I'm using chrome but assuming it's the same for others) was sending a request for favicon.ico. I'm able to identify that request on my server, so I'm trying to serve up a random icon I downloaded and resized to 16x16 pixels in png format, as that's what the internet says the size needs to be. Here's my code, note it's not supposed to be anything professional, just something that will work for my basic educational purposes:</p>
  
  <pre><code>[set up ServerSocket and listen]
  public static String err_header = "HTTP/1.1 500 ERR\nAccess-Control-Allow-Origin: *";
  public static String success_header = "HTTP/1.1 200 OK\nAccess-Control-Allow-Origin: *";
  public static String end_header = "\r\n\r\n";
  while(true){
          try{
              System.out.println("Listening for new connections");
              clientSocket = server.accept();
              System.out.println("Connection established");
              InputStreamReader isr = new InputStreamReader(clientSocket.getInputStream());
              BufferedReader reader = new BufferedReader(isr);
              String getLine = reader.readLine();//first line of HTTP request
              handleRequest(getLine,clientSocket);
          }//end of try
          catch(Exception e){
              [error stuff]
          }//end of catch
      }//end of while
  </code></pre>
  
  <p>HandleRequest method:</p>
  
  <pre><code>public static void handleRequest(String getLine,Socket clientSocket) throws Exception{
      if(getLine.substring(5,16).equals("favicon.ico")){
          List&lt;String&gt; iconTag = new ArrayList&lt;String&gt;();
          iconTag.add("\nContent-Type: image/png");
          handleFileRequest("[file]",iconTag,clientSocket);
      }//end of if
      else{
          handleFileRequest("[file]",clientSocket);
      }//end of else
  }//end of handleRequest
  </code></pre>
  
  <p>handleFileRequest for images:</p>
  
  <pre><code>public static void handleFileRequest(String fileName,List&lt;String&gt; headerTags,Socket clientSocket) throws Exception{
      OutputStream out = clientSocket.getOutputStream();
      BufferedReader read = new BufferedReader(new FileReader(fileName));
      out.write(success_header.getBytes("UTF-8"));
      Iterator&lt;String&gt; itr = headerTags.iterator();
      while(itr.hasNext()){
          out.write(itr.next().getBytes("UTF-8"));
      }//end of while
      out.write(end_header.getBytes("UTF-8"));
      String readLine = "";
      while((readLine = read.readLine())!=null){
          out.write(readLine.getBytes("UTF-8"));
      }//end of while
      out.flush();
      out.close();
  }//end of handleFileRequest
  </code></pre>
  
  <p>And it appears to work, as the server sends the file, the browser shows the 200 OK response, but there's no favicon and when I filter network requests to just images, there is one image requested by the page being served but the favicon request is not listed there (the favicon request is in the "other" section). Similarly when clicking on the other image the image shows up on the preview, whereas that's not the case with the favicon request. Screenshot:</p>
  
  <p><img src="https://i.gyazo.com/bba75171537e89d23e24820536dd4008.png" alt="favicon"></p>
  
  <p>Meanwhile here's what the other image looks like, and it shows up in the page just fine:</p>
  
  <p><img src="https://i.gyazo.com/0d48aaa4c0f90372c5cbbca83f4426e4.png" alt="other image"></p>
  
  <p>I also tried including the Content-Length header, but that didn't seem to make a difference. Am I missing something obvious?</p>
  
  <p>Also just to clarify, I know I can include the favicon in the actual html page, the goal isn't to do it, but to understand how it works.</p>