예제 #1
0
 private void handleError(StreamSinkChannel c, String m, Throwable t) {
   if (t instanceof IOException) UndertowLogger.REQUEST_IO_LOGGER.ioException((IOException) t);
   else UndertowLogger.REQUEST_IO_LOGGER.error(m, t);
   cleanup();
   c.getWriteSetter().set(null);
   IoUtils.safeClose(c);
 }
예제 #2
0
  private void handleError(IOException e) {

    UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
    IoUtils.safeClose(SpdyClientConnection.this);
    for (Map.Entry<Integer, SpdyClientExchange> entry : currentExchanges.entrySet()) {
      try {
        entry.getValue().failed(e);
      } catch (Exception ex) {
        UndertowLogger.REQUEST_IO_LOGGER.ioException(new IOException(ex));
      }
    }
  }
예제 #3
0
    @Override
    public void handleEvent(SpdyChannel channel) {
      try {
        SpdyStreamSourceChannel result = channel.receive();
        if (result instanceof SpdySynReplyStreamSourceChannel) {
          final int streamId = ((SpdySynReplyStreamSourceChannel) result).getStreamId();
          SpdyClientExchange request = currentExchanges.get(streamId);
          result.addCloseTask(
              new ChannelListener<SpdyStreamSourceChannel>() {
                @Override
                public void handleEvent(SpdyStreamSourceChannel channel) {
                  currentExchanges.remove(streamId);
                }
              });
          if (request == null) {

            // server side initiated stream, we can't deal with that at the moment
            // just fail
            // TODO: either handle this properly or at the very least send RST_STREAM
            channel.sendGoAway(SpdyChannel.CLOSE_PROTOCOL_ERROR);
            IoUtils.safeClose(SpdyClientConnection.this);
            return;
          }
          request.responseReady((SpdySynReplyStreamSourceChannel) result);

        } else if (result instanceof SpdyPingStreamSourceChannel) {
          handlePing((SpdyPingStreamSourceChannel) result);
        } else if (result instanceof SpdyRstStreamStreamSourceChannel) {
          int stream = ((SpdyRstStreamStreamSourceChannel) result).getStreamId();
          UndertowLogger.REQUEST_LOGGER.debugf("Client received RST_STREAM for stream %s", stream);
          SpdyClientExchange exchange = currentExchanges.get(stream);
          if (exchange != null) {
            exchange.failed(UndertowMessages.MESSAGES.spdyStreamWasReset());
          }
        } else if (!channel.isOpen()) {
          throw UndertowMessages.MESSAGES.channelIsClosed();
        }

      } catch (IOException e) {
        UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
        IoUtils.safeClose(SpdyClientConnection.this);
        for (Map.Entry<Integer, SpdyClientExchange> entry : currentExchanges.entrySet()) {
          try {
            entry.getValue().failed(e);
          } catch (Exception ex) {
            UndertowLogger.REQUEST_IO_LOGGER.ioException(new IOException(ex));
          }
        }
      }
    }
예제 #4
0
 @Override
 public void handleEvent(final StreamSinkChannel channel) {
   HeaderMap trailers = source.getAttachment(HttpAttachments.REQUEST_TRAILERS);
   if (trailers != null) {
     target.putAttachment(HttpAttachments.RESPONSE_TRAILERS, trailers);
   }
   try {
     channel.shutdownWrites();
     if (!channel.flush()) {
       channel
           .getWriteSetter()
           .set(
               ChannelListeners.flushingChannelListener(
                   new ChannelListener<StreamSinkChannel>() {
                     @Override
                     public void handleEvent(StreamSinkChannel channel) {
                       channel.suspendWrites();
                       channel.getWriteSetter().set(null);
                     }
                   },
                   ChannelListeners.closingChannelExceptionHandler()));
       channel.resumeWrites();
     } else {
       channel.getWriteSetter().set(null);
       channel.shutdownWrites();
     }
   } catch (IOException e) {
     UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
     IoUtils.safeClose(channel);
   }
 }
예제 #5
0
 @Override
 public void handleException(Channel channel, IOException exception) {
   IoUtils.safeClose(channel);
   IoUtils.safeClose(clientConnection);
   if (exchange.isResponseStarted()) {
     UndertowLogger.REQUEST_IO_LOGGER.debug("Exception reading from target server", exception);
     if (!exchange.isResponseStarted()) {
       exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
       exchange.endExchange();
     } else {
       IoUtils.safeClose(exchange.getConnection());
     }
   } else {
     UndertowLogger.REQUEST_IO_LOGGER.ioException(exception);
     exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
     exchange.endExchange();
   }
 }
  @Override
  public void handleEvent(StreamConnection channel) {
    // set read and write timeouts
    try {
      Integer readTimeout = channel.getOption(Options.READ_TIMEOUT);
      Integer idleTimeout = undertowOptions.get(UndertowOptions.IDLE_TIMEOUT);
      if ((readTimeout == null || readTimeout <= 0) && idleTimeout != null) {
        readTimeout = idleTimeout;
      } else if (readTimeout != null && idleTimeout != null && idleTimeout > 0) {
        readTimeout = Math.min(readTimeout, idleTimeout);
      }
      if (readTimeout != null && readTimeout > 0) {
        channel
            .getSourceChannel()
            .setConduit(
                new ReadTimeoutStreamSourceConduit(
                    channel.getSourceChannel().getConduit(), channel, this));
      }
      Integer writeTimeout = channel.getOption(Options.WRITE_TIMEOUT);
      if ((writeTimeout == null || writeTimeout <= 0) && idleTimeout != null) {
        writeTimeout = idleTimeout;
      } else if (writeTimeout != null && idleTimeout != null && idleTimeout > 0) {
        writeTimeout = Math.min(writeTimeout, idleTimeout);
      }
      if (writeTimeout != null && writeTimeout > 0) {
        channel
            .getSinkChannel()
            .setConduit(
                new WriteTimeoutStreamSinkConduit(
                    channel.getSinkChannel().getConduit(), channel, this));
      }
    } catch (IOException e) {
      IoUtils.safeClose(channel);
      UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
    }

    final PortForwardServerConnection connection =
        new PortForwardServerConnection(channel, bufferPool, undertowOptions, bufferSize);
    connection
        .getWorker()
        .execute(
            new Runnable() {
              @Override
              public void run() {
                try {
                  connection.startForwarding(
                      masterPortForwardConnection,
                      urlPath,
                      targetPort,
                      requestId.getAndIncrement());
                } catch (IOException e) {
                } finally {
                  IoUtils.safeClose(connection);
                }
              }
            });
  }
예제 #7
0
 private void sendBadRequestAndClose(final StreamConnection channel, final Exception exception) {
   UndertowLogger.REQUEST_IO_LOGGER.failedToParseRequest(exception);
   channel.getSourceChannel().suspendReads();
   new StringWriteChannelListener(BAD_REQUEST) {
     @Override
     protected void writeDone(final StreamSinkChannel c) {
       IoUtils.safeClose(channel);
     }
   }.setup(channel.getSinkChannel());
 }
 @Override
 public void handleEvent(final StreamSourceChannel channel) {
   if (anyAreClear(state, FLAG_FINISHED)) {
     try {
       state |= FLAG_READY;
       channel.suspendReads();
       listener.onDataAvailable();
     } catch (IOException e) {
       UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
       IoUtils.safeClose(channel);
     }
   }
   if (anyAreSet(state, FLAG_FINISHED) && anyAreClear(state, FLAG_ON_DATA_READ_CALLED)) {
     state |= FLAG_ON_DATA_READ_CALLED;
     try {
       channel.shutdownReads();
       listener.onAllDataRead();
     } catch (IOException e) {
       IoUtils.safeClose(channel);
     }
   } else if (allAreClear(state, FLAG_FINISHED)) {
     channel.resumeReads();
   }
 }
예제 #9
0
  public void handleEvent(final StreamSourceChannel channel) {

    Pooled<ByteBuffer> existing = connection.getExtraBytes();

    final Pooled<ByteBuffer> pooled =
        existing == null ? connection.getBufferPool().allocate() : existing;
    final ByteBuffer buffer = pooled.getResource();
    boolean free = true;

    try {
      int res;
      do {
        if (existing == null) {
          buffer.clear();
          try {
            res = channel.read(buffer);
          } catch (IOException e) {
            UndertowLogger.REQUEST_IO_LOGGER.debug("Error reading request", e);
            IoUtils.safeClose(connection);
            return;
          }
        } else {
          res = buffer.remaining();
        }

        if (res == 0) {
          if (!channel.isReadResumed()) {
            channel.getReadSetter().set(this);
            channel.resumeReads();
          }
          return;
        } else if (res == -1) {
          try {
            channel.suspendReads();
            channel.shutdownReads();
            final StreamSinkChannel responseChannel = this.connection.getChannel().getSinkChannel();
            responseChannel.shutdownWrites();
            // will return false if there's a response queued ahead of this one, so we'll set up a
            // listener then
            if (!responseChannel.flush()) {
              responseChannel
                  .getWriteSetter()
                  .set(ChannelListeners.flushingChannelListener(null, null));
              responseChannel.resumeWrites();
            }
          } catch (IOException e) {
            UndertowLogger.REQUEST_IO_LOGGER.debug("Error reading request", e);
            // f**k it, it's all ruined
            IoUtils.safeClose(channel);
            return;
          }
          return;
        }
        if (existing != null) {
          existing = null;
          connection.setExtraBytes(null);
        } else {
          buffer.flip();
        }
        parser.handle(buffer, state, httpServerExchange);
        if (buffer.hasRemaining()) {
          free = false;
          connection.setExtraBytes(pooled);
        }
        int total = read + res;
        read = total;
        if (read > maxRequestSize) {
          UndertowLogger.REQUEST_LOGGER.requestHeaderWasTooLarge(
              connection.getPeerAddress(), maxRequestSize);
          IoUtils.safeClose(connection);
          return;
        }
      } while (!state.isComplete());

      // we remove ourselves as the read listener from the channel;
      // if the http handler doesn't set any then reads will suspend, which is the right thing to do
      channel.getReadSetter().set(null);
      channel.suspendReads();

      final HttpServerExchange httpServerExchange = this.httpServerExchange;
      httpServerExchange.putAttachment(
          UndertowOptions.ATTACHMENT_KEY, connection.getUndertowOptions());
      httpServerExchange.setRequestScheme(connection.getSslSession() != null ? "https" : "http");
      this.httpServerExchange = null;
      HttpTransferEncoding.setupRequest(httpServerExchange);
      HttpHandlers.executeRootHandler(
          connection.getRootHandler(),
          httpServerExchange,
          Thread.currentThread() instanceof XnioExecutor);
    } catch (Exception e) {
      sendBadRequestAndClose(connection.getChannel(), e);
      return;
    } finally {
      if (free) pooled.free();
    }
  }