HttpRequest in Java: Always goes to 404 - java

I wrote this HttpRequest method, but for some reason it always goes to 404 Not Found, even though the file location exists when the java process isn't running.
import java.io.*;
import java.net.*;
import java.util.*;
final class HttpRequest implements Runnable {
final static String CRLF = "\r\n";
Socket socket;
// Constructor
public HttpRequest(Socket socket) throws Exception {
this.socket = socket;
}
// Implement the run() method of the Runnable interface.
public void run() {
try {
processRequest();
} catch (Exception e) {
System.out.println(e);
}
}
private static void sendBytes(FileInputStream fis, OutputStream os)
throws Exception {
// Construct a 1K buffer to hold bytes on their way to the socket.
byte[] buffer = new byte[1024];
int bytes = 0;
// Copy requested file into the socket's output stream.
while((bytes = fis.read(buffer)) != -1 ) {
os.write(buffer, 0, bytes);
}
}
private static String contentType(String fileName) {
if(fileName.endsWith(".htm") || fileName.endsWith(".html")) {
return "text/html";
}
if(fileName.endsWith(".jpeg") || fileName.endsWith(".jpg")) {
return "image/jpeg";
}
if(fileName.endsWith(".gif")) {
return "image/gif";
}
return "application/octet-stream";
}
private void processRequest() throws Exception {
// Get a reference to the socket's input and output streams.
InputStream is = socket.getInputStream();
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
// Set up input stream filters.
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// Get the request line of the HTTP request message.
String requestLine = new String(br.readLine());
// Display the request line.
System.out.println();
System.out.println(requestLine);
// Get and display the header lines.
String headerLine = null;
while ((headerLine = br.readLine()).length() != 0) {
System.out.println(headerLine);
}
// Extract the filename from the request line.
StringTokenizer tokens = new StringTokenizer(requestLine);
tokens.nextToken(); // skip over the method, which should be "GET"
String fileName = tokens.nextToken();
// Prepend a "." so that file request is within the current directory.
fileName = "." + fileName;
// Open the requested file.
FileInputStream fis = null;
boolean fileExists = true;
try {
fis = new FileInputStream(fileName);
} catch (FileNotFoundException e) {
fileExists = false;
}
// Construct the response message.
String statusLine = null;
String contentTypeLine = null;
String entityBody = null;
if (fileExists) {
statusLine = "200 OK" + CRLF;
contentTypeLine = "Content-type: " +
contentType( fileName ) + CRLF;
} else {
statusLine = "404 NOT FOUND" + CRLF;
contentTypeLine = "Content Not Found!" + CRLF;
entityBody = "<HTML>" +
"<HEAD><TITLE>Not Found</TITLE></HEAD>" +
"<BODY>Not Found</BODY></HTML>";
}
// Send the status line.
os.writeBytes(statusLine);
// Send the content type line.
os.writeBytes(contentTypeLine);
// Send a blank line to indicate the end of the header lines.
os.writeBytes(CRLF);
// Send the entity body.
if (fileExists) {
sendBytes(fis, os);
fis.close();
} else {
os.writeBytes("File DNE: Content Not Found!");
}
// Close streams and socket.
os.close();
br.close();
socket.close();
}
}
Any help would be greatly appreciated...I feel like it's something simple I'm missing.

I ran your code; it works fine (except for some minor issues with not printing the headers correctly, which every browser I've tried is willing to completely ignore).
Are you sure your working directory is where you expect? Try changing the 404 message to something like:
contentTypeLine = "Content Not Found: " + new File(fileName).getAbsolutePath() + CRLF;
For reference, I ran it with a test harness of:
public static void main(String[] args) throws Exception {
final ServerSocket ss = new ServerSocket(8080);
while (true)
new HttpRequest(ss.accept()).run();
}

Related

Http webserver array out of bounds error

i've been working on a simple HTTP web server in java. however i seem to be running into an issue where when i try to get the file name in the request i get an array out of bounds error even though its not out of bounds and i can clearly see it in the array. can anyone help code is below
public static void main(String[]args) throws Exception{
ServerSocket ss = new ServerSocket(8080);
while(true){
Socket s= ss.accept();
String ip = s.getInetAddress().toString();
ConnectionHandler ch = new ConnectionHandler(s);
ch.start();
System.out.println(ip);
}
public class ConnectionHandler extends Thread{
private Socket s;
private PrintWriter pw;
private BufferedReader br;
public ConnectionHandler(Socket s) throws Exception{
this.s = s;
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
pw = new PrintWriter(s.getOutputStream());
}
#Override
public void run(){
String reqs = "";
try {
while(br.ready()){
reqs += (char) br.read();
//System.out.println(reqs);
HttpRequest hr = new HttpRequest(reqs);
HttpResponse res = new HttpResponse(hr);
pw.write(res.response.toCharArray());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
pw.close();
try {
br.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class HttpRequest {
String fileName;
public HttpRequest(String reqs){
String lines[] = reqs.split("\n");
//System.out.println(lines[0]);
String lines1[] = lines[0].split(" ");
for(int i = 0;i<lines1.length;i++){
System.out.println(i + lines1[i]);
}
fileName = lines1[1]; //error is here
}
}
public class HttpResponse {
private HttpRequest req;
String response;
private String root="H:/root";
private FileInputStream fis;
private File f;
public HttpResponse(HttpRequest hr) throws Exception {
req = hr;
if(req.fileName == null){
f = new File("H:/root/helloworld.html");
fis = new FileInputStream(f);
}else{
f = new File(root + req.fileName);
fis = new FileInputStream(f);
}
response = "HTTP/1.1 200";
response += "content-type: text/html \r\n";
response += "Connection: close \r\n";
response += "content-length: " + f.length() + "\r\n";
response += "\r\n";
int s;
while((s=fis.read())!=-1){
response += (char) s;
}
fis.close();
}
}
The problem is that:
reqs += (char) br.read();
only reads a single char from the input and after each read character you try to parse the request.
So you will end up in a situation where you only have "G" in reqs which would cause lines1 to be of length 1. lines1[1] would try to access the second element in that array, which doesn't exist.
Try moving the parsing of the request outside of the loop.
[EDIT] Better formatting support in the answers. This works as intended for me.
while (br.ready()) {
reqs += (char) br.read();
}
HttpRequest hr = new HttpRequest(reqs);
HttpResponse res = new HttpResponse(hr);
pw.write(res.response.toCharArray());

error in my java code for a web server

I keep getting these error and i have no clue why. I've been working on this for over 4 hours and i still cant fix this error. i honestly don't know what i'm doing wrong here.
WebServer.java:84: error: class, interface, or enum expected
StringTokenizer tokens = new StringTokenizer(requestLine);
^
WebServer.java:85: error: class, interface, or enum expected
tokens.nextToken(); // skip over the method, which should be "GET"
^
WebServer.java:86: error: class, interface, or enum expected
String fileName = tokens.nextToken();
^
WebServer.java:89: error: class, interface, or enum expected
fileName = "." + fileName;
^
WebServer.java:92: error: class, interface, or enum expected
FileInputStream fis = null;
^
WebServer.java:93: error: class, interface, or enum expected
boolean fileExists = true;
^
WebServer.java:94: error: class, interface, or enum expected
try {
^
WebServer.java:96: error: class, interface, or enum expected
} catch (FileNotFoundException e) {
^
WebServer.java:98: error: class, interface, or enum expected
}
^
WebServer.java:102: error: class, interface, or enum expected
String contentTypeLine = null;
^
WebServer.java:103: error: class, interface, or enum expected
String entityBody = null;
^
WebServer.java:104: error: class, interface, or enum expected
if (fileExists) {
^
WebServer.java:106: error: class, interface, or enum expected
contentTypeLine = "Content-type: " + contentType( fileName ) + CRL
^
WebServer.java:107: error: class, interface, or enum expected
}
^
WebServer.java:110: error: class, interface, or enum expected
contentTypeLine = "Content-type: " + "text/html" + CRLF;
^
WebServer.java:111: error: class, interface, or enum expected
entityBody = "<HTML>" +
^
WebServer.java:114: error: class, interface, or enum expected
}
^
WebServer.java:119: error: class, interface, or enum expected
os.writeBytes(contentTypeLine);
^
WebServer.java:121: error: class, interface, or enum expected
os.writeBytes(CRLF);
^
WebServer.java:123: error: class, interface, or enum expected
if (fileExists) {
^
WebServer.java:125: error: class, interface, or enum expected
fis.close();
^
WebServer.java:126: error: class, interface, or enum expected
}
^
WebServer.java:129: error: class, interface, or enum expected
}
^
WebServer.java:136: error: class, interface, or enum expected
int bytes = 0;
^
WebServer.java:138: error: class, interface, or enum expected
while((bytes = fis.read(buffer)) != -1 ) {
^
WebServer.java:140: error: class, interface, or enum expected
}
^
WebServer.java:147: error: class, interface, or enum expected
}
^
WebServer.java:150: error: class, interface, or enum expected
}
^
WebServer.java:153: error: class, interface, or enum expected
}
^
WebServer.java:156: error: class, interface, or enum expected
}
^
WebServer.java:159: error: class, interface, or enum expected
}
^
WebServer.java:161: error: class, interface, or enum expected
}
^
32 errors
here is source code
import java.io.* ;
import java.net.* ;
import java.util.* ;
public final class WebServer{
public static void main(String argv[]) throws Exception
{
// Set the port number.
int port = 6789;
// Establish the listen socket.
ServerSocket listenSocket = new ServerSocket(port);
//Process HTTP service requests in an infinite loop
while (true) {
// Listen for a TCP connection request
Socket connectionSocket = listenSocket.accept();
// Construct an object to process the HTTP request message
HttpRequest request = new HttpRequest(connectionSocket);
// Create a new thread to process the request.
Thread thread = new Thread(request);
// Start the thread.
thread.start();
}
}
}
final class HttpRequest implements Runnable
{
final static String CRLF = "\r\n";
Socket socket;
// Constructor
public HttpRequest(Socket socket) throws Exception
{
this.socket = socket;
}
// Implement the run() method of the Runnable interface.
public void run()
{
try
{
processRequest();
}
catch (Exception e)
{
System.out.println(e);
}
}
private void processRequest() throws Exception
{
// Get a reference to the socket's input and output streams.
InputStream is = socket.getInputStream();
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
// Set up input stream filters.
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//Get the request line of the HTTP request message.
String requestLine = br.readLine();
// Display the request line.
System.out.println();
System.out.println(requestLine);
// Get and display the header lines.
String headerLine = null;
while ((headerLine = br.readLine()).length() != 0) {
System.out.println(headerLine);
}
// Close streams and socket.
os.close();
br.close();
socket.close();
}
}
// Extract the filename from the request line.
StringTokenizer tokens = new StringTokenizer(requestLine);
tokens.nextToken(); // skip over the method, which should be "GET"
String fileName = tokens.nextToken();
// Prepend a "." so that file request is within the current directory.
fileName = "." + fileName;
// Open the requested file.
FileInputStream fis = null;
boolean fileExists = true;
try {
fis = new FileInputStream(fileName);
} catch (FileNotFoundException e) {
fileExists = false;
}
// Construct the response message.
String statusLine = null;
String contentTypeLine = null;
String entityBody = null;
if (fileExists) {
statusLine = "HTTP/1.0 200 OK" + CRLF;
contentTypeLine = "Content-type: " + contentType( fileName ) + CRLF;
}
else {
statusLine = "HTTP/1.0 404 Not Found" + CRLF;
contentTypeLine = "Content-type: " + "text/html" + CRLF;
entityBody = "<HTML>" +
"<HEAD><TITLE>Not Found</TITLE></HEAD>" +
"<BODY>Not Found</BODY></HTML>";
}
// Send the status line.
os.writeBytes(statusLine);
// Send the content type line.
os.writeBytes(contentTypeLine);
// Send a blank line to indicate the end of the header lines.
os.writeBytes(CRLF);
// Send the entity body.
if (fileExists) {
sendBytes(fis, os);
fis.close();
}
else {
os.writeBytes(entityBody);
}
private static void sendBytes(FileInputStream fis, OutputStream os)
throws Exception
{
// Construct a 1K buffer to hold bytes on their way to the socket.
byte[] buffer = new byte[1024];
int bytes = 0;
// Copy requested file into the socket's output stream.
while((bytes = fis.read(buffer)) != -1 ) {
os.write(buffer, 0, bytes);
}
}
private static String contentType(String fileName)
{
if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
return "text/html";
}
if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
return "image/jpeg";
}
if (fileName.endsWith(".gif")) {
return "image/gif";
}
if (fileName.endsWith(".txt")) {
return "text/plain";
}
if (fileName.endsWith(".pdf")) {
return "application/pdf";
}
return "application/octet-stream";
}
can someone please help me under what is wrong with my code. I would greatly appreciate the help.
can someone please help me under what is wrong with my code.
Starting from the comment line
// Extract the filename from the request line.
you have a bunch of statements, and then method declarations that are not inside any class. That is not legal Java.
If they are supposed to be inside a class (e.g. your HttpRequest class or WebServer class) then you have probably made a mistake with opening / closing brackets further up the file.
If not ... then you misunderstand Java. All executable code in Java must be declared inside a class (or interface or enum).
You are misplacing some braces.
import java.io.*;
import java.net.*;
import java.util.*;
public final class WebServer {
public static void main(String argv[]) throws Exception {
// Set the port number.
int port = 6789;
// Establish the listen socket.
ServerSocket listenSocket = new ServerSocket(port);
// Process HTTP service requests in an infinite loop
while (true) {
// Listen for a TCP connection request
Socket connectionSocket = listenSocket.accept();
// Construct an object to process the HTTP request message
HttpRequest request = new HttpRequest(connectionSocket);
// Create a new thread to process the request.
Thread thread = new Thread(request);
// Start the thread.
thread.start();
}
}
}
final class HttpRequest implements Runnable {
final static String CRLF = "\r\n";
Socket socket;
// Constructor
public HttpRequest(Socket socket) throws Exception {
this.socket = socket;
}
// Implement the run() method of the Runnable interface.
public void run() {
try {
processRequest();
} catch (Exception e) {
System.out.println(e);
}
}
private void processRequest() throws Exception {
// Get a reference to the socket's input and output streams.
InputStream is = socket.getInputStream();
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
// Set up input stream filters.
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// Get the request line of the HTTP request message.
String requestLine = br.readLine();
// Display the request line.
System.out.println();
System.out.println(requestLine);
// Get and display the header lines.
String headerLine = null;
while ((headerLine = br.readLine()).length() != 0) {
System.out.println(headerLine);
}
// Close streams and socket.
os.close();
br.close();
socket.close();
// } // *** DELETED
// } // *** DELETED
// Extract the filename from the request line.
StringTokenizer tokens = new StringTokenizer(requestLine);
tokens.nextToken(); // skip over the method, which should be "GET"
String fileName = tokens.nextToken();
// Prepend a "." so that file request is within the current directory.
fileName = "." + fileName;
// Open the requested file.
FileInputStream fis = null;
boolean fileExists = true;
try {
fis = new FileInputStream(fileName);
} catch (FileNotFoundException e) {
fileExists = false;
}
// Construct the response message.
String statusLine = null;
String contentTypeLine = null;
String entityBody = null;
if (fileExists) {
statusLine = "HTTP/1.0 200 OK" + CRLF;
contentTypeLine = "Content-type: " + contentType(fileName) + CRLF;
} else {
statusLine = "HTTP/1.0 404 Not Found" + CRLF;
contentTypeLine = "Content-type: " + "text/html" + CRLF;
entityBody = "<HTML>" +
"<HEAD><TITLE>Not Found</TITLE></HEAD>" +
"<BODY>Not Found</BODY></HTML>";
}
// Send the status line.
os.writeBytes(statusLine);
// Send the content type line.
os.writeBytes(contentTypeLine);
// Send a blank line to indicate the end of the header lines.
os.writeBytes(CRLF);
// Send the entity body.
if (fileExists) {
sendBytes(fis, os);
fis.close();
} else {
os.writeBytes(entityBody);
}
} // *** INSERTED
private static void sendBytes(FileInputStream fis, OutputStream os)
throws Exception {
// Construct a 1K buffer to hold bytes on their way to the socket.
byte[] buffer = new byte[1024];
int bytes = 0;
// Copy requested file into the socket's output stream.
while ((bytes = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytes);
}
}
private static String contentType(String fileName) {
if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
return "text/html";
}
if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
return "image/jpeg";
}
if (fileName.endsWith(".gif")) {
return "image/gif";
}
if (fileName.endsWith(".txt")) {
return "text/plain";
}
if (fileName.endsWith(".pdf")) {
return "application/pdf";
}
return "application/octet-stream";
}
} // *** INSERTED

map file directory from a java server to local machine

I have created a java server application which will take GET requests and return files to the browser. Also the files are downloaded to the directory using "content-disposition:attachment" in header.But this only downloads as files, I want to download as a folder and map it to a local directory. for example
localhost:8080/xyz.jpg gives u an image .But localhost:8080/src/xyz.jpg should be downlaoded as src folder with an image in it eg: downloads/src/xyz.jpg. Currently if i do that ,it downloads as just a file. Since you guys asked.Here is the example code i used :) .thanks
import java.io.*;
import java.net.*;
import java.util.*;
public class myHTTPServer extends Thread {
static final String HTML_START =
"<html>" +
"<title>HTTP Server in java</title>" +
"<body>";
static final String HTML_END =
"</body>" +
"</html>";
Socket connectedClient = null;
BufferedReader inFromClient = null;
DataOutputStream outToClient = null;
public myHTTPServer(Socket client) {
connectedClient = client;
}
public void run() {
try {
System.out.println( "The Client "+
connectedClient.getInetAddress() + ":" + connectedClient.getPort() + " is connected");
inFromClient = new BufferedReader(new InputStreamReader (connectedClient.getInputStream()));
outToClient = new DataOutputStream(connectedClient.getOutputStream());
String requestString = inFromClient.readLine();
String headerLine = requestString;
StringTokenizer tokenizer = new StringTokenizer(headerLine);
String httpMethod = tokenizer.nextToken();
String httpQueryString = tokenizer.nextToken();
StringBuffer responseBuffer = new StringBuffer();
responseBuffer.append("<b> This is the HTTP Server Home Page.... </b><BR>");
responseBuffer.append("The HTTP Client request is ....<BR>");
System.out.println("The HTTP request string is ....");
while (inFromClient.ready())
{
// Read the HTTP complete HTTP Query
responseBuffer.append(requestString + "<BR>");
System.out.println(requestString);
requestString = inFromClient.readLine();
}
if (httpMethod.equals("GET")) {
if (httpQueryString.equals("/")) {
// The default home page
sendResponse(200, responseBuffer.toString(), false);
} else {
//This is interpreted as a file name
String fileName = httpQueryString.replaceFirst("/", "");
fileName = URLDecoder.decode(fileName);
if (new File(fileName).isFile()){
sendResponse(200, fileName, true);
}
else {
sendResponse(404, "<b>The Requested resource not found ...." +
"Usage: http://127.0.0.1:5000 or http://127.0.0.1:5000/</b>", false);
}
}
}
else sendResponse(404, "<b>The Requested resource not found ...." +
"Usage: http://127.0.0.1:5000 or http://127.0.0.1:5000/</b>", false);
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendResponse (int statusCode, String responseString, boolean isFile) throws Exception {
String statusLine = null;
String serverdetails = "Server: Java HTTPServer";
String contentLengthLine = null;
String fileName = null;
String contentTypeLine = "Content-Type: text/html" + "\r\n";
String Content_disposition="Content-Disposition: attachment; filename='src/fname.ext'";
FileInputStream fin = null;
if (statusCode == 200)
statusLine = "HTTP/1.1 200 OK" + "\r\n";
else
statusLine = "HTTP/1.1 404 Not Found" + "\r\n";
if (isFile) {
fileName = responseString;
fin = new FileInputStream(fileName);
contentLengthLine = "Content-Length: " + Integer.toString(fin.available()) + "\r\n";
if (!fileName.endsWith(".htm") && !fileName.endsWith(".html"))
contentTypeLine = "Content-Type: \r\n";
}
else {
responseString = myHTTPServer.HTML_START + responseString + myHTTPServer.HTML_END;
contentLengthLine = "Content-Length: " + responseString.length() + "\r\n";
}
outToClient.writeBytes(statusLine);
outToClient.writeBytes(serverdetails);
outToClient.writeBytes(contentTypeLine);
outToClient.writeBytes(contentLengthLine);
outToClient.writeBytes(Content_disposition);
outToClient.writeBytes("Connection: close\r\n");
outToClient.writeBytes("\r\n");
if (isFile) sendFile(fin, outToClient);
else outToClient.writeBytes(responseString);
outToClient.close();
}
public void sendFile (FileInputStream fin, DataOutputStream out) throws Exception {
byte[] buffer = new byte[1024] ;
int bytesRead;
while ((bytesRead = fin.read(buffer)) != -1 ) {
out.write(buffer, 0, bytesRead);
}
fin.close();
}
public static void main (String args[]) throws Exception {
ServerSocket Server = new ServerSocket (5000, 10, InetAddress.getByName("127.0.0.1"));
System.out.println ("TCPServer Waiting for client on port 5000");
while(true) {
Socket connected = Server.accept();
(new myHTTPServer(connected)).start();
}
}
}
You can't do this using the HTTP protocol and a normal browser, there is no MIME type for folders. Your browser is able to download only files.
If you want to do this through HTTP:
Option 1: Generate a "zip" file (or some other format that enables you to package a folder tree into a single file) which contains the folder tree and send that to the browser.
Option 2: Develop a custom client program that is able to interpret the response that it gets from the server and create the corresponding folders on the local filesystem.

Java TCP Simple Webserver Problems with response codes (homework)

This is an assignment for a course we are having and i need some help.
I am having problems for example, trying to request a file that does not exist, it works that a 404 file not found page comes up, but when i look in the web tool for Safari i can see that the response code is 200, OK, which is definialty wrong, it should be the code that is the error.
But why i don't see, i send the error code header when a error occurs, but it´still doesn't work. Can somebody point me at the right direction or maybe just say what the problem is and i can fix it :D ?
Main:
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
public class WebServer {
private static int PORT = 8888;
private static String ROOT_DIR = "";
public static void main(String[] args) {
if (isCorrect(args) == true) {
boolean isRunning = true;
try {
/* Creates a new server socket */
ServerSocket serverSocket = new ServerSocket();
/* Binds the port to the server */
SocketAddress localBindPoint = new InetSocketAddress(PORT);
serverSocket.bind(localBindPoint);
System.out.println("==============================================" +
"\n| HTTP Web Server |" +
"\n===================" +
"\n| Configuration: " +
"\n| Directory: " +
"\n| " + ROOT_DIR +
"\n| Port: " +
"\n| " + PORT +
"\n| Usage: <directory> <port>" +
"\n| ctrl-c to exit" +
"\n==============================================");
/* The server is running */
while (isRunning) {
try {
/* Accept connection by client */
Socket socket = serverSocket.accept();
/* Each connected client gets a new thread */
new Thread(new RequestHandler(socket, ROOT_DIR)).start();
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
} catch (IOException e) {
System.err.println("Address already in use!" +
"\nClose running connection or choose other port");
}
} else
usageMsg();
System.exit(1);
}
public static boolean isDirectory(String path){
File filePath = null;
try{
filePath = new File(path);
/* False if file is not a directory */
if (!filePath.isDirectory())
return false;
}
catch (Exception e){
System.err.println(e.getMessage());
}
/* Seems to be a file path */
return true;
}
public static boolean isCorrect(String[] args){
if (args.length != 2){
usageMsg();
return false;
}
try{
ROOT_DIR = args[0].toString();
PORT = Integer.parseInt(args[1]);
}
catch (NumberFormatException n){
System.err.println(n.getMessage());
}
if (!isDirectory(ROOT_DIR)){
usageMsg();
return false;
}
return true;
}
public static void usageMsg(){
System.err.println("Invalid arguments"+
"\nUsage: java -jar Webserver.jar <directory> <port>");
}
}
RequestHandler:
import java.io.*;
import java.net.Socket;
import java.util.StringTokenizer;
/**
* Web Server Request Handler.
* Created on 2015-02-16.
*/
public class RequestHandler implements Runnable {
/*
TODO ( ) Problem 1
TODO ( ) Problem 2
TODO ( ) Problem 3
TODO (X) Index page for first page.
TODO (X) Read and download images & other files
TODO ( ) Fix header responses
TODO ( ) Error responses
*/
private String
OK = "HTTP/1.0 200 OK",
NOT_FOUND = "HTTP/1.0 404 Not Found",
BAD_REQUEST = "HTTP/1.0 400 Bad Request",
FORBIDDEN = "HTTP/1.0 403 Forbidden",
SERVER_ERROR = "HTTP/1.0 500 Internal Server Error";
private String ROOT_DIR;
private Socket client;
private PrintStream send;
private DataInputStream fromClient;
private DataOutputStream out;
RequestHandler(Socket client, String ROOT_DIR) {
this.client = client;
this.ROOT_DIR = ROOT_DIR;
try {
send = new PrintStream(client.getOutputStream());
fromClient = new DataInputStream(client.getInputStream());
out = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
/* Reads the HTTP request and responds */
public void run() {
String request = null;
String fileName = null;
StringTokenizer tok = null;
try {
/* Read HTTP request from client */
while ((request = fromClient.readLine()) != null) {
System.out.println(request);
tok = new StringTokenizer(request);
/* Extracts the file path from the GET command */
if (tok.hasMoreElements() && tok.nextToken().equals("GET")
&& tok.hasMoreElements()) {
fileName = tok.nextToken();
} else
throw new FileNotFoundException();
/* */
if (fileName.endsWith("/"))
fileName += "index.html";
/* Illegal characters, prevent access to super directories */
if (fileName.indexOf("..") >= 0 || fileName.indexOf('|') >= 0
|| fileName.indexOf(':') >= 0 || fileName.indexOf('~') >= 0) {
error(FORBIDDEN, "Forbidden Access", fileName);
}
else
if (new File(fileName).isDirectory()) {
fileName = fileName.replace('\\', '/');
send.close();
return;
}
/* File name is ROOT_DIR + file name */
fileName = ROOT_DIR + fileName;
/* Create file */
File file = new File(fileName);
if (file.isDirectory()) {
fileName = fileName + "index.html";
}
/* File does not exist */
if (file.exists()){
/* Determines the MIME type of the file */
String mimeType = getMimeType(file);
/* Sends the file */
sendFile(file, mimeType, fileName);
client.close();
}
else
error(NOT_FOUND, "404 File Not Found", fileName);
}
}
catch (FileNotFoundException e) {
System.err.println(e.getMessage());
}
catch (IOException e){
System.err.println(e.getMessage());
}
}
/* Sends the requested file to the client */
public void sendFile(File file, String fileType, String fileName) {
try {
// Buffer must not be to low, => fragments
int length = (int) file.length();
FileInputStream fileIn = new FileInputStream(fileName);
byte[] bytes = new byte[length];
/* Write until bytes is empty */
while ((length = fileIn.read(bytes)) != -1 ){
out.write(bytes, 0, length);
out.flush();
out.writeBytes(OK);
out.writeBytes("Server: Jakobs Web Server v1.0");
out.writeBytes("Content-Type: " + fileType + "\r\n");
out.writeBytes("Content-Length: " + length + "\r\n");
out.writeBytes("");
}
send.close();
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
/* Sends the header response to the client */
public void sendHeaderResponse(String code, String fileType){
try {
out.writeBytes(code);
out.writeBytes("Server: Jakobs Web Server v1.0");
out.writeBytes("Content-Type: " + fileType + "\r\n");
out.writeBytes("");
}
catch (IOException e){
System.err.println(e.getMessage());
}
}
/* Sends error response to the client */
public void error(String code, String error, String fileName){
System.err.println(error +
"\nFile Requested: " + fileName);
/* Sends the error code header */
sendHeaderResponse(code, fileName);
/* Sends the error message and cause to client */
send.print("<html><head><title>" + error + "</title></head><body>");
send.print("<h1>" + error + "</h1>\r\n");
send.println("Location: /" + fileName + "/\r\n");
send.println("Exception Cause: " + error + "\r\n");
send.print("Start Page");
send.print("</body>\"</html>");
send.flush();
send.close();
}
/* Finds out the MIME type of the requested file */
public String getMimeType(File f) {
String file = f.toString();
String type = "";
if (file.endsWith(".txt")) {
type = "text/txt";
} else if (file.endsWith(".html") || file.endsWith("htm")) {
type = "text/html";
} else if (file.endsWith(".jpg")) {
type = "image/jpg";
} else if (file.endsWith(".png")) {
type = "image/png";
} else if (file.endsWith(".jpeg")) {
type = "image/jpeg";
} else if (file.endsWith(".gif")) {
type = "image/gif";
} else if (file.endsWith(".pdf")) {
type = "application/pdf";
} else if (file.endsWith(".mp3")) {
type = "audio/mpeg";
} else if (file.endsWith(".class")){
type = "application/octet-stream";
} else if (file.endsWith(".mp4")){
type = "video/mp4";
}
return type;
}
}
Make sure that you write e.g. HTTP/1.1 404 Not Found to the client, not just the 400.
Actually no, your problem is that you don't end the response properly. The browser keeps receiving data and shows no response code received. Let me see how this can be fixed in your code.
Also, you use two wrapper streams around client.getOutputStream() to send data to the client (send and out). Not sure why you do this. This looks weird. You should use just one wrapper stream. And you never close out, probably that's your problem, that's why the browser thinks the response is not yet fully received. Try to use one stream and handle it properly.
OK, here is your code fixed.
import java.io.*;
import java.net.Socket;
import java.util.StringTokenizer;
/**
* Web Server Request Handler.
* Created on 2015-02-16.
*/
public class RequestHandler implements Runnable {
/*
TODO ( ) Problem 1
TODO ( ) Problem 2
TODO ( ) Problem 3
TODO (X) Index page for first page.
TODO (X) Read and download images & other files
TODO ( ) Fix header responses
TODO ( ) Error responses
*/
private String
OK = "HTTP/1.0 200 OK",
NOT_FOUND = "HTTP/1.0 404 Not Found",
BAD_REQUEST = "HTTP/1.0 400 Bad Request",
FORBIDDEN = "HTTP/1.0 403 Forbidden",
SERVER_ERROR = "HTTP/1.0 500 Internal Server Error";
private String ROOT_DIR;
private Socket client;
private PrintStream send;
private DataInputStream fromClient;
// private DataOutputStream out;
RequestHandler(Socket client, String ROOT_DIR) {
this.client = client;
this.ROOT_DIR = ROOT_DIR;
try {
send = new PrintStream(client.getOutputStream());
fromClient = new DataInputStream(client.getInputStream());
// out = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
/* Reads the HTTP request and responds */
public void run() {
String request = null;
String fileName = null;
StringTokenizer tok = null;
try {
/* Read HTTP request from client */
while ((request = fromClient.readLine()) != null) {
System.out.println(request);
tok = new StringTokenizer(request);
/* Extracts the file path from the GET command */
if (tok.hasMoreElements() && tok.nextToken().equals("GET")
&& tok.hasMoreElements()) {
fileName = tok.nextToken();
} else
throw new FileNotFoundException();
/* */
if (fileName.endsWith("/"))
fileName += "index.html";
/* Illegal characters, prevent access to super directories */
if (fileName.indexOf("..") >= 0 || fileName.indexOf('|') >= 0
|| fileName.indexOf(':') >= 0 || fileName.indexOf('~') >= 0) {
error(FORBIDDEN, "Forbidden Access", fileName);
}
else
if (new File(fileName).isDirectory()) {
fileName = fileName.replace('\\', '/');
send.close();
return;
}
/* File name is ROOT_DIR + file name */
fileName = ROOT_DIR + fileName;
/* Create file */
File file = new File(fileName);
if (file.isDirectory()) {
fileName = fileName + "index.html";
}
/* File does not exist */
if (file.exists()){
/* Determines the MIME type of the file */
String mimeType = getMimeType(file);
/* Sends the file */
sendFile(file, mimeType, fileName);
client.close();
}
else
error(NOT_FOUND, "404 File Not Found", fileName);
}
}
catch (FileNotFoundException e) {
System.err.println(e.getMessage());
}
catch (IOException e){
System.err.println(e.getMessage());
}
}
/* Sends the requested file to the client */
public void sendFile(File file, String fileType, String fileName) {
try {
// Buffer must not be to low, => fragments
int length = 0; // (int) file.length();
FileInputStream fileIn = new FileInputStream(fileName);
byte[] bytes = new byte[1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
/* Write until bytes is empty */
while ((length = fileIn.read(bytes)) != -1 ){
bos.write(bytes, 0, length);
// send.write(bytes, 0, length);
// send.flush();
}
bos.flush();
bos.close();
byte[] data1 = bos.toByteArray();
System.out.print(new String(data1));
send.print(OK);
send.print("");
send.print("Server: Jakobs Web Server v1.0");
send.print("Content-Type: " + fileType + "\r\n");
send.print("Content-Length: " + data1.length + "\r\n");
send.println("");
send.write(data1, 0, data1.length);
send.println("");
send.flush();
send.close();
fileIn.close();
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
/* Sends the header response to the client */
public void sendHeaderResponse(String code, String fileType){
try {
send.print(code);
send.print("Server: Jakobs Web Server v1.0");
send.print("Content-Type: " + fileType + "\r\n");
send.print("");
send.println();
}
catch (Exception e){
System.err.println(e.getMessage());
}
}
/* Sends error response to the client */
public void error(String code, String error, String fileName){
System.err.println(error +
"\nFile Requested: " + fileName);
/* Sends the error code header */
sendHeaderResponse(code, fileName);
// send.println("ERROR");
/* Sends the error message and cause to client */
send.print("<html><head><title>" + error + "</title></head><body>");
send.print("<h1>" + error + "</h1>\r\n");
send.println("Location: /" + fileName + "/\r\n");
send.println("Exception Cause: " + error + "\r\n");
send.print("Start Page");
send.print("</body></html>");
send.flush();
send.close();
}
/* Finds out the MIME type of the requested file */
public String getMimeType(File f) {
String file = f.toString();
String type = "";
if (file.endsWith(".txt")) {
type = "text/txt";
} else if (file.endsWith(".html") || file.endsWith("htm")) {
type = "text/html";
} else if (file.endsWith(".jpg")) {
type = "image/jpg";
} else if (file.endsWith(".png")) {
type = "image/png";
} else if (file.endsWith(".jpeg")) {
type = "image/jpeg";
} else if (file.endsWith(".gif")) {
type = "image/gif";
} else if (file.endsWith(".pdf")) {
type = "application/pdf";
} else if (file.endsWith(".mp3")) {
type = "audio/mpeg";
} else if (file.endsWith(".class")){
type = "application/octet-stream";
} else if (file.endsWith(".mp4")){
type = "video/mp4";
}
return type;
}
}

Java Server: Socket sending HTML code to browser

I am trying to write a simple Java program using ServerSockets that will send some HTML code to the browser. Here is my code:
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(55555);
} catch (IOException e) {
System.err.println("Could not listen on port: 55555.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
if(clientSocket != null) {
System.out.println("Connected");
}
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
out.println("HTTP/1.1 200 OK");
out.println("Content-Type: text/html");
out.println("\r\n");
out.println("<p> Hello world </p>");
out.flush();
out.close();
clientSocket.close();
serverSocket.close();
I then go to localhost:55555 in my browser and nothing displays. I know the connection is working because the program outputs "Connected" as checked in the if statement. I have also tried outputting the data from the inputStream and that works. But the text I am trying to output in the browser is not displaying at all, the program finishes running and I get a
"Problem loading page - the connection has been reset"
in my browser, but no text.
I have searched the internet and it seems everyone else coding it this way is having their text display fine, they are having other problems.
How can I fix this?
I tested your code in Chrome, Firefox, IE, and Opera and it works.
However, I would suggest that you use multi-threading and essentially spawn a new thread to handle each new request.
You can create a class that implements runnable and takes a clientSocket within the constructor. This will essentially make your custom webserver capable of accepting more than one request concurrently.
You will also need a while loop if you want to handle more than one total requests.
A good read demonstrating the above: https://web.archive.org/web/20130525092305/http://www.prasannatech.net/2008/10/simple-http-server-java.html
If the web-archive is not working, I'm posting the code below (taken from above):
/*
* myHTTPServer.java
* Author: S.Prasanna
* #version 1.00
*/
import java.io.*;
import java.net.*;
import java.util.*;
public class myHTTPServer extends Thread {
static final String HTML_START =
"<html>" +
"<title>HTTP Server in java</title>" +
"<body>";
static final String HTML_END =
"</body>" +
"</html>";
Socket connectedClient = null;
BufferedReader inFromClient = null;
DataOutputStream outToClient = null;
public myHTTPServer(Socket client) {
connectedClient = client;
}
public void run() {
try {
System.out.println( "The Client "+
connectedClient.getInetAddress() + ":" + connectedClient.getPort() + " is connected");
inFromClient = new BufferedReader(new InputStreamReader (connectedClient.getInputStream()));
outToClient = new DataOutputStream(connectedClient.getOutputStream());
String requestString = inFromClient.readLine();
String headerLine = requestString;
StringTokenizer tokenizer = new StringTokenizer(headerLine);
String httpMethod = tokenizer.nextToken();
String httpQueryString = tokenizer.nextToken();
StringBuffer responseBuffer = new StringBuffer();
responseBuffer.append("<b> This is the HTTP Server Home Page.... </b><BR>");
responseBuffer.append("The HTTP Client request is ....<BR>");
System.out.println("The HTTP request string is ....");
while (inFromClient.ready())
{
// Read the HTTP complete HTTP Query
responseBuffer.append(requestString + "<BR>");
System.out.println(requestString);
requestString = inFromClient.readLine();
}
if (httpMethod.equals("GET")) {
if (httpQueryString.equals("/")) {
// The default home page
sendResponse(200, responseBuffer.toString(), false);
} else {
//This is interpreted as a file name
String fileName = httpQueryString.replaceFirst("/", "");
fileName = URLDecoder.decode(fileName);
if (new File(fileName).isFile()){
sendResponse(200, fileName, true);
}
else {
sendResponse(404, "<b>The Requested resource not found ...." +
"Usage: http://127.0.0.1:5000 or http://127.0.0.1:5000/</b>", false);
}
}
}
else sendResponse(404, "<b>The Requested resource not found ...." +
"Usage: http://127.0.0.1:5000 or http://127.0.0.1:5000/</b>", false);
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendResponse (int statusCode, String responseString, boolean isFile) throws Exception {
String statusLine = null;
String serverdetails = "Server: Java HTTPServer";
String contentLengthLine = null;
String fileName = null;
String contentTypeLine = "Content-Type: text/html" + "\r\n";
FileInputStream fin = null;
if (statusCode == 200)
statusLine = "HTTP/1.1 200 OK" + "\r\n";
else
statusLine = "HTTP/1.1 404 Not Found" + "\r\n";
if (isFile) {
fileName = responseString;
fin = new FileInputStream(fileName);
contentLengthLine = "Content-Length: " + Integer.toString(fin.available()) + "\r\n";
if (!fileName.endsWith(".htm") && !fileName.endsWith(".html"))
contentTypeLine = "Content-Type: \r\n";
}
else {
responseString = myHTTPServer.HTML_START + responseString + myHTTPServer.HTML_END;
contentLengthLine = "Content-Length: " + responseString.length() + "\r\n";
}
outToClient.writeBytes(statusLine);
outToClient.writeBytes(serverdetails);
outToClient.writeBytes(contentTypeLine);
outToClient.writeBytes(contentLengthLine);
outToClient.writeBytes("Connection: close\r\n");
outToClient.writeBytes("\r\n");
if (isFile) sendFile(fin, outToClient);
else outToClient.writeBytes(responseString);
outToClient.close();
}
public void sendFile (FileInputStream fin, DataOutputStream out) throws Exception {
byte[] buffer = new byte[1024] ;
int bytesRead;
while ((bytesRead = fin.read(buffer)) != -1 ) {
out.write(buffer, 0, bytesRead);
}
fin.close();
}
public static void main (String args[]) throws Exception {
ServerSocket Server = new ServerSocket (5000, 10, InetAddress.getByName("127.0.0.1"));
System.out.println ("TCPServer Waiting for client on port 5000");
while(true) {
Socket connected = Server.accept();
(new myHTTPServer(connected)).start();
}
}
}
Enjoy!
You need to need to set the PrintWriter to autoflush when it prints.
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
should be
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
The line terminator in HTTP is \r\n. This means that you shouldn't use println(), you should use print() and add an explicit \r\n yourself to each line.
The result of an HTTP GET is supposed to be an HTML document, not a fragment. Browsers are entitled to ignore or complain. Send this:
<html>
<head/>
<body>
<p> Hello world </p>
</body>
</html>
in my computer, at least to get the socket's inputStream:
clientSocket.getInputStream();
with out this line, sometimes chrome doesn't work
you need read the input from socket first
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = "";
while((line = bufferedReader.readLine()) != null){
System.out.println(line);
if(line.isEmpty())
break;
}
You should accept the request sent by client(browser in this case),to do that just add the following lines:
Buffered reader in = new Buffered reader(new InputStreamReader(client_socket.getInputStream()));
Note: you need to replace the "client_socket" part with name of your own socket for the client.
Why we need to accept browser request?
It's because if we don't accept the request browser doesn't get any acknowledgement from the server that the request that was sent is received,hence it thinks the server is not reachable any more.
My code:
public class Help {
public static void main(String args) throws IOException{
ServerSocket servsock new serverSocket(80)
Socket cs servsock, accept();
Printwriter out new Printwriter(Cs.getoutputstream), true)
BufferedReader in new BufferedReader(new InputStreamReader(cs.getInputStream());
out.println("<html> <body> <p>My first StackOverflow answer </p> </body> </html>");
out.close();
servsock.close();
}
}
You need to send
"HTTP/1.1 200 OK" first. followed by a newline
then "Content-Type: text/html; charset: UTF-8" followed by 2 newlines.
then send the HTML source for it to display as a styled webpage and not just a text output.
I used OutputStreamWriter
OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream());
osw.write("HTTP/1.1 200 OK\nContent-Type: text/html; charset=UTF-8\n\n");
osw.write("<html><head><title>Hello World</title></head><body></body><p>Hello World</p></body></html>");
Not sending "HTTP/1.1 200 OK" first results in source code being displayed without html parsing..
And to avoid "Connection being reset" error, you need to close your socket. Very Important !!
The whole code:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class WebServer
{
ServerSocket serverSocket;
Socket socket;
FileReader fr;
OutputStreamWriter osw;
WebServer() throws IOException
{
serverSocket = new ServerSocket(8080);
socket = serverSocket.accept();
fr = new FileReader("index.html");
osw = new OutputStreamWriter(socket.getOutputStream());
osw.write("HTTP/1.1 200 OK\nContent-Type: text/html; charset=UTF-8\n\n");
int c;
char[] ch = new char[4096];
while ((c = fr.read(ch)) != -1)
{
osw.write(ch, 0, c);
}
osw.close();
socket.close();
}
public static void main(String[] args) throws IOException
{
new WebServer();
}
}

Categories