Home : Course Map : Chapter 14 :
HTTP Protocol
JavaTech
Course Map
Chapter 14

Web Servers
Design of Server
ServerSocket
Threads For Clients
Client Streams
HTTP Protocol
Run Server
  Demo 1
Secure Server
  Demo 2
More Security
A client application
  Demo 3
Server Apps
Servlets
Exercises

     About JavaTech
     Codes List
     Exercises
     Feedback
     References
     Resources
     Tips
     Topic Index
     Course Guide
     What's New

For network communications to work correctly a common language or protocol must be established. The web protocol is the HTTP (Hypertext Transfer Protocol). A HTTP request for a web page from a server would go as:

  GET /index.html HTTP/1.0 \r\n\r\n

where GET is the request keyword, /index.html is the file requested, and HTTP/1.0 is the protocol/version. The final \r\n\r\n indicates the two carriage return/linefeed pairs that must terminate the line.

The code snippet from run() shown below obtains the request line sent from the client by invoking the readLine() method of BufferedReader. Then the request text is broken into tokens with the split() method in the String class (see Chapter 10 :Java : String Tools).

The tokens are checked to determine if the client sent the "GET" command and, if so, to obtain the name of the file that the client is requesting.

 ... In the run() method in Worker...

       // First read the message from the client
      String client_str = client_in.readLine ();
      System.out.println ("Client message: "+client_str);

      // Split the message into substrings.
      String [] tokens = client_str.split(" ");

      // Check that the message has a minimun number of words
      // and that the first word is the GET command.
      if ((tokens.length >= 2) &&
           tokens[0].equals ("GET")) {
         String file_name = tokens[1];

        // Ignore the leading "/" on the file name.
        if (file_name.startsWith ("/"))
            file_name = file_name.substring (1);

        // If no file name is there, use index.html default.
        if (file_name.endsWith ("/") || file_name.equals (""))
           file_name = file_name + "index.html";

        // Check if the file is hypertext or plain text
        String content_type;
        if (file_name.endsWith (".html") ||
            file_name.endsWith (".htm")) {
           content_type = "text/html";
        }
        else {
          content_type = "text/plain";
        }

 ...

If the request from the client is valid, we then read from the local file that the client is requesting and return it to the client. As shown in the following code, to read the file we first obtain a FileInputStream for the file. We send text messages back to the client using the PrintWriter methods.

We note that the PrintWriter methods don't throw IOException and instead the class offers the checkError() method, which returns true if an IOException occurred. For the sake of brevity, we did not check for errors after every print invocation. (In the DataWorker class in Chapter 15, we place the print invocations in utility methods that check for errors and throw exceptions when they occur.)

 ... Continue in the run() method in Worker...

        // Now read the file from the disk and write it to the
        // output stream to the client.
        try {

          // Open a stream to the file.
          FileInputStream file_in = new FileInputStream  (file_name);

          // Send the header.
          pw_client_out.print ("HTTP/1.0 200 OK\r\n");
          File file = new File (file_name);
          Date date = new Date (file.lastModified ());
          pw_client_out.print ("Date: " + date + "\r\n");
          pw_client_out.print ("Server: MicroServer 1.0\r\n");
          pw_client_out.print ("Content-length: " + file_in.available ()
            + "\r\n");
          pw_client_out.print ("Content-type: " + content_type
            + "\r\n\r\n");

          // Creat a byte array to hold the file.
          byte [] data = new byte [file_in.available ()];

          file_in.read (data);     // Read file into the byte array
          client_out.write (data); // Write it to client output stream
          client_out.flush ();     // Remember to flush output buffer
          file_in.close ();        // Close file input stream

        } catch (FileNotFoundException e) {
          // If no such file, then send the famous 404 message.
          pw_client_out.println ("404 Object Not Found" );
        }
      } else{
        pw_client_out.println ("400 Bad Request");
      }
    } catch (IOException e) {
      System.out.println ( "I/O error " + e );
    }

    // Close client socket.
    try {
      fClient.close ();
    } catch (IOException e){
      System.out.println ("I/O error " + e );
    }
    // On return from run () the thread process will stop.
  } // run

  ...

 

The line "HTTP/1.0 200 OK\r\n" gives the protocol and version number of the return message followed by the 200 code number that indicates that the file has been found successfully and will be sent. This is followed by the file's modification date, an identification of the server, the length of the file and the file type (e.g. "text/html"). Finally, the whole file is sent in one big byte array via the write() method of OutputStream.

If the file is not available, the program sends the "404 Object Not Found" error message, which is a common one for Web users. If the request line had problems, a "400 Bad Request" error message is sent.

This short program provides a basic Web server that returns Web files to browsers and any other client program that connects to the port and uses the proper HTTP protocol. The Socket and ServerSocket classes, along with the I/O stream classes, do most of the work.

 

Latest update: Dec. 9, 2004

  
  Part I Part II Part III
Java Core 1  2  3  4  5  6  7  8  9  10  11  12 13 14 15 16 17
18 19 20
21
22 23 24
Supplements

1  2  3  4  5  6  7  8  9  10  11  12

Tech 1  2  3  4  5  6  7  8  9  10  11  12
Physics 1  2  3  4  5  6  7  8  9  10  11  12

Java is a trademark of Sun Microsystems, Inc.