I need to do an assignment, but I'm really not sure if I understood how to do it. Here comes the questions and my comments in bold:
1. I have to modify the HttpClient below, in order to use a newer version of the HTTP protocol. To do this, I have to send a somewhat more complicated GET request to the web server. I have to get the inspiration in the HttpMirror below to see what form this request should take (I didn't understand what form is that). HTTP versions 1.0 and later add a version number to the GET request and follow the GET line with a number of header lines followed by a blank line that serves to terminate the request (does that mean that I just have to replace the console print to a different version, like HTTP 1.1? I didn't understand that either).
The only header I need to include is the User-Agent line, which should identify the web client that I'm using. Since I'm writing my own web client, I can give it any name I like! (sure! But how to do that?). I have to be sure to follow my GET request and User-Agent header with a blank line, or the web server will keep waiting for more headers and will never respond to my request ( I'm sure that in case I arrive at this point, I'll understand it better, but up to now: what does that mean?). When I get this program working, I should notice that web servers respond differently to requests from it than they did to request from the original HttpClient program. Wne a client requests data using HTTP 1.0 or 1.1, the server sends a version number, a status code, and a number of response header lines before it sends the actual requested file.
If my server requests a file above the server's working directory (e.g. http://localhost:3001/...\tmp.txt from the command line argument) it should return a forbidden access message. Use the following status codes in order and my own version number
200 Document follows 400 Bad Request 403 Forbidden 404 Not Found
(so, how should it be implemented? By checking the request in the server and if, for example, it is not there, but the syntax is correct, it sends a 404? How should I do that?
Thank you for whichever good soul that was patient enough to read until this point! :O)
Eduardo
publicclass HttpClient {
publicstaticvoid main(String[] args) {
try {
// Check the arguments
if ((args.length != 1) && (args.length != 2))
thrownew IllegalArgumentException("Wrong number of args");
// Get an output stream to write the URL contents to
OutputStream to_file;
if (args.length == 2) to_file = new FileOutputStream(args[1]);
else to_file = System.out;
// Now use the URL class to parse the user-specified URL into
// its various parts.
URL url = new URL(args[0]);
String protocol = url.getProtocol();
if (!protocol.equals("http")) // Check that we support the protocol
thrownew IllegalArgumentException("Must use 'http:' protocol");
String host = url.getHost();
int port = url.getPort();
if (port == -1) port = 80; // if no port, use the default HTTP port
String filename = url.getFile();
// Open a network socket connection to the specified host and port
Socket socket = new Socket(host, port);
// Get input and output streams for the socket
InputStream from_server = socket.getInputStream();
PrintWriter to_server = new PrintWriter(socket.getOutputStream());
// Send the HTTP GET command to the Web server, specifying the file
// This uses an old and very simple version of the HTTP protocol
to_server.print("GET " + filename + "\n\n");
to_server.flush(); // Send it right now!
// Now read the server's response, and write it to the file
byte[] buffer = newbyte[4096];
int bytes_read;
while((bytes_read = from_server.read(buffer)) != -1)
to_file.write(buffer, 0, bytes_read);
// When the server closes the connection, we close our stuff
socket.close();
to_file.close();
}
catch (Exception e) { // Report any errors that arise
System.err.println(e);
System.err.println("Usage: java HttpClient <URL> [<filename>]");
}
}
}
and...
publicclass HttpMirror {
publicstaticvoid main(String args[]) {
try {
// Get the port to listen on
int port = Integer.parseInt(args[0]);
// Create a ServerSocket to listen on that port.
ServerSocket ss = new ServerSocket(port);
// Now enter an infinite loop, waiting for & handling connections.
for(;;) {
// Wait for a client to connect. The method will block;
// when it returns the socket will be connected to the client
Socket client = ss.accept();
// Get input and output streams to talk to the client
BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream());
// Start sending our reply, using the HTTP 1.0 protocol
out.print("HTTP/1.0 200 \n"); // Version & status code
out.print("Content-Type: text/plain\n"); // The type of data
out.print("\n"); // End of headers
// Now, read the HTTP request from the client, and send it
// right back to the client as part of the body of our
// response. The client doesn't disconnect, so we never get
// an EOF. It does sends an empty line at the end of the
// headers, though. So when we see the empty line, we stop
// reading. This means we don't mirror the contents of POST
// requests, for example. Note that the readLine() method
// works with Unix, Windows, and Mac line terminators.
String line;
while((line = in.readLine()) != null) {
if (line.length() == 0) break;
out.print(line + "\n");
}
// Close socket, breaking the connection to the client, and
// closing the input and output streams
out.close(); // Flush and close the output stream
in.close(); // Close the input stream
client.close(); // Close the socket itself
} // Now loop again, waiting for the next connection
}
// If anything goes wrong, print an error message
catch (Exception e) {
System.err.println(e);
System.err.println("Usage: java HttpMirror <port>");
}
}
}