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

1.1k Views Asked by At

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);
1

There are 1 best solutions below

0
On BEST ANSWER

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;
  }

...