I am trying to display images inside my HTTP Web Server but I'm unable to. I can display the HTML. I think it is something to do with the way I handle my IO (input and output streams). There's probably a lot of mistakes in there that I haven't noticed.
import java.io.* ;
import java.net.* ;
import java.util.Properties;
public class HTTPThread extends Thread
{
private Socket socket = null;
private Properties config = null;
private String root = "";
public HTTPThread(Socket s, Properties config)
{
this.socket = s;
this.config = config;
this.root = this.config.getProperty("root");
}
public void run()
{
// InputStream in = null;
OutputStream out = null;
try
{
out = socket.getOutputStream();
PrintWriter writer = new PrintWriter(out, true);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String request = reader.readLine();
writer.println("HTTP/1.1 200 OK");
writer.println("Content-Type: text/html");
writer.println();
// Search for filename
int slash = request.indexOf("/"); //find first occurrence of slash
int emptySpace = request.indexOf(" ", slash); //find first space after slash
String filename = request.substring(slash, emptySpace); //return filename
// writer.println("<b>" + filename + "</b>");
String pathname = "";
try
{
pathname = (filename == "/") ? root + filename : root;
// System.out.println(filename);
URL url = new URL(pathname);
URLConnection urlc = url.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
urlc.getInputStream()));
String line;
while ((line = in.readLine()) != null)
{
writer.println(line);
}
in.close();
}
catch (MalformedURLException e)
{
System.err.println("Don't know about host: " + pathname);
System.exit(1);
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for "
+ "the connection to: " + pathname);
System.exit(1);
}
// reader.close();
writer.close();
socket.close();
}
catch(IOException e)
{
System.out.println("Error: " + e);
}
finally
{
try
{
// in.close() ;
out.close() ;
socket.close();
}
catch(IOException e)
{
System.out.println("Error: " + e);
}
}
}
}
Are you trying to write some sort of proxy server that takes external URL from the request and returns the contents? Well, there are several issues with your code:
writer.println("HTTP/1.1 200 OK");
writer.println("Content-Type: text/html");
When browser sees the above, it assumes whatever is returned is HTML. Rendering binary image as HTML will clearly fail. Which leads us to this:
String line;
while ((line = in.readLine()) != null)
{
writer.println(line);
}
in.close();
In the loop above you are reading some external URL line-by-line (in text mode) and forwarding it to original client. This works for HTML (which is text-based) but will fail for any image (binary). You must use InputStream
/OutputStream
instead.
And small thing at the end:
pathname = (filename == "/") ? root + filename : root;
Do not compare strings using ==
operator, replace it with:
pathname = (filename.equals("/")) ? root + filename : root;
As a final note, consider using servlet container like Tomcat or Jetty, which will release you from HTTP-handling code and provide more high-level constructs.