0

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);
Frank
  • 30,590
  • 58
  • 161
  • 244
  • it's not exactly an http "server" as commonly understood. it's a library that you have to intercept every request and serve accordingly; it doesn't serve file for you automatically. – ZhongYu Aug 25 '15 at 15:27
  • So what do I need to do to let it serve images ? – Frank Aug 25 '15 at 15:54
  • Are you asking: How the `src` attribute of the `<ìmg>` tag needs to look for lokal files? Furthermore, why would you even consider absolute paths to local paths in html sites? – Micha Wiedenmann Aug 26 '15 at 16:54
  • @MichaWiedenmann : The reason I use absolute pass is the relative ones I tried didn't work, so I want to see if it's pointing definitely to an existing image, can it serve it ? It couldn't, so the point is, the problem is not in the relative path, it's the httpserver that is not serving an existing image. – Frank Aug 26 '15 at 23:55

1 Answers1

1

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

...

Frank
  • 30,590
  • 58
  • 161
  • 244