Frank
Frank

Reputation: 31096

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

Upvotes: 0

Views: 1129

Answers (1)

Frank
Frank

Reputation: 31096

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

...

Upvotes: 1

Related Questions