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;
}
}
Related
I'm trying to save image in FTP server. But it giving error like java.io.IOException: FTP error: 553 Could not create file.
I call the method
upload("xxx.xx.2.36","ftpuser","xxxxxpos",imageFile,"ftp://ftpuser#xxx.xx.2.36/Item/");
public static void check(FTPClient ftp, String cmd, boolean succeeded) throws IOException {
if (!succeeded) {
throw new IOException("FTP error: " + ftp.getReplyString());
}
}
/**
*
* #return
*/
private static String today() {
return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
}
public static void upload(String server, String username, String Password,
File imageFile, String destDir) {
FTPClient ftp = new FTPClient();
try {
ftp.connect(server);
check(ftp, "login", ftp.login(username, Password));
System.out.println("Connected to " + server + ".");
InputStream input = new FileInputStream(imageFile);
try {
String destination = destDir;
if (destination.endsWith("/")) {
destination += today()+"-"+imageFile.getName();
System.out.println("direc" +destination);
}
check(ftp, "store", ftp.storeFile(destination, input));
System.out.println("Stored " + imageFile + " to " + destination + ".");
} finally {
input.close();
}
check(ftp, "logout", ftp.logout());
}catch(Exception e){
e.printStackTrace();
}
finally {
try {
ftp.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
After ftp.storeFile(destination, input) it giving error
Please help to solve this.
i'm new to java programming and am using Apache commons net ftp to upload text files to my ftp server.
however, it seems that i can only upload the files on the same directory as my program .. when i set the file path to something like that : "C:\Users\Packard\Documents\ProjectsJava\FugeLessons\outputFile.txt" , it throws no errors, but when i check the ftp, there is nothing, like it has not been uploaded .
here is the code i'm using :
import org.apache.commons.net.ftp.FTPClient;
import java.io.FileInputStream;
import java.io.IOException;
public class ftp{
private final String host = "ftp.address.com";
private final String user = "user";
private final String pass = "pass";
public static void main(String[] args) {
ftp client = new ftp();
client.FtpUpload("C:\\Users\\Packard\\Documents\\ProjectsJava\\FugeLessons\\outputFile.txt");
}
public String FtpUpload(String filename){
FTPClient client = new FTPClient();
FileInputStream fis = null;
try {
client.connect(this.host);
client.login(this.user, this.pass);
fis = new FileInputStream(filename);
client.storeFile(filename, fis);
client.logout();
System.out.println("File " + filename + "\t uploaded successfully!");
} catch(IOException e){
error error = new error();
error.setVisible(true);
e.printStackTrace();
} finally {
try {
if ( fis != null) {
fis.close();
}
client.disconnect();
} catch(IOException e){
e.printStackTrace();
}
}
String ret = "success";
return ret;
}
}
what am i doing wrong ?
Thanks for your help!
You can use ftpClient method getReplyString() to get the error message. Below code can help.
boolean isSendSucces = ftpClient.storeFile(fileName, input );
if( isSendSuccess )
{
System.out.println("Sent File: " + fileName);
}
else
{
System.out.println("Problem is sending File: " + ftpClient.getReplyString());
}
I have a piece of software which establishes a communication between a PC and a machine, which used to work in Java 1.6, but doesn't anymore in 1.7. The IOException --> "Invalid Http response" is what I get as soon as the getInputStream() method is called. It seems like the method had been improved an is much more sensitive, meaning that responseCode=
-1 result is not specifically checked in Java 1.6.
Assited with Wireshark I checked if both versions (1.6 & 1.7) sent and received same Ethernet frames, and so did both.
I can only resolve this from the PC (client) side...that means no posibility to edit or change the Server code.
I would apreciate any help on how to modify or implement something new to make the code compatible for ver. 1.7 as Im not a former programmer... Thanks
Sequence:
get is called
return readResponse(..) is called
getInputStream() --> IOException
catch (Exception e) {System.out.println("error sending get request " + getURL() + " string: " + requestString); return Error.ethernetException; //TODO
here the console output:
-1
error sending get request ... string: *APPLETCOMMINFO_
strResponse: Ethernet Exception
and the Code:
private String get(String requestString)/* throws ComunicationException*/ {
HttpURLConnection httpURLConnection = null;
OutputStream out = null;
try {
String encodedRequestString = URLEncoder.encode(requestString, "iso-8859-1");
String path = getURL().getPath();
if (!path.endsWith("/")) path = path + "/";
path = path + encodedRequestString;
URL fullURL = new URL(getURL().getProtocol(), getURL().getHost(), getURL().getPort(), path);
httpURLConnection = (HttpURLConnection)fullURL.openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setDoOutput(false);
httpURLConnection.setDoInput(true);
httpURLConnection.setUseCaches(false);
// Set timeout at 5s
httpURLConnection.setConnectTimeout(m_nTimeOut);
httpURLConnection.setReadTimeout(m_nTimeOut);
return readResponse(httpURLConnection);
} catch (Exception e) {
System.out.println("error sending get request " + getURL() + " string: " + requestString);
return Error.ethernetException; //TODO
} finally {
if (out != null) {
try {
out.close();
} catch (Throwable t) {
System.out.println("GET: out.close(), Class: Client");
}
}
if (httpURLConnection != null) {
try {
httpURLConnection.disconnect();
} catch (Throwable t) {
System.out.println("GET: httpURLConnection.disconnect(), Class: Client");
}
}
}
}
/**
* Reads the response from the server into a string.
* The content length header must be set!
* #param connection
* #return
* #throws IOException
*/
private String readResponse(HttpURLConnection connection) throws IOException {
if (connection == null) throw new IllegalStateException("connection must not be null");
connection.connect();
int status = connection.getResponseCode();
System.out.println(status);
// InputStream aaa = connection.getInputStream();
Reader reader = null;
try {
reader = new InputStreamReader(connection.getInputStream(), "iso-8859-1");
int readBufferSize = connection.getContentLength();
if (readBufferSize < 0) {
// use default buffer size
readBufferSize = DEFAULT_READ_BUFFER_SIZE;
}
// if content length was set, read will be done in a single
// iteration because buffer fits...
StringBuffer response = new StringBuffer();
char[] readBuffer = new char[readBufferSize];
int len;
while ((len = reader.read(readBuffer)) > 0) {
response.append(new String(readBuffer, 0, len));
}
return response.toString();
} catch (IOException ioe) {
throw ioe;
} finally {
if (reader != null) {
try {
reader.close();
} catch (Throwable t) {
System.out.println("readResponse: reader.close(), Class: Client");
//log
}
}
}
}
/**
*
* #return the url
*/
public URL getURL() {
return url;
}
}
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();
}
I have an assignment to write a proxy server. Simple tests work, but when I configure firefox to use the proxy, the response input stream is never ready. Can you help?
ProxyServer (the important method)
public void start() {
while (true) {
Socket serverSocket;
Socket clientSocket;
BufferedWriter toClient;
BufferedWriter toServer;
try {
//The client is meant to put data on the port, read the socket.
clientSocket = listeningSocket.accept();
Request request = new Request(clientSocket.getInputStream());
System.out.println("Accepted a request!\n" + request);
while(request.busy);
//Make a connection to a real proxy.
//Host & Port - should be read from the request
URL url = null;
try {
url = new URL(request.getRequestURL());
} catch (MalformedURLException e){
url = new URL("http:\\"+request.getRequestHost()+request.getRequestURL());
}
//remove entry from cache if needed
if (!request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
cache.remove(request);
}
Response response = null;
if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
response = cache.get(request);
} else {
//Get the response from the destination
int remotePort = (url.getPort() == -1) ? 80 : url.getPort();
System.out.println("I am going to try to connect to: " + url.getHost() + " at port " + remotePort);
serverSocket = new Socket(url.getHost(), remotePort);
System.out.println("Connected.");
//write to the server - keep it open.
System.out.println("Writing to the server's buffer...");
toServer = new BufferedWriter(new OutputStreamWriter(serverSocket.getOutputStream()));
toServer.write(request.getFullRequest());
toServer.flush();
System.out.println("flushed.");
System.out.println("Getting a response...");
response = new Response(serverSocket.getInputStream());
System.out.println("Got a response!\n" + response);
//wait for the response
while(response.isBusy());
}
if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE)) {
cache.put(request, response);
}
response = filter.filter(response);
// Return the response to the client
toClient = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
toClient.write(response.getFullResponse());
toClient.flush();
toClient.close();
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
The Response and Request classes are just very simple parsers for HTTP requests/responses. When I try to load a website through the proxy, I get:
EDIT 2
Here's another attempt. I added a debug print just before the line toClient.write(response.getFullResponse());
Accepted a request!
Request
==============================
GET http://t2.technion.ac.il/~srachum/ HTTP/1.1
Host: t2.technion.ac.il
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:2.0) Gecko/20100101 Firefox/4.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Proxy-Connection: keep-alive
I am going to try to connect to: t2.technion.ac.il at port 80
Connected.
Writing to the server's buffer...
flushed.
Getting a response...
Got a response!
Response
==============================
HTTP/1.1 200 OK
Date: Sat, 23 Apr 2011 15:54:08 GMT
Server: Apache/2.0.52 (Red Hat)
Last-Modified: Fri, 18 Mar 2011 23:45:24 GMT
ETag: "14928fc-877-49eca5f29cd00"
Accept-Ranges: bytes
Content-Length: 2167
Connection: close
Content-Type: text/html
X-Pad: avoid browser bug
<html>
...
</html>
I am going to write the following response:
HTTP/1.1 200 OK
Date: Sat, 23 Apr 2011 15:54:08 GMT
Server: Apache/2.0.52 (Red Hat)
Last-Modified: Fri, 18 Mar 2011 23:45:24 GMT
ETag: "14928fc-877-49eca5f29cd00"
Accept-Ranges: bytes
Content-Length: 2167
Connection: close
Content-Type: text/html
X-Pad: avoid browser bug
<html>
...
</html>
EDIT 3:
Request
package cs236369.proxy;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import cs236369.proxy.types.CacheControl;
import cs236369.proxy.types.HttpPatterns;
import cs236369.proxy.types.RequestHeader;
import cs236369.proxy.types.RequestType;
public class Request {
private String fullRequest = "";
private BufferedReader reader;
private RequestHeader requestHeader;
private String requestHost;
boolean busy = true;
private CacheControl cacheControl = CacheControl.CACHE;
public CacheControl getCacheControl() {
return cacheControl;
}
Request(String request) {
this(new ByteArrayInputStream(request.getBytes()));
}
Request(InputStream input){
reader = new BufferedReader(new InputStreamReader(input));
try {
while(!reader.ready()); //wait for initialization.
String line;
while ((line = reader.readLine()) != null) {
fullRequest += "\r\n" + line;
if (HttpPatterns.CACHE_CONTROL.matches(line)) {
cacheControl = (CacheControl) HttpPatterns.RESPONSE_CODE.process(line);
} else if (HttpPatterns.REQUEST_HEADER.matches(line)) {
requestHeader = (RequestHeader) HttpPatterns.REQUEST_HEADER.process(line);
} else if (HttpPatterns.HOST.matches(line)) {
requestHost = (String) HttpPatterns.HOST.process(line);
}
}
fullRequest = "\r\n" + fullRequest.trim() + "\r\n\r\n";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
busy = false;
}
public String getFullRequest() {
return fullRequest;
}
public RequestType getRequestType() {
return requestHeader.type;
}
public String getRequestURL() {
return requestHeader.url;
}
public String getRequestProtocol() {
return requestHeader.protocol;
}
public String getRequestHost() {
return requestHost;
}
public boolean isBusy() {
return busy;
}
#Override
public String toString() {
return "Request\n==============================\n" + fullRequest;
}
}
Response
package cs236369.proxy;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import cs236369.proxy.types.CacheControl;
import cs236369.proxy.types.HttpPatterns;
public class Response {
private String fullResponse = "";
private BufferedReader reader;
private boolean busy = true;
private int responseCode;
private CacheControl cacheControl;
public Response(String input) {
this(new ByteArrayInputStream(input.getBytes()));
}
public Response(InputStream input) {
reader = new BufferedReader(new InputStreamReader(input));
try {
while (!reader.ready());//wait for initialization.
String line;
while ((line = reader.readLine()) != null) {
fullResponse += "\r\n" + line;
if (HttpPatterns.RESPONSE_CODE.matches(line)) {
responseCode = (Integer) HttpPatterns.RESPONSE_CODE.process(line);
} else if (HttpPatterns.CACHE_CONTROL.matches(line)) {
cacheControl = (CacheControl) HttpPatterns.CACHE_CONTROL.process(line);
}
}
reader.close();
fullResponse = "\r\n" + fullResponse.trim() + "\r\n\r\n";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
busy = false;
}
public CacheControl getCacheControl() {
return cacheControl;
}
public String getFullResponse() {
return fullResponse;
}
public boolean isBusy() {
return busy;
}
public int getResponseCode() {
return responseCode;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((fullResponse == null) ? 0 : fullResponse.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Response))
return false;
Response other = (Response) obj;
if (fullResponse == null) {
if (other.fullResponse != null)
return false;
} else if (!fullResponse.equals(other.fullResponse))
return false;
return true;
}
#Override
public String toString() {
return "Response\n==============================\n" + fullResponse;
}
}
Once I was writing a program to send HTTP requests... My code was like this:
String host="www.google.com";
String request="GET / HTTP/1.0\r\nHost: "+host+"\r\nAccept-Encoding: gzip\r\n\r\n";
System.out.println(request);
Socket sock=new Socket(host,80);
InputStream inp=sock.getInputStream();
OutputStream outp=sock.getOutputStream();
outp.write(request.getBytes());
byte[] buff=new byte[999];
while(true){
int n=inp.read(buff);
if(n<0) break;
System.out.println(new String(buff,0,n));
}
inp.close();
outp.close();
sock.close();
This code works. At first sight, it looks like yours. You can try combining the two and watch when problems start to occur. Maybe there is something wrong in your Response parser?
P.S. Are you sure that the original request you got from the browser ends with two line breaks? In the log you posted it seems that there is only one blank line...
EDIT: I compiled your code with minor modifications, and it works fine. The things I did:
Commented out everything about CacheControl, filtering and RequestHeader because I don't have sources for these classes;
Added simple parsing of URL and host because it won't work without them;
Added a check to remove Accept-Encoding because many servers use gzip which gets corrupted in this program;
Added a check to stop parsing the request after two line breaks.
This program serves as a proxy server for Firefox and works fine with HTML code. Please compile my version and try whether it works for you. Probably there is something to do with Firefox settings?
Please note that this proxy server is corrupting binary data such as images and gzipped HTML. This must be caused by the usage of InputStreamReader and OutputStreamWriter; they convert bytes to characters and vice versa, this is good for text but for binary data you'd better use InputStream and OutputStream "as is".
public class AmirRachum {
public static void main(String[] args) {
try{
int port=38824;
ServerSocket listeningSocket=new ServerSocket(port);
System.out.println("Socket created");
while (true) {
Socket serverSocket;
Socket clientSocket;
BufferedWriter toClient;
BufferedWriter toServer;
try {
//The client is meant to put data on the port, read the socket.
clientSocket = listeningSocket.accept();
Request request = new Request(clientSocket.getInputStream());
System.out.println("Accepted a request!\n" + request);
while(request.busy);
//Make a connection to a real proxy.
//Host & Port - should be read from the request
URL url = null;
try {
url = new URL(request.getRequestURL());
} catch (MalformedURLException e){
url = new URL("http:\\"+request.getRequestHost()+request.getRequestURL());
}
//remove entry from cache if needed
/* if (!request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
cache.remove(request);
}*/
Response response = null;
/* if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
response = cache.get(request);
} else*/ {
//Get the response from the destination
int remotePort = (url.getPort() == -1) ? 80 : url.getPort();
System.out.println("I am going to try to connect to: " + url.getHost() + " at port " + remotePort);
serverSocket = new Socket(url.getHost(), remotePort);
System.out.println("Connected.");
//write to the server - keep it open.
System.out.println("Writing to the server's buffer...");
toServer = new BufferedWriter(new OutputStreamWriter(serverSocket.getOutputStream()));
toServer.write(request.getFullRequest());
toServer.flush();
System.out.println("flushed.");
System.out.println("Getting a response...");
response = new Response(serverSocket.getInputStream());
System.out.println("Got a response!\n" + response);
//wait for the response
while(response.isBusy());
}
/* if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE)) {
cache.put(request, response);
}
response = filter.filter(response);*/
// Return the response to the client
toClient = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
toClient.write(response.getFullResponse());
toClient.flush();
toClient.close();
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static class Request {
private String fullRequest = "";
private BufferedReader reader;
// private RequestHeader requestHeader;
private String requestHost;
private String requestURL;
boolean busy = true;
// private CacheControl cacheControl = CacheControl.CACHE;
/* public CacheControl getCacheControl() {
return cacheControl;
}*/
Request(String request) {
this(new ByteArrayInputStream(request.getBytes()));
}
Request(InputStream input){
reader = new BufferedReader(new InputStreamReader(input));
try {
while(!reader.ready()); //wait for initialization.
String line;
while ((line = reader.readLine()) != null) {
if(!line.startsWith("Accept-Encoding:")) fullRequest += "\r\n" + line;
/* if (HttpPatterns.CACHE_CONTROL.matches(line)) {
cacheControl = (CacheControl) HttpPatterns.RESPONSE_CODE.process(line);
} else if (HttpPatterns.REQUEST_HEADER.matches(line)) {
requestHeader = (RequestHeader) HttpPatterns.REQUEST_HEADER.process(line);
} else if (HttpPatterns.HOST.matches(line)) {
requestHost = (String) HttpPatterns.HOST.process(line);
}*/
if(line.startsWith("GET ")){requestURL=line.split(" ")[1];System.out.println("url \""+requestURL+"\"");}
if(line.startsWith("Host:")){requestHost=line.substring(6);System.out.println("Host \""+requestHost+"\"");}
if(line.length()==0){System.out.println("empty line");break;}
}
fullRequest = "\r\n" + fullRequest.trim() + "\r\n\r\n";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
busy = false;
}
public String getFullRequest() {
return fullRequest;
}
/* public RequestType getRequestType() {
return requestHeader.type;
}*/
public String getRequestURL() {
return requestURL;
}
/* public String getRequestProtocol() {
return requestHeader.protocol;
}*/
public String getRequestHost() {
return requestHost;
}
public boolean isBusy() {
return busy;
}
//#Override
public String toString() {
return "Request\n==============================\n" + fullRequest;
}
}
public static class Response {
private String fullResponse = "";
private BufferedReader reader;
private boolean busy = true;
// private int responseCode;
// private CacheControl cacheControl;
public Response(String input) {
this(new ByteArrayInputStream(input.getBytes()));
}
public Response(InputStream input) {
reader = new BufferedReader(new InputStreamReader(input));
try {
while (!reader.ready());//wait for initialization.
String line;
while ((line = reader.readLine()) != null) {
fullResponse += "\r\n" + line;
/* if (HttpPatterns.RESPONSE_CODE.matches(line)) {
responseCode = (Integer) HttpPatterns.RESPONSE_CODE.process(line);
}/* else if (HttpPatterns.CACHE_CONTROL.matches(line)) {
cacheControl = (CacheControl) HttpPatterns.CACHE_CONTROL.process(line);
}*/
}
reader.close();
fullResponse = "\r\n" + fullResponse.trim() + "\r\n\r\n";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
busy = false;
}
/* public CacheControl getCacheControl() {
return cacheControl;
}*/
public String getFullResponse() {
return fullResponse;
}
public boolean isBusy() {
return busy;
}
/* public int getResponseCode() {
return responseCode;
}*/
//#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((fullResponse == null) ? 0 : fullResponse.hashCode());
return result;
}
//#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Response))
return false;
Response other = (Response) obj;
if (fullResponse == null) {
if (other.fullResponse != null)
return false;
} else if (!fullResponse.equals(other.fullResponse))
return false;
return true;
}
//#Override
public String toString() {
return "Response\n==============================\n" + fullResponse;
}
}
}