// // example of java.net.* classes. // // adapted from example in ch. 11 of _Exploring Java_, Niemeyer & Peck. // // version 1: no security manager. (but program responds to requests // just by confirming the requested file's existence and size, and // is restricted to those files to which server program has read // access.) // import java.net.* ; import java.io.* ; import java.util.* ; // // ---- main ----------------------------------------------------------- // // command-line argument is port number. // // instructions for testing: // // (1) start the TinyHttpd1 server: // java TinyHttpd1 nnnn // (nnnn is any port number you choose, higher than 1024) // suppose mymachine.org is the name of the machine on which // you've done this, and nnnn = 1234. // // (2) point a Web browser at it, via URLs like: // http://mymachine.org:1234/filename // // filename will be interpreted relative to the directory *in // which you started TinyHttpd1*. to specify an // absolute pathname, include an extra "/", e.g., // http://mymachine.org:1234//toplevel/midlevel/filename. // // if you don't know the name of the machine on which you're // running, you can use its IP address instead. for // a Windows machine, you may be able to get its IP address // by typing "winipcfg" at a DOS prompt. // // when done, stop the server with control-C. // // these instructions have been tested on Unix and Windows systems at // UF, and on Linux systems at Trinity. // public class TinyHttpd1 { public static void main(String[] args) throws IOException { if (args.length < 1) { System.out.println("Argument is portnum") ; System.exit(-1) ; } // create server socket to accept client requests. ServerSocket ss = new ServerSocket(Integer.parseInt(args[0])) ; // accept client requests, creating a new thread for // each. while (true) { new TinyHttpd1Connection(ss.accept()).start() ; } } } // // a TinyHttpd1Connection object is a thread that serves a // client request (of the form GET /filename .. options ..). // "filename" (without the leading slash) is assumed to be a file // in the server's directory. // it sends back to the client: // error message for badly formed request or file not found. // some info about file otherwise. // class TinyHttpd1Connection extends Thread { Socket client ; PrintWriter pout ; TinyHttpd1Connection(Socket client) throws SocketException { this.client = client ; setPriority(NORM_PRIORITY - 1) ; } public void run() { try { // create in, out streams using standard // encoding for HTTP. BufferedReader in = new BufferedReader( new InputStreamReader( client.getInputStream(), "8859_1")) ; pout = new PrintWriter( new OutputStreamWriter( client.getOutputStream(), "8859_1"), true) ; // read and echo request. String request = in.readLine() ; System.out.println("Request: " + request) ; // parse request. StringTokenizer st = new StringTokenizer(request) ; if ((st.countTokens() >= 2) && st.nextToken().equals("GET") ) { serviceRequest(st.nextToken()) ; } else { pout.println("400 Bad Request") ; } client.close() ; } catch (IOException e) { System.out.println("I/O error " + e) ; } } // processes request (filename). private void serviceRequest(String filereq) { // strip off leading "/". if (filereq.startsWith("/")) filereq = filereq.substring(1) ; // append "index.html" if name ends with "/". if (filereq.endsWith("/") || filereq.equals("")) filereq = filereq + "index.html" ; // try to return info about file. File f = new File(filereq) ; if (f.exists()) { if (f.isDirectory()) { pout.println("Directory " + filereq + " found
") ; if (f.canRead()) pout.println("Contains " + f.list().length + " files or subdirectories
") ; else pout.println("Not readable
") ; } else { pout.println("File " + filereq + " found
") ; pout.println("Size = " + f.length() + " bytes
") ; } } else pout.println("404 File Not Found") ; } }