Search code examples
javaimagecom.sun.net.httpserver

With com.sun.net.httpserver, why image is not showing up in Java generated html page?


I'm using com.sun.net.httpserver to serve html pages, text content shows up correctly, but I can't get it to serve images, here is how my code looks like :

  static String Test(int Font_Size,String First_Name,String Last_Name)
  {
    String Pic_File="C:/Dir_Resume_App/Dir_Resume_Picture/Hi_Test.jpg";
    String Resume="<Table><Tr><Td><H2>First_Name Last_Name</H2></Td></Tr><Tr><Td><Img Src=\"file://"+Pic_File+"\" alt=Hi_Test width=268 height=201><br>"+(Pic_File+" : exists = "+new File(Pic_File).exists())+"</Td></Tr></Table>\n";
    ...
    return Resume;
  }

And here is the result :

enter image description here

As you can see from the result, the image file exists, but somehow the path "file://C:/Dir_Resume_App/Dir_Resume_Picture/Hi_Test.jpg" can't lead it to display the image.

I've also tried the relative paths, like "Dir_Resume_Picture/Hi_Test.jpg", "/Dir_Resume_Picture/Hi_Test.jpg", "../Dir_Resume_Picture/Hi_Test.jpg", "../../Dir_Resume_Picture/Hi_Test.jpg" and "Dir_Resume_App/Dir_Resume_Picture/Hi_Test.jpg", none of them works, has someone successfully served images with com.sun.net.httpserver ?

I suspect I could have missed something in the http header, such as telling it how to serve image instead of just plain text, could that be the reason ? Right now it looks like this :

    InetSocketAddress  addr=new InetSocketAddress(Port);
    HttpServer  server=HttpServer.create(addr,0);
    server.createContext("/"+App_Id,new MyHandler(server));
...

class MyHandler implements HttpHandler
{
  HttpServer server;

  public MyHandler(HttpServer server) { this.server=server; }

  public void handle(HttpExchange exchange)
  {
    OutputStream responseBody=exchange.getResponseBody();
    String requestMethod=exchange.getRequestMethod(),requestPath=exchange.getRequestURI().getPath(),line,title="Match Skillsets",
           responseString="<Html>\n<Head>\n  <Title>"+title+"</Title>\n  </Head>\n<Body>\n<Center>\n";
    BufferedReader in=new BufferedReader(new InputStreamReader(exchange.getRequestBody()));
    LinkedHashMap<String,String> params=queryToMap(exchange.getRequestURI().getQuery());

    try
    {
      if (requestMethod.equalsIgnoreCase("GET"))
      {
        Headers responseHeaders=exchange.getResponseHeaders();
//      responseHeaders.set("Content-Type","text/plain");
        responseHeaders.set("Content-Type","text/html;charset=utf-8");
        exchange.sendResponseHeaders(200,0);

Solution

  • I found out how to make it work :

      public void handle(HttpExchange exchange)
      {
        OutputStream responseBody=exchange.getResponseBody();
        String requestMethod=exchange.getRequestMethod(),requestPath=exchange.getRequestURI().getPath(),title="Page title",root="",
               responseString="<Html>\n<Head>\n  <Title>"+title+"</Title>\n </Head>\n<Body>\n<Center>\n";
        LinkedHashMap<String,String> params=queryToMap(exchange.getRequestURI().getRawQuery());
        File file;
    
        try
        {
          URI uri=exchange.getRequestURI();
          if (params.get("Img")!=null) file=new File(URLDecoder.decode(params.get("Img"),"utf-8")).getCanonicalFile();
          else file=new File(root+uri.getPath()).getCanonicalFile();
    
          if (!file.getPath().startsWith(root))
          {
            // Suspected path traversal attack: reject with 403 error.
            responseString+="403 (Forbidden)\n";
            responseString+="\n</Center>\n</Body>\n</Html>";
            exchange.sendResponseHeaders(403,0);
            responseBody.write(responseString.getBytes());
          }
          else if (!file.isFile())
          {
            Headers responseHeaders=exchange.getResponseHeaders();
            responseHeaders.set("Content-Type","text/html;charset=utf-8");
            exchange.sendResponseHeaders(200,0);
    
            responseString+=Get_Content()+"<P>\n";
            // Object does not exist or is not a file: reject with 404 error.
            responseString+="\n</Center>\n</Body>\n</Html>";
            responseBody.write(responseString.getBytes());
          }
          else
          {
            // Object exists and is a file: accept with response code 200.
            exchange.sendResponseHeaders(200,0);
            FileInputStream fs=new FileInputStream(file);
            final byte[] buffer=new byte[0x10000];
            int count;
            while ((count=fs.read(buffer))>=0) responseBody.write(buffer,0,count);
            fs.close();
          }
        }
        catch (Exception e)
        {
          responseString+="<P><Pre>"+e.toString()+"</Pre>\n";
          e.printStackTrace();
        }
        finally
        {
          try
          {
            responseBody.close();
            if (Id.equals("Stop_Server")) server.stop(0);
          }
          catch (Exception ex)
          {
            ex.printStackTrace();
          }
        }
      }
    
      public LinkedHashMap<String,String> queryToMap(String query)                 // http://localhost:6600/Resume_App?Id=Edit&File_Name=AT&T.txt
      {
    //    Out("query = "+query);
        LinkedHashMap<String,String> result=new LinkedHashMap();
        for (String param : query.split("&"))
        {
          String pair[]=param.split("=");
          if (pair.length>1) result.put(pair[0],pair[1]);
          else result.put(pair[0],"");
        }
        return result;
      }
    

    ...