Example #1
0
 /**
  * Expected to be used by the handler once the processor is no longer required.
  *
  * @param socket
  * @param processor
  * @param isSocketClosing Not used in HTTP
  * @param addToPoller
  */
 @Override
 public void release(
     SocketWrapper<NioChannel> socket,
     Processor<NioChannel> processor,
     boolean isSocketClosing,
     boolean addToPoller) {
   processor.recycle(isSocketClosing);
   recycledProcessors.offer(processor);
   if (addToPoller) {
     // The only time this method is called with addToPoller == true
     // is when the socket is in keep-alive so set the appropriate
     // timeout.
     socket.setTimeout(getProtocol().getKeepAliveTimeout());
     socket.getSocket().getPoller().add(socket.getSocket());
   }
 }
Example #2
0
  /**
   * Process pipelined HTTP requests using the specified input and output streams.
   *
   * @throws IOException error during an I/O operation
   */
  @Override
  public SocketState process(SocketWrapper<NioChannel> socket) throws IOException {
    RequestInfo rp = request.getRequestProcessor();
    rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);

    // Setting up the socket
    this.socketWrapper = socket;

    long soTimeout = endpoint.getSoTimeout();
    boolean cping = false;

    // Error flag
    error = false;

    while (!error && !endpoint.isPaused()) {
      // Parsing the request header
      try {
        // Get first message of the request
        int bytesRead = readMessage(requestHeaderMessage, false);
        if (bytesRead == 0) {
          break;
        }
        // Set back timeout if keep alive timeout is enabled
        if (keepAliveTimeout > 0) {
          socket.setTimeout(soTimeout);
        }
        // Check message type, process right away and break if
        // not regular request processing
        int type = requestHeaderMessage.getByte();
        if (type == Constants.JK_AJP13_CPING_REQUEST) {
          if (endpoint.isPaused()) {
            recycle(true);
            break;
          }
          cping = true;
          try {
            output(pongMessageArray, 0, pongMessageArray.length);
          } catch (IOException e) {
            error = true;
          }
          recycle(false);
          continue;
        } else if (type != Constants.JK_AJP13_FORWARD_REQUEST) {
          // Unexpected packet type. Unread body packets should have
          // been swallowed in finish().
          if (log.isDebugEnabled()) {
            log.debug("Unexpected message: " + type);
          }
          error = true;
          recycle(true);
          break;
        }
        request.setStartTime(System.currentTimeMillis());
      } catch (IOException e) {
        error = true;
        break;
      } catch (Throwable t) {
        ExceptionUtils.handleThrowable(t);
        log.debug(sm.getString("ajpprocessor.header.error"), t);
        // 400 - Bad Request
        response.setStatus(400);
        adapter.log(request, response, 0);
        error = true;
      }

      if (!error) {
        // Setting up filters, and parse some request headers
        rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
        try {
          prepareRequest();
        } catch (Throwable t) {
          ExceptionUtils.handleThrowable(t);
          log.debug(sm.getString("ajpprocessor.request.prepare"), t);
          // 400 - Internal Server Error
          response.setStatus(400);
          adapter.log(request, response, 0);
          error = true;
        }
      }

      if (!error && !cping && endpoint.isPaused()) {
        // 503 - Service unavailable
        response.setStatus(503);
        adapter.log(request, response, 0);
        error = true;
      }
      cping = false;

      // Process the request in the adapter
      if (!error) {
        try {
          rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
          adapter.service(request, response);
        } catch (InterruptedIOException e) {
          error = true;
        } catch (Throwable t) {
          ExceptionUtils.handleThrowable(t);
          log.error(sm.getString("ajpprocessor.request.process"), t);
          // 500 - Internal Server Error
          response.setStatus(500);
          adapter.log(request, response, 0);
          error = true;
        }
      }

      if (isAsync() && !error) {
        break;
      }

      // Finish the response if not done yet
      if (!finished) {
        try {
          finish();
        } catch (Throwable t) {
          ExceptionUtils.handleThrowable(t);
          error = true;
        }
      }

      // If there was an error, make sure the request is counted as
      // and error, and update the statistics counter
      if (error) {
        response.setStatus(500);
      }
      request.updateCounters();

      rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
      // Set keep alive timeout if enabled
      if (keepAliveTimeout > 0) {
        socket.setTimeout(keepAliveTimeout);
      }

      recycle(false);
    }

    rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);

    if (!error && !endpoint.isPaused()) {
      if (isAsync()) {
        return SocketState.LONG;
      } else {
        return SocketState.OPEN;
      }
    } else {
      return SocketState.CLOSED;
    }
  }
  /**
   * Send an action to the connector.
   *
   * @param actionCode Type of the action
   * @param param Action parameter
   */
  @Override
  public void actionInternal(ActionCode actionCode, Object param) {

    if (actionCode == ActionCode.REQ_SSL_ATTRIBUTE) {

      try {
        if (sslSupport != null) {
          Object sslO = sslSupport.getCipherSuite();
          if (sslO != null) request.setAttribute(SSLSupport.CIPHER_SUITE_KEY, sslO);
          sslO = sslSupport.getPeerCertificateChain(false);
          if (sslO != null) request.setAttribute(SSLSupport.CERTIFICATE_KEY, sslO);
          sslO = sslSupport.getKeySize();
          if (sslO != null) request.setAttribute(SSLSupport.KEY_SIZE_KEY, sslO);
          sslO = sslSupport.getSessionId();
          if (sslO != null) request.setAttribute(SSLSupport.SESSION_ID_KEY, sslO);
          request.setAttribute(SSLSupport.SESSION_MGR, sslSupport);
        }
      } catch (Exception e) {
        log.warn(sm.getString("http11processor.socket.ssl"), e);
      }

    } else if (actionCode == ActionCode.REQ_HOST_ADDR_ATTRIBUTE) {

      if ((remoteAddr == null) && (socket != null)) {
        InetAddress inetAddr = socket.getSocket().getInetAddress();
        if (inetAddr != null) {
          remoteAddr = inetAddr.getHostAddress();
        }
      }
      request.remoteAddr().setString(remoteAddr);

    } else if (actionCode == ActionCode.REQ_LOCAL_NAME_ATTRIBUTE) {

      if ((localName == null) && (socket != null)) {
        InetAddress inetAddr = socket.getSocket().getLocalAddress();
        if (inetAddr != null) {
          localName = inetAddr.getHostName();
        }
      }
      request.localName().setString(localName);

    } else if (actionCode == ActionCode.REQ_HOST_ATTRIBUTE) {

      if ((remoteHost == null) && (socket != null)) {
        InetAddress inetAddr = socket.getSocket().getInetAddress();
        if (inetAddr != null) {
          remoteHost = inetAddr.getHostName();
        }
        if (remoteHost == null) {
          if (remoteAddr != null) {
            remoteHost = remoteAddr;
          } else { // all we can do is punt
            request.remoteHost().recycle();
          }
        }
      }
      request.remoteHost().setString(remoteHost);

    } else if (actionCode == ActionCode.REQ_LOCAL_ADDR_ATTRIBUTE) {

      if (localAddr == null) localAddr = socket.getSocket().getLocalAddress().getHostAddress();

      request.localAddr().setString(localAddr);

    } else if (actionCode == ActionCode.REQ_REMOTEPORT_ATTRIBUTE) {

      if ((remotePort == -1) && (socket != null)) {
        remotePort = socket.getSocket().getPort();
      }
      request.setRemotePort(remotePort);

    } else if (actionCode == ActionCode.REQ_LOCALPORT_ATTRIBUTE) {

      if ((localPort == -1) && (socket != null)) {
        localPort = socket.getSocket().getLocalPort();
      }
      request.setLocalPort(localPort);

    } else if (actionCode == ActionCode.REQ_SSL_CERTIFICATE) {
      if (sslSupport != null) {
        /*
         * Consume and buffer the request body, so that it does not
         * interfere with the client's handshake messages
         */
        InputFilter[] inputFilters = inputBuffer.getFilters();
        ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]).setLimit(maxSavePostSize);
        inputBuffer.addActiveFilter(inputFilters[Constants.BUFFERED_FILTER]);
        try {
          Object sslO = sslSupport.getPeerCertificateChain(true);
          if (sslO != null) {
            request.setAttribute(SSLSupport.CERTIFICATE_KEY, sslO);
          }
        } catch (Exception e) {
          log.warn(sm.getString("http11processor.socket.ssl"), e);
        }
      }
    } else if (actionCode == ActionCode.ASYNC_COMPLETE) {
      if (asyncStateMachine.asyncComplete()) {
        ((JIoEndpoint) endpoint).processSocketAsync(this.socket, SocketStatus.OPEN);
      }
    } else if (actionCode == ActionCode.ASYNC_SETTIMEOUT) {
      if (param == null) return;
      long timeout = ((Long) param).longValue();
      // if we are not piggy backing on a worker thread, set the timeout
      socket.setTimeout(timeout);
    } else if (actionCode == ActionCode.ASYNC_DISPATCH) {
      if (asyncStateMachine.asyncDispatch()) {
        ((JIoEndpoint) endpoint).processSocketAsync(this.socket, SocketStatus.OPEN);
      }
    }
  }