8

I think my problem will take some explaining of the background. My assignment is to create a basic server that will send HTML files on my system that clients request. I was told to test my server by just entering localhost:8080/index.html in my firefox browser as a test client. Entering in that line of input works correctly and prints out the contents of index.html. As a safety, I am suposed to test to make sure that the requested file is within my current working directly, and if its not I should deny the request. I have set up just such a catch and I want to check it. I want to use my file index.html again, but by the entire pathname aka C:\Users\Gabrielle\Documents\NetBeansProjects\CS2 Assignment 5\src\index.html So I enter in my browser

localhost:8080/C:\Users\Gabrielle\Documents\NetBeansProjects\CS2 Assignment 5\src\index.html

and I am given an error that says the file doesn't exist. I then checked to see what it was trying to make a file out of and its trying to make a file out of and I get

C:%5CUsers%5C%5CGabreille%5C%5CDocuments%5C%5CNetBeansProjects%5C%5CCS2%20Assignment%205%5Cindex.html

which clearly isn't the name of the file. Am i just sending in the file name incorrectly? If it makes any difference, I am running the program from the windows command prompt. Below is the code for my multi-threaded client and the code for my runnable object. If you have any questions or want some clarity, Ill be closely watching this thread.

import java.io.*;
import java.net.*;

public class WebServer {

    public static void main(String[] args)
    {
        try{
            ServerSocket ss = new ServerSocket(8080);
            while(true){
                Thread conn = new Thread(new ClientConnection(ss.accept()));
                conn.start();
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
}

Here's the actual content

import java.io.*;
import java.net.*;

public class ClientConnection  implements Runnable{

private Socket socket;
File requestedFileName;
String entireInput ="";
String editedInput="";
String fileContent="";
String fileLine="";
PrintWriter out;
File defaultFile = new File("index.html");
File toBeRead;

public ClientConnection(Socket socket)
{
    this.socket=socket;
}

public void run()
{
    try{
        System.out.println("Client Connected");
        String workingDirectory = System.getProperty("user.dir");
        BufferedReader in =
                new BufferedReader(new InputStreamReader(socket.getInputStream()));
         out = new PrintWriter(socket.getOutputStream());
        String line;
            entireInput = in.readLine();

        editedInput= entireInput.substring(entireInput.indexOf("GET")+3,
                entireInput.indexOf("HTTP/1.1"));
        System.out.println("File name:" + editedInput);
        requestedFileName = new File(editedInput);
        System.out.println("What about here?");
        if(editedInput.equals(" / ") || editedInput.equals("  "))
        {
            toBeRead = defaultFile;
            System.out.println("Parent file "+toBeRead.getParent());
            String absolutePath = toBeRead.getAbsolutePath();
            System.out.println("absolute path "+ absolutePath);
            String filePath = absolutePath.substring(0,absolutePath.lastIndexOf(File.separator));
            if(filePath.equals(workingDirectory))
            {
                System.out.println("is in directory");
            }
            else{
                System.out.println("not in directory");
            }
        }
        else
        {   

            String hope = editedInput.substring(2);
            toBeRead = new File(hope);
        }

             //toBeRead = new File("index.html");
            if(toBeRead.exists())
            {
                System.out.println("File exists");
            }
            else
            {
                System.out.println("file doesn't exist");
            }
           BufferedReader fileIn = new BufferedReader(new FileReader(toBeRead));

           while((fileLine = fileIn.readLine()) != null)
             {
               //System.out.println("can i get in while loop?");
               fileContent = fileContent + fileLine;
                //System.out.println("File content: \n" + fileContent);
             }

           out.print("HTTP/1.1 200 OK\r\n");
           out.print("content-type: text/html\r\n\r\n");
           out.print(fileContent);
           out.flush();
           out.close();

        }
        catch(FileNotFoundException f)
        {
            System.out.println("File not found");
            out.print("HTTP/1.1 404 Not Found\r\n\r\n");
            out.flush();
            out.close();
        }
        catch(Exception e)
        {
            out.print("HTTP/1.1 500 Internal Server Error\r\n\r\n");
            out.flush();
            out.close();
        }

    }
}
Filburt
  • 17,626
  • 12
  • 64
  • 115
art3m1sm00n
  • 389
  • 6
  • 9
  • 19

1 Answers1

8

You're giving the file a relative path and expecting it to magically find the file. Relative paths are resolved relative to where your JVM was started. If you want an absolute path you'll need to do something like:

new File("C:\\Users\\Gabrielle\\Documents\\NetBeansProjects\\CS2 Assignment 5\\src\\index.html");

You're not getting that from the request to your application because the request is URLEncoded.

Of course, the better solution would be to have the file in a reasonable place relative to your application and reference it relatively.

vegemite4me
  • 6,621
  • 5
  • 53
  • 79
Aurand
  • 5,487
  • 1
  • 25
  • 35
  • What do you mean URLEncoded? Is that why there are the random `%`'s in the pathname? I think, because of the assignment, I have to be able to accept a full pathname input. Is there anyway to get around the URLEncoding? Why is it not encoded when I only type in `index.hmtl`? – art3m1sm00n Mar 29 '13 at 00:17
  • When you put special characters in a URL, they are encoded. For example %5C is a backslash and %20 is a space. I think what your assignment is really trying to check for is if someone does something like "localhost:8080/../../someValuableFile.file". – Aurand Mar 29 '13 at 00:20
  • Yes, thats exactly what I'm trying to do. So you're telling me that because the way that it gets encoded, such a thing is impossible? I sent an email to my professor asking if I really have to accept full path input and haven't gotten a reply. The reason I think that I would need to accept full path is because "this server is extremely insecure, and will allow a malicious user to access any textfile on your machine. You should implement a check so that the server will only send files that are located inside a directory you designate" – art3m1sm00n Mar 29 '13 at 00:25
  • The directory i'm supposed to designate is the current working directly. If i don't have to accept full pathname input, I don't see how any textfile on my machine could be accessed. – art3m1sm00n Mar 29 '13 at 00:26
  • new File("../index.html") will go to the parent directory of the current directory and attempt to find "index.html" in that directory. By constantly going up to the parent directory and then back down into child directories you can access any file on the current drive as a relative path. – Aurand Mar 29 '13 at 00:32
  • So I don't necessarily need to handle full pathnames? – art3m1sm00n Mar 29 '13 at 00:33
  • 2
    I am not your teacher, so I don't know what they are thinking. However, in a sane universe, no. – Aurand Mar 29 '13 at 00:34
  • Ha, ok good. Ill just ignore that factor until I get a response from him. Thank you! – art3m1sm00n Mar 29 '13 at 00:35