Example #1
0
 public HttpResponseImpl response() throws IOException, InterruptedException {
   HttpRequestImpl r = request;
   if (r.timeval() != 0) {
     // set timer
     td = new TimedEvent(r.timeval());
     client.registerTimer(td);
   }
   while (attempts < max_attempts) {
     try {
       attempts++;
       Exchange currExchange = getExchange();
       requestFilters(r);
       HttpResponseImpl response = currExchange.response();
       Pair<HttpResponse, HttpRequestImpl> filterResult = responseFilters(response);
       HttpRequestImpl newreq = filterResult.second;
       if (newreq == null) {
         if (attempts > 1) {
           Log.logError("Succeeded on attempt: " + attempts);
         }
         cancelTimer();
         return response;
       }
       response.body(HttpResponse.ignoreBody());
       setExchange(new Exchange(newreq, currExchange.getAccessControlContext()));
       r = newreq;
     } catch (IOException e) {
       if (cancelled) {
         throw new HttpTimeoutException("Request timed out");
       }
       throw e;
     }
   }
   cancelTimer();
   throw new IOException("Retry limit exceeded");
 }
  /**
   * Process an incoming HTTP request on the Socket that has been assigned to this Processor. Any
   * exceptions that occur during processing must be swallowed and dealt with.
   *
   * @param socket The socket on which we are connected to the client
   */
  private void process(Socket socket) {

    boolean ok = true;
    boolean finishResponse = true;
    SocketInputStream input = null;
    OutputStream output = null;

    // Construct and initialize the objects we will need
    try {
      input = new SocketInputStream(socket.getInputStream(), connector.getBufferSize());
    } catch (Exception e) {
      log("process.create", e);
      ok = false;
    }

    keepAlive = true;

    while (!stopped && ok && keepAlive) {

      finishResponse = true;

      try {
        request.setStream(input);
        request.setResponse(response);
        output = socket.getOutputStream();
        response.setStream(output);
        response.setRequest(request);
        ((HttpServletResponse) response.getResponse()).setHeader("Server", SERVER_INFO);
      } catch (Exception e) {
        log("process.create", e);
        ok = false;
      }

      // Parse the incoming request
      try {
        if (ok) {
          parseConnection(socket);
          parseRequest(input, output);
          if (!request.getRequest().getProtocol().startsWith("HTTP/0")) parseHeaders(input);
          if (http11) {
            // Sending a request acknowledge back to the client if
            // requested.
            ackRequest(output);
            // If the protocol is HTTP/1.1, chunking is allowed.
            if (connector.isChunkingAllowed()) response.setAllowChunking(true);
          }
        }
      } catch (EOFException e) {
        // It's very likely to be a socket disconnect on either the
        // client or the server
        ok = false;
        finishResponse = false;
      } catch (ServletException e) {
        ok = false;
        try {
          ((HttpServletResponse) response.getResponse())
              .sendError(HttpServletResponse.SC_BAD_REQUEST);
        } catch (Exception f) {;
        }
      } catch (InterruptedIOException e) {
        if (debug > 1) {
          try {
            log("process.parse", e);
            ((HttpServletResponse) response.getResponse())
                .sendError(HttpServletResponse.SC_BAD_REQUEST);
          } catch (Exception f) {;
          }
        }
        ok = false;
      } catch (Exception e) {
        try {
          log("process.parse", e);
          ((HttpServletResponse) response.getResponse())
              .sendError(HttpServletResponse.SC_BAD_REQUEST);
        } catch (Exception f) {;
        }
        ok = false;
      }

      // Ask our Container to process this request
      try {
        ((HttpServletResponse) response).setHeader("Date", FastHttpDateFormat.getCurrentDate());
        if (ok) {
          connector.getContainer().invoke(request, response);
        }
      } catch (ServletException e) {
        log("process.invoke", e);
        try {
          ((HttpServletResponse) response.getResponse())
              .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        } catch (Exception f) {;
        }
        ok = false;
      } catch (InterruptedIOException e) {
        ok = false;
      } catch (Throwable e) {
        log("process.invoke", e);
        try {
          ((HttpServletResponse) response.getResponse())
              .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        } catch (Exception f) {;
        }
        ok = false;
      }

      // Finish up the handling of the request
      if (finishResponse) {
        try {
          response.finishResponse();
        } catch (IOException e) {
          ok = false;
        } catch (Throwable e) {
          log("process.invoke", e);
          ok = false;
        }
        try {
          request.finishRequest();
        } catch (IOException e) {
          ok = false;
        } catch (Throwable e) {
          log("process.invoke", e);
          ok = false;
        }
        try {
          if (output != null) output.flush();
        } catch (IOException e) {
          ok = false;
        }
      }

      // We have to check if the connection closure has been requested
      // by the application or the response stream (in case of HTTP/1.0
      // and keep-alive).
      if ("close".equals(response.getHeader("Connection"))) {
        keepAlive = false;
      }

      // End of request processing
      status = Constants.PROCESSOR_IDLE;

      // Recycling the request and the response objects
      request.recycle();
      response.recycle();
    }

    try {
      shutdownInput(input);
      socket.close();
    } catch (IOException e) {;
    } catch (Throwable e) {
      log("process.invoke", e);
    }
    socket = null;
  }
  /**
   * Parse the incoming HTTP request headers, and set the appropriate request headers.
   *
   * @param input The input stream connected to our socket
   * @exception IOException if an input/output error occurs
   * @exception ServletException if a parsing error occurs
   */
  private void parseHeaders(SocketInputStream input) throws IOException, ServletException {

    while (true) {

      HttpHeader header = request.allocateHeader();

      // Read the next header
      input.readHeader(header);
      if (header.nameEnd == 0) {
        if (header.valueEnd == 0) {
          return;
        } else {
          throw new ServletException(sm.getString("httpProcessor.parseHeaders.colon"));
        }
      }

      String value = new String(header.value, 0, header.valueEnd);
      if (debug >= 1) log(" Header " + new String(header.name, 0, header.nameEnd) + " = " + value);

      // Set the corresponding request headers
      if (header.equals(DefaultHeaders.AUTHORIZATION_NAME)) {
        request.setAuthorization(value);
      } else if (header.equals(DefaultHeaders.ACCEPT_LANGUAGE_NAME)) {
        parseAcceptLanguage(value);
      } else if (header.equals(DefaultHeaders.COOKIE_NAME)) {
        Cookie cookies[] = RequestUtil.parseCookieHeader(value);
        for (int i = 0; i < cookies.length; i++) {
          if (cookies[i].getName().equals(Globals.SESSION_COOKIE_NAME)) {
            // Override anything requested in the URL
            if (!request.isRequestedSessionIdFromCookie()) {
              // Accept only the first session id cookie
              request.setRequestedSessionId(cookies[i].getValue());
              request.setRequestedSessionCookie(true);
              request.setRequestedSessionURL(false);
              if (debug >= 1)
                log(
                    " Requested cookie session id is "
                        + ((HttpServletRequest) request.getRequest()).getRequestedSessionId());
            }
          }
          if (debug >= 1)
            log(" Adding cookie " + cookies[i].getName() + "=" + cookies[i].getValue());
          request.addCookie(cookies[i]);
        }
      } else if (header.equals(DefaultHeaders.CONTENT_LENGTH_NAME)) {
        int n = -1;
        try {
          n = Integer.parseInt(value);
        } catch (Exception e) {
          throw new ServletException(sm.getString("httpProcessor.parseHeaders.contentLength"));
        }
        request.setContentLength(n);
      } else if (header.equals(DefaultHeaders.CONTENT_TYPE_NAME)) {
        request.setContentType(value);
      } else if (header.equals(DefaultHeaders.HOST_NAME)) {
        int n = value.indexOf(':');
        if (n < 0) {
          if (connector.getScheme().equals("http")) {
            request.setServerPort(80);
          } else if (connector.getScheme().equals("https")) {
            request.setServerPort(443);
          }
          if (proxyName != null) request.setServerName(proxyName);
          else request.setServerName(value);
        } else {
          if (proxyName != null) request.setServerName(proxyName);
          else request.setServerName(value.substring(0, n).trim());
          if (proxyPort != 0) request.setServerPort(proxyPort);
          else {
            int port = 80;
            try {
              port = Integer.parseInt(value.substring(n + 1).trim());
            } catch (Exception e) {
              throw new ServletException(sm.getString("httpProcessor.parseHeaders.portNumber"));
            }
            request.setServerPort(port);
          }
        }
      } else if (header.equals(DefaultHeaders.CONNECTION_NAME)) {
        if (header.valueEquals(DefaultHeaders.CONNECTION_CLOSE_VALUE)) {
          keepAlive = false;
          response.setHeader("Connection", "close");
        }
        // request.setConnection(header);
        /*
          if ("keep-alive".equalsIgnoreCase(value)) {
          keepAlive = true;
          }
        */
      } else if (header.equals(DefaultHeaders.EXPECT_NAME)) {
        if (header.valueEquals(DefaultHeaders.EXPECT_100_VALUE)) sendAck = true;
        else
          throw new ServletException(sm.getString("httpProcessor.parseHeaders.unknownExpectation"));
      } else if (header.equals(DefaultHeaders.TRANSFER_ENCODING_NAME)) {
        // request.setTransferEncoding(header);
      }

      request.nextHeader();
    }
  }