/**
   * Connect this socket wrapper to remote server and start main loop on AprSocketSource stdout
   * link, to watch for incoming data, and AprSocketSink stdin link, to pull for outgoing data.
   */
  @Override
  public void connect(InetSocketAddress address) throws IOException {
    try {
      inetAddress =
          Address.info(address.getHostName(), Socket.APR_UNSPEC, address.getPort(), 0, pool);
      socket =
          Socket.create(
              Address.getInfo(inetAddress).family, Socket.SOCK_STREAM, Socket.APR_PROTO_TCP, pool);
    } catch (Exception e) {
      throw new IOException(
          "[" + this + "] ERROR: Cannot create socket for \"" + address + "\".", e);
    }

    int ret = Socket.connect(socket, inetAddress);
    if (ret != 0)
      throw new IOException(
          "["
              + this
              + "] ERROR: Cannot connect to remote host \""
              + address
              + "\": "
              + Error.strerror(ret));

    source.setSocket(socket);
    sink.setSocket(socket);

    // Start polling for data to send to remote sever
    runMainLoop(IN, STDIN, true, true);

    // Push incoming data from server to handlers
    runMainLoop(OUT, STDOUT, false, false);
  }
  private void closeImmediately0() {
    // We need to close the channel immediately to remove it from the
    // server session's channel table and *not* send a packet to the
    // client.  A notification was already sent by our caller, or will
    // be sent after we return.
    //
    super.close(true);

    // We also need to close the socket.
    Socket.close(handle);

    try {
      if ((forwarder != null) && (!forwarder.isDone())) {
        forwarder.cancel(true);
      }
    } finally {
      forwarder = null;
    }

    try {
      if ((forwardService != null) && shutdownForwarder) {
        Collection<?> runners = forwardService.shutdownNow();
        if (log.isDebugEnabled()) {
          log.debug("Shut down runners count=" + GenericUtils.size(runners));
        }
      }
    } finally {
      forwardService = null;
      shutdownForwarder = false;
    }
  }
  /** Read at least the specified amount of bytes, and place them in the input buffer. */
  protected boolean readt(int n, boolean useAvailableData) throws IOException {

    if (useAvailableData && inputBuffer.remaining() == 0) {
      return false;
    }
    if (inputBuffer.capacity() - inputBuffer.limit() <= n - inputBuffer.remaining()) {
      inputBuffer.compact();
      inputBuffer.limit(inputBuffer.position());
      inputBuffer.position(0);
    }
    int nRead;
    while (inputBuffer.remaining() < n) {
      nRead =
          Socket.recvbb(
              getSocketWrapper().getSocket().longValue(),
              inputBuffer.limit(),
              inputBuffer.capacity() - inputBuffer.limit());
      if (nRead > 0) {
        inputBuffer.limit(inputBuffer.limit() + nRead);
      } else {
        if ((-nRead) == Status.getEtimedout() || (-nRead) == Status.getTimeup()) {
          return false;
        } else {
          throw new IOException(getSm().getString("ajpprocessor.failedread"));
        }
      }
    }

    return true;
  }
 /** {@inheritDoc} */
 public boolean isReuseAddress() {
   try {
     return Socket.optGet(getDescriptor(), Socket.APR_SO_REUSEADDR) == 1;
   } catch (Exception e) {
     throw new RuntimeIoException("Failed to get SO_REUSEADDR.", e);
   }
 }
 /** {@inheritDoc} */
 public int getReceiveBufferSize() {
   try {
     return Socket.optGet(getDescriptor(), Socket.APR_SO_RCVBUF);
   } catch (Exception e) {
     throw new RuntimeException("APR Exception", e);
   }
 }
示例#6
0
 public void run() {
   try {
     byte[] buf = new byte[1024];
     while (true) {
       int result = Socket.recv(socket, buf, 0, buf.length);
       if (result == Status.APR_EOF) {
         break;
       } else if (result < Status.APR_SUCCESS) {
         throwException(result);
       }
       messageReceived(new Buffer(buf, 0, result));
     }
   } catch (Exception e) {
     e.printStackTrace();
   } finally {
     Socket.close(socket);
   }
 }
 @Override
 protected void doWriteData(byte[] data, int off, long len) throws IOException {
   ValidateUtils.checkTrue(
       len <= Integer.MAX_VALUE, "Data length exceeds int boundaries: %d", len);
   int result = Socket.send(handle, data, off, (int) len);
   if (result < Status.APR_SUCCESS) {
     throwException(result);
   }
 }
  @Override
  protected OpenFuture doInit(Buffer buffer) {
    OpenFuture f = new DefaultOpenFuture(this);
    try {
      out =
          new ChannelOutputStream(
              this, getRemoteWindow(), log, SshConstants.SSH_MSG_CHANNEL_DATA, true);
      authSocket = PropertyResolverUtils.getString(this, SshAgent.SSH_AUTHSOCKET_ENV_NAME);
      pool = Pool.create(AprLibrary.getInstance().getRootPool());
      handle = Local.create(authSocket, pool);
      int result = Local.connect(handle, 0);
      if (result != Status.APR_SUCCESS) {
        throwException(result);
      }

      ExecutorService service = getExecutorService();
      forwardService =
          (service == null)
              ? ThreadUtils.newSingleThreadExecutor("ChannelAgentForwarding[" + authSocket + "]")
              : service;
      shutdownForwarder = service != forwardService || isShutdownOnExit();

      final int copyBufSize =
          PropertyResolverUtils.getIntProperty(
              this, FORWARDER_BUFFER_SIZE, DEFAULT_FORWARDER_BUF_SIZE);
      ValidateUtils.checkTrue(
          copyBufSize >= MIN_FORWARDER_BUF_SIZE, "Copy buf size below min.: %d", copyBufSize);
      ValidateUtils.checkTrue(
          copyBufSize <= MAX_FORWARDER_BUF_SIZE, "Copy buf size above max.: %d", copyBufSize);

      forwarder =
          forwardService.submit(
              () -> {
                try {
                  byte[] buf = new byte[copyBufSize];
                  while (true) {
                    int len = Socket.recv(handle, buf, 0, buf.length);
                    if (len > 0) {
                      out.write(buf, 0, len);
                      out.flush();
                    }
                  }
                } catch (IOException e) {
                  close(true);
                }
              });

      signalChannelOpenSuccess();
      f.setOpened();
    } catch (Throwable t) {
      Throwable e = GenericUtils.peelException(t);
      signalChannelOpenFailure(e);
      f.setException(e);
    }

    return f;
  }
  void destroyPull() {
    if (shutdowned) return;

    // Causes segfault in AprSocketSource.poll() method, so this function must be called from it
    try {
      Socket.close(socket);
      // or
      // Socket.shutdown(socket, Socket.APR_SHUTDOWN_READWRITE);
      Pool.destroy(pool);
    } catch (Exception e) {
      s_logger.info("[ignored]" + "failure during network cleanup: " + e.getLocalizedMessage());
    }
  }
  @Override
  protected void output(byte[] src, int offset, int length) throws IOException {
    outputBuffer.put(src, offset, length);

    long socketRef = getSocketWrapper().getSocket().longValue();

    if (outputBuffer.position() > 0) {
      if ((socketRef != 0) && Socket.sendbb(socketRef, 0, outputBuffer.position()) < 0) {
        // There are no re-tries so clear the buffer to prevent a
        // possible overflow if the buffer is used again. BZ53119.
        outputBuffer.clear();
        throw new IOException(getSm().getString("ajpprocessor.failedsend"));
      }
      outputBuffer.clear();
    }
  }
  /** Read at least the specified amount of bytes, and place them in the input buffer. */
  protected boolean read(int n) throws IOException {

    if (inputBuffer.capacity() - inputBuffer.limit() <= n - inputBuffer.remaining()) {
      inputBuffer.compact();
      inputBuffer.limit(inputBuffer.position());
      inputBuffer.position(0);
    }
    int nRead;
    while (inputBuffer.remaining() < n) {
      nRead =
          Socket.recvbb(
              getSocketWrapper().getSocket().longValue(),
              inputBuffer.limit(),
              inputBuffer.capacity() - inputBuffer.limit());
      if (nRead > 0) {
        inputBuffer.limit(inputBuffer.limit() + nRead);
      } else {
        throw new IOException(getSm().getString("ajpprocessor.failedread"));
      }
    }

    return true;
  }
示例#12
0
 protected void reply(Buffer buf) throws IOException {
   int result = Socket.send(socket, buf.array(), buf.rpos(), buf.available());
   if (result < Status.APR_SUCCESS) {
     throwException(result);
   }
 }
  /**
   * Process pipelined HTTP requests using the specified input and output streams.
   *
   * @throws IOException error during an I/O operation
   */
  @Override
  public SocketState process(SocketWrapper<Long> socket) throws IOException {
    RequestInfo rp = getRequest().getRequestProcessor();
    rp.setStage(Constants24.getStageParse());

    // Setting up the socket
    this.setSocketWrapper(socket);
    long socketRef = socket.getSocket().longValue();
    Socket.setrbb(socketRef, inputBuffer);
    Socket.setsbb(socketRef, outputBuffer);
    boolean cping = false;

    boolean keptAlive = false;

    while (!getErrorState().isError() && !getEndpoint().isPaused()) {
      // Parsing the request header
      try {
        // Get first message of the request
        if (!readMessage(getRequestHeaderMessage(), true, keptAlive)) {
          // This means that no data is available right now
          // (long keepalive), so that the processor should be recycled
          // and the method should return true
          break;
        }
        // Check message type, process right away and break if
        // not regular request processing
        int type = getRequestHeaderMessage().getByte();
        if (type == Constants25.getJkAjp13CpingRequest()) {
          if (getEndpoint().isPaused()) {
            recycle(true);
            break;
          }
          cping = true;
          if (Socket.send(socketRef, getPongmessagearray(), 0, getPongmessagearray().length) < 0) {
            setErrorState(ErrorState.CLOSE_NOW, null);
          }
          continue;
        } else if (type != Constants25.getJkAjp13ForwardRequest()) {
          // Unexpected packet type. Unread body packets should have
          // been swallowed in finish().
          if (log.isDebugEnabled()) {
            log.debug("Unexpected message: " + type);
          }
          setErrorState(ErrorState.CLOSE_NOW, null);
          break;
        }
        keptAlive = true;
        getRequest().setStartTime(System.currentTimeMillis());
      } catch (IOException e) {
        setErrorState(ErrorState.CLOSE_NOW, e);
        break;
      } catch (Throwable t) {
        ExceptionUtils2.handleThrowable(t);
        log.debug(getSm().getString("ajpprocessor.header.error"), t);
        // 400 - Bad Request
        getResponse().setStatus(400);
        setErrorState(ErrorState.CLOSE_CLEAN, t);
        getAdapter().log(getRequest(), getResponse(), 0);
      }

      if (!getErrorState().isError()) {
        // Setting up filters, and parse some request headers
        rp.setStage(Constants24.getStagePrepare());
        try {
          prepareRequest();
        } catch (Throwable t) {
          ExceptionUtils2.handleThrowable(t);
          log.debug(getSm().getString("ajpprocessor.request.prepare"), t);
          // 500 - Internal Server Error
          getResponse().setStatus(500);
          setErrorState(ErrorState.CLOSE_CLEAN, t);
          getAdapter().log(getRequest(), getResponse(), 0);
        }
      }

      if (!getErrorState().isError() && !cping && getEndpoint().isPaused()) {
        // 503 - Service unavailable
        getResponse().setStatus(503);
        setErrorState(ErrorState.CLOSE_CLEAN, null);
        getAdapter().log(getRequest(), getResponse(), 0);
      }
      cping = false;

      // Process the request in the adapter
      if (!getErrorState().isError()) {
        try {
          rp.setStage(Constants24.getStageService());
          getAdapter().service(getRequest(), getResponse());
        } catch (InterruptedIOException e) {
          setErrorState(ErrorState.CLOSE_NOW, e);
        } catch (Throwable t) {
          ExceptionUtils2.handleThrowable(t);
          log.error(getSm().getString("ajpprocessor.request.process"), t);
          // 500 - Internal Server Error
          getResponse().setStatus(500);
          setErrorState(ErrorState.CLOSE_CLEAN, t);
          getAdapter().log(getRequest(), getResponse(), 0);
        }
      }

      if (isAsync() && !getErrorState().isError()) {
        break;
      }

      // Finish the response if not done yet
      if (!isFinished() && getErrorState().isIoAllowed()) {
        try {
          finish();
        } catch (Throwable t) {
          ExceptionUtils2.handleThrowable(t);
          setErrorState(ErrorState.CLOSE_NOW, t);
        }
      }

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

      rp.setStage(Constants24.getStageKeepalive());
      recycle(false);
    }

    rp.setStage(Constants24.getStageEnded());

    if (!getErrorState().isError() && !getEndpoint().isPaused()) {
      if (isAsync()) {
        return SocketState.LONG;
      } else {
        return SocketState.OPEN;
      }
    } else {
      return SocketState.CLOSED;
    }
  }
示例#14
0
 public void close() {
   agent.close();
   Socket.close(handle);
 }
 /** {@inheritDoc} */
 public void setReuseAddress(boolean on) {
   Socket.optSet(getDescriptor(), Socket.APR_SO_REUSEADDR, on ? 1 : 0);
 }
 /** {@inheritDoc} */
 public void setReceiveBufferSize(int size) {
   Socket.optSet(getDescriptor(), Socket.APR_SO_RCVBUF, size);
 }
 /** {@inheritDoc} */
 public void setSendBufferSize(int size) {
   Socket.optSet(getDescriptor(), Socket.APR_SO_SNDBUF, size);
 }