HttpReadListener(final HttpServerConnection connection, final HttpRequestParser parser) { this.connection = connection; this.parser = parser; maxRequestSize = connection .getUndertowOptions() .get(UndertowOptions.MAX_HEADER_SIZE, UndertowOptions.DEFAULT_MAX_HEADER_SIZE); this.maxEntitySize = connection.getUndertowOptions().get(UndertowOptions.MAX_ENTITY_SIZE, 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(); } }