⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httprequest.java

📁 21天学通java的示例程序源代码
💻 JAVA
字号:
// HTTPRequest.java

package com.wrox.httpserver;

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

/**
 * Manages a single HTTP request coming from a client.
 */
class HTTPRequest extends HTTPConstants implements Runnable {

  // Localized messages
  private static HTTPLocalizedResources resources;

  // Read message resources
  static {
    try {
      resources = new HTTPLocalizedResources("msg.httprequest");
    } catch (MissingResourceException mre) {
      System.err.println(RESOURCE_ERROR);
      System.exit(1);
    } 
  } 

  // Instance variables
  private Socket socket;
  private BufferedOutputStream bos;
  private HTTPBufferedInputStream bis;
  private HTTPHandler handler;
  private HTTPMessageHeaders headers;
  private HTTPInformation info;
  private String header_method;
  private String header_uri;
  private String header_protocol;

  /**
   * Constructs an HTTPRequest.
   */
  public HTTPRequest(Socket socket) {

    // Initialize instance variables
    this.socket = socket;

    try {

      // As we need to read both character strings and then later in case
      // of a POST request also bytes, we need a special input stream that
      // can do both
      bis = new HTTPBufferedInputStream(socket.getInputStream(), 
                                        BUFFER_SIZE, HTTP_ENCODING);
      bos = new BufferedOutputStream(socket.getOutputStream(), BUFFER_SIZE);
    } catch (Exception e) {
      HTTPException httpre = 
        new HTTPException("ERROR_HTTP_GET_STREAMS" + e.getMessage(), 
                          HTTPStatus.INTERNAL_ERROR);
      handleException(httpre);
    } 

    headers = new HTTPMessageHeaders();
    info = new HTTPInformation();
  }

  /**
   * Parses the request lines until an empty line is encountered.
   */
  private void getHeaders() throws HTTPException {
    String line;
    boolean firstLine = true;

    try {

      // Read the request headers, line by line
      while ((line = bis.readLine()) != null && line.length() > 0) {
        if (firstLine) {

          // Store request string for logging
          info.requestString = line;

          // Parse the HTTP request line to determine the request method
          parseRequestLine(line);

          if (header_protocol.equalsIgnoreCase(HTTP_09)) {

            // No more headers, so just continue
            return;
          } 

          // The first line has been processed
          firstLine = false;
        } else {
          parseHeaderLine(line);
        } 
      } 
    } catch (IOException e) {
      throw new HTTPException(resources
        .getResourceString("ERROR_HTTP_READ_REQUEST"), HTTPStatus
          .INTERNAL_ERROR);
    } 
  } 

  /**
   * All exceptions are handled by this method.
   */
  private void handleException(HTTPException e) {
    int status = e.getStatus();
    info.status = status;

    try {

      // Return relevant information to the browser
      String statusString = HTTPStatus.getString(status);

      if (statusString == null) {

        // Unrecognized status
        status = HTTPStatus.INTERNAL_ERROR;
        statusString = HTTPStatus.getString(status);
      } 

      // Create HTTP response
      HTTPResponse response = new HTTPResponse();
      response.getHeaders().addHeader(HEADER_FIELD_CONTENTTYPE, 
                                      DEFAULT_MIME_TYPE);
      response.printStatus(bos, info.serverProtocol, status);
      response.printHeaders(bos);

      // Build status message and return HTML error information
      String statusMessage = new Integer(status).toString() + " " 
                             + statusString;
      StringBuffer message = new StringBuffer();
      message.append("<html>\n<head>\n<title>" + statusMessage 
                     + "</title>\n</head>");
      message.append("<body>\n<h1>" + statusMessage + "</h1>\n");
      message.append(e.getMessage() + "\n</body>\n</html>\n");
      byte bytes[] = message.toString().getBytes(HTTP_ENCODING);
      bos.write(bytes);
      bos.flush();
    } catch (Exception exception) {

      // The exception handler throws an exception, ignore
    } 

    // Log the error
    HTTPLog.logger.log(info);
  } 

  /**
   * Parses the header line and adds a header to the request.
   */
  private void parseHeaderLine(String header) {

    // Trim any whitespace characters
    header = header.trim();
    try {
      int colonIndex = header.indexOf(HTTP_HEADER_FIELD_SEPERATOR);
      if (colonIndex > 0) {
        String fieldName = header.substring(0, colonIndex);
        String fieldValue = header.substring(colonIndex + 1);
        headers.addHeader(fieldName, fieldValue);
      } 
    } catch (Exception e) {

      // Bad header line, ignore it or write to error log
    } 
  } 

  /**
   * Parses the first line of the request to determine URI, protocol, HTTP request method.
   */
  private void parseRequestLine(String request) throws HTTPException {

    // Remove any whitespace from both ends
    StringTokenizer st = new StringTokenizer(request.trim());

    try {

      // Read the method
      header_method = st.nextToken();

      // Read the URI
      header_uri = st.nextToken();
      header_uri = URLDecoder.decode(header_uri);
      if (header_uri.endsWith("/")) {

        // Add the default document when the URI points to a directory
        header_uri = header_uri + HTTPConfig.config.getDirectoryIndex();
      } 

      if (!st.hasMoreTokens()) {

        // When the protocol is missing, we assume it is HTTP/0.9
        header_protocol = HTTP_09;
        return;
      } else {
        header_protocol = st.nextToken();
      }
    } catch (Exception e) {

      // An error occurred while parsing the request
      throw new HTTPException(resources
        .getResourceString("ERROR_HTTP_PARSE_REQUESTLINE"), HTTPStatus
          .BAD_REQUEST);
    } 
  } 

  /**
   * Processes the HTTP request by parsing the header information first and
   * then creating the respective method object for further processing.
   */
  private void process() throws HTTPException {

    // Read in the request headers
    getHeaders();

    // Check that we have a supported protocol
    if (!(header_protocol.equalsIgnoreCase(HTTP_09) 
          || header_protocol.equalsIgnoreCase(HTTP_10) 
          || header_protocol.equalsIgnoreCase(HTTP_11))) {

      // Invalid request
      throw new HTTPException(resources
        .getResourceString("ERROR_HTTP_INVALID_PROTOCOL"), HTTPStatus
          .BAD_REQUEST);
    } 

    // Get variables required for method processing
    InetAddress address = socket.getInetAddress();

    // Check if we support the request method
    if (header_method.equals(METHOD_GET)) {
      handler = new HTTPGetHandler(info, header_uri, headers, address, 
                                   header_protocol, bis, bos);
    } else if (header_method.equals(METHOD_POST)) {
      handler = new HTTPPostHandler(info, header_uri, headers, address, 
                                    header_protocol, bis, bos);
    } else if (header_method.equals(METHOD_HEAD)) {
      handler = new HTTPHeadHandler(info, header_uri, headers, address, 
                                    header_protocol, bis, bos);
    } 

    if (handler == null) {

      // Unsupported method
      throw new HTTPException(resources
        .getResourceString("ERROR_HTTP_INVALID_PROTOCOL"), HTTPStatus
          .NOT_IMPLEMENTED);
    } 

    // Process method
    handler.process();

    // Log request
    HTTPLog.logger.log(info);
  } 

  /**
   * Processes the HTTP request in a seperate thread.
   */
  public void run() {
    try {
      process();
    } catch (HTTPException e) {
      handleException(e);
    } 
    finally {
      try {
        bos.flush();
        bos.close();
        socket.close();
      } catch (IOException e) {
        handleException(new HTTPException(resources.getResourceString("ERROR_HTTP_REQUEST_SHUTDOWN") 
                                          + e.getMessage(), HTTPStatus.INTERNAL_ERROR));
      } 
    } 
  } 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -