I have a programming assignment where I need to build a webserver which can handle GET and HEAD requests. My webserver is working as it should but since I'm still a newbie at Java I'm not sure about my structure or quality of my code so if you have some criticism/tips I would appreciate it.
Main:
package pytteweb;
import java.net.ServerSocket;
import java.net.Socket;
public class PyttewebMain {
public static void main(String[] args) {
int port = 8080;
if(args.length == 1){
try{
port = Integer.parseInt(args[0]);
}
catch (Exception e) {
System.err.print("Something went wrong..check your arguments \nUsage: pytteweb [port]\n");
System.exit(1);
}
}
else if(args.length > 1){
System.err.print("Usage: pytteweb [listening port]");
System.exit(1);
}
try{
ServerSocket listen = new ServerSocket(port);
System.out.print("Welcome to the pytteweb 1.0 web server..listening for connections on port " + port + "...\n");
while(true) {
Socket clientSocket = listen.accept();
System.out.println("\nNew connection from " + clientSocket.getInetAddress());
RequestHandler requestHandler = new RequestHandler(clientSocket);
Thread thread = new Thread(requestHandler);
thread.start();
}
}
catch (Exception e) {
System.err.print("Something went wrong.. port " + port + " already in use? \n");
e.printStackTrace();
System.exit(1);
}
}
}
RequestHandler
:
package pytteweb;
import java.net.Socket;
import java.util.StringTokenizer;
import java.io.*;
public class RequestHandler implements Runnable {
Socket clientSocket = null;
String[] requestLines = null;
String requestLine = "";
String httpMethod = "";
String httpVersion = "";
String fileName = "";
String status = "";
String END = "\r\n";
boolean badRequest = true;
public RequestHandler(Socket socket) throws Exception {
this.clientSocket = socket;
}
public void run(){
try {
processRequest();
}
catch (Exception e){
System.out.println("Error trying to process request..");
System.out.println(e);
e.printStackTrace();
}
}
/**
* Processes the request sent from the client. Reads and checks the request. Uses the Responder class to respond.
*
*
*/
private void processRequest() throws Exception {
System.out.println("\nReading request..\n");
requestLines = readRequest(clientSocket).split(System.getProperty("line.separator"));
requestLine = requestLines[0].toUpperCase();
for (String s: requestLines) {
System.out.println(s);
}
if(requestLine.startsWith("QUIT")){
System.exit(0);
}
StringTokenizer st = new StringTokenizer(requestLine);
if(requestLine.startsWith("GET") || requestLine.startsWith ("HEAD") && requestLine.endsWith("HTTP/1.0") || requestLine.endsWith("HTTP/1.1")){
badRequest = false;
if(st.countTokens() < 3){
badRequest = true;
}
}
if(!badRequest){
httpMethod = st.nextToken();
fileName = st.nextToken();
httpVersion=st.nextToken();
}
Responder r = new Responder(httpMethod,fileName,clientSocket,badRequest);
r.sendResponse();
clientSocket.close();
}
/**
* Reads the request.
*
* @param s - the socket to read from.
* @throws IOException
*/
private String readRequest(Socket s) throws IOException{
InputStream input = clientSocket.getInputStream();
int avaliable = 0;
String received = "";
while (!received.endsWith(END + END)) {
avaliable = input.available();
byte[] bytes = new byte[avaliable];
input.read(bytes);
received += new String(bytes);
}
return received.trim();
}
}
Responder
:
package pytteweb;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class Responder {
String status = null;
String contentType = null;
String fileName = null;
String httpMethod = "";
String END = "\r\n";
String contentLength = null;
DataOutputStream out = null;
File file = null;
FileInputStream fis = null;
boolean badRequest = false;
public Responder(String httpMethod, String fileName, Socket clientSocket, boolean badRequest){
this.httpMethod = httpMethod;
this.fileName = fileName;
this.badRequest = badRequest;
try {
this.out = new DataOutputStream(clientSocket.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* A method to send the correct response
* @throws Exception
*
*
*/
public void sendResponse() throws Exception{
if(badRequest){
System.out.println("\n400 Bad Request\n");
status = "HTTP/1.1 400 Bad Request" + END;
fileName = "ERROR400.HTML";
}
else if(!fileExists()){
System.out.println("\n404 Not Found: \n" + fileName + "Was not found on this server...");
status = "HTTP/1.1 404 Not Found" + END;
fileName = "ERROR404.HTML";
}
else if(fileExists() && !badRequest){
status = "HTTP/1.1 200 OK" + END;
}
file = new File(fileName);
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
contentType = "Content-type: " + getContentType(fileName) + END;
contentLength = "Content-Length: " + file.length() + END;
out.writeBytes(status);
out.writeBytes(contentType);
out.writeBytes(contentLength);
out.writeBytes(END);
if(httpMethod.equalsIgnoreCase("GET")){
sendBytes(fis, out);
}
fis.close();
out.close();
}
/**
* A method to check if a file exists and also reformats if needed
*
*
* @return True if the file exists and false if it does not.
*/
private boolean fileExists(){
if(fileName.endsWith("/")){
fileName+="INDEX.HTML";
}
if(fileName.startsWith("/")){
fileName = fileName.toUpperCase().substring(1);
}
//if(fileName.contains("favicon")){
// return false;
//}
File file = new File(fileName);
if(!file.exists()){
return false;
}
return true;
}
/**
* A method to check and return what kind of file is requested by the client.
*
* @param fileName specifies the filename to check.
* @return The file type of the file.
*/
private String getContentType(String fileName)
{
if(fileName.endsWith(".TXT")) {return "text/plain";}
if(fileName.endsWith(".HTM") || fileName.endsWith(".HTML")) {return "text/html";}
if(fileName.endsWith(".JPG") || fileName.endsWith(".JPEG")) {return "image/jpeg";}
if(fileName.endsWith(".PNG")) {return "image/png";}
if(fileName.endsWith(".GIF")) {return "image/gif";}
if(fileName.endsWith(".ICO")) {return "image/ico";}
return "application/octet-stream";
}
/**
* A method which buffers data from a fileinputstream and sends it to the outputstream.
*
* @param in - The FileInputStream to be read
* @param out - The OutPutStream to be written to
*/
private void sendBytes(FileInputStream in, OutputStream out) throws Exception{
byte[] buffer = new byte[1024];
int bytes = 0;
while((bytes = in.read(buffer)) != -1 )
{
out.write(buffer, 0, bytes);
}
}
}
enter code here
\$\endgroup\$