p. 188: In the code fragemnt in the middle of the page, InetAddress.getHostByName("sunsite.unc.edu")
should be
InetAddress.getByName("sunsite.unc.edu")
. That is,
try {
ServerSocket httpd = new ServerSocket(5776, 100,
InetAddress.getByName("sunsite.unc.edu"));
}
catch (IOException e) {
System.err.println(e);
}
p. 193: The setSoTimeout()
method throws InterruptedIOException
,
not InterruptedException
.
thisLine
variable should be
initialized to the empty string ""
.
Otherwise, "null" will be prefixed to the data. Secondly,
I neglected to set the
ContentLength
field. There are many ways to fix this.
One is to simply eliminate it completely as in the following:
import java.net.*;
import java.io.*;
import java.util.*;
public class onefile extends Thread {
static String theData = "";
static String ContentType;
Socket theConnection;
public static void main(String[] args) {
int thePort;
ServerSocket ss;
Socket theConnection;
FileInputStream theFile;
// cache the file
try {
theFile = new FileInputStream(args[0]);
DataInputStream dis = new DataInputStream(theFile);
if (args[0].endsWith(".html") || args[0].endsWith(".htm")) {
ContentType = "text/html";
}
else {
ContentType = "text/plain";
}
try {
String thisLine = "";
while ((thisLine = dis.readLine()) != null) {
theData += thisLine + "\n";
}
}
catch (Exception e) {
System.err.println("Error: " + e);
}
}
catch (Exception e) {
System.err.println(e);
System.err.println("Usage: java onefile filename port");
System.exit(1);
}
// set the port to listen on
try {
thePort = Integer.parseInt(args[1]);
if (thePort < 0 || thePort > 65535) thePort = 80;
}
catch (Exception e) {
thePort = 80;
}
try {
ss = new ServerSocket(thePort);
System.out.println("Accepting connections on port "
+ ss.getLocalPort());
System.out.println("Data to be sent:");
System.out.println(theData);
while (true) {
onefile fs = new onefile(ss.accept());
fs.start();
}
}
catch (IOException e) {
}
}
public onefile(Socket s) {
theConnection = s;
}
public void run() {
try {
PrintStream os = new PrintStream(theConnection.getOutputStream());
DataInputStream is = new DataInputStream(theConnection.getInputStream());
String request = is.readLine();
// If this is HTTP/1.0 or later send a MIME header
if (request.indexOf("HTTP/") != -1) {
while (true) { // read the rest of the MIME header
String thisLine = is.readLine();
if (thisLine.trim().equals("")) break;
}
os.print("HTTP/1.0 200 OK\r\n");
Date now = new Date();
os.print("Date: " + now + "\r\n");
os.print("Server: OneFile 1.0\r\n");
os.print("Content-length: " + theData.length() + "\r\n");
os.print("Content-type: " + ContentType + "\r\n\r\n");
} // end if
os.println(theData);
theConnection.close();
} // end try
catch (IOException e) {
}
}
}
Furthermore, the String
field theData
should be initialized to the empty string.
p. 209: The run() method in Example 8-7 (jhttp)
checks if the method
is GET and, if so, it parses the header to get the protocol version.
On p 210, if the method is not GET, it checks the protocol version
without ever having parsed the header to find the protocol version, so
it will never execute the code to generate the 'Not implemented'
response.
This is a bug, though it won't crash the program.
The following revised run()
method fixes the problem.
public void run() {
String method;
String file="";
String ct;
String version = "";
File theFile;
try {
PrintStream os = new PrintStream(theConnection.getOutputStream());
DataInputStream is = new DataInputStream(theConnection.getInputStream());
String get = is.readLine();
StringTokenizer st = new StringTokenizer(get);
method = st.nextToken();
if (st.hasMoreTokens()) {
file = st.nextToken();
if (file.endsWith("/")) file += indexfile;
}
if (st.hasMoreTokens()) version = st.nextToken();
if (method.equals("GET")) {
ct = guessContentTypeFromName(file);
// loop through the rest of the input lines
while ((get = is.readLine()) != null) {
if (get.trim().equals("")) break;
}
try {
theFile = new File(docroot, file.substring(1,file.length()));
FileInputStream fis = new FileInputStream(theFile);
byte[] theData = new byte[(int) theFile.length()];
// need to check the number of bytes read here
fis.read(theData);
fis.close();
if (version.startsWith("HTTP/")) { // send a MIME header
os.print("HTTP/1.0 200 OK\r\n");
Date now = new Date();
os.print("Date: " + now + "\r\n");
os.print("Server: jhttp 1.0\r\n");
os.print("Content-length: " + theData.length + "\r\n");
os.print("Content-type: " + ct + "\r\n\r\n");
} // end try
// send the file
os.write(theData);
os.close();
} // end try
catch (IOException e) { // can't find the file
if (version.startsWith("HTTP/")) { // send a MIME header
os.print("HTTP/1.0 404 File Not Found\r\n");
Date now = new Date();
os.print("Date: " + now + "\r\n");
os.print("Server: jhttp 1.0\r\n");
os.print("Content-type: text/html" + "\r\n\r\n");
}
os.println("<HTML><HEAD><TITLE>File Not Found</TITLE></HEAD>");
os.println("<BODY><H1>HTTP Error 404: File Not Found</H1></BODY></HTML>");
os.close();
}
}
else { // method does not equal "GET"
if (version.startsWith("HTTP/")) { // send a MIME header
os.print("HTTP/1.0 501 Not Implemented\r\n");
Date now = new Date();
os.print("Date: " + now + "\r\n");
os.print("Server: jhttp 1.0\r\n");
os.print("Content-type: text/html" + "\r\n\r\n");
}
os.println("<HTML><HEAD><TITLE>Not Implemented</TITLE></HEAD>");
os.println("<BODY><H1>HTTP Error 501: Not Implemented</H1></BODY></HTML>");
os.close();
}
}
catch (IOException e) {
}
try {
theConnection.close();
}
catch (IOException e) {
}
}