package org.webpieces.frontend.impl; import java.nio.ByteBuffer; import java.util.Optional; import org.webpieces.frontend.api.FrontendConfig; import org.webpieces.frontend.api.HttpServerSocket; import org.webpieces.httpparser.api.HttpParser; import org.webpieces.nio.api.channels.Channel; import org.webpieces.nio.api.channels.ChannelSession; import org.webpieces.nio.api.channels.TCPChannel; import org.webpieces.nio.api.handlers.AsyncDataListener; import com.webpieces.hpack.api.HpackParser; class ServerDataListener implements AsyncDataListener { private TimedRequestListener timedRequestListener; private Http11DataListener http11DataListener; private HttpParser httpParser; private HpackParser http2Parser; private FrontendConfig frontendConfig; private HttpServerSocket getHttpServerSocketForChannel(Channel channel) { ChannelSession session = channel.getSession(); HttpServerSocket httpServerSocket = (HttpServerSocket) session.get("webpieces.httpServerSocket"); if(httpServerSocket == null) { // Default to HTTP/1.1 but pass in the parser so that we can upgrade to http2. httpServerSocket = new HttpServerSocketImpl( channel, http11DataListener, new Http11ResponseSender(channel, httpParser), http2Parser, timedRequestListener, frontendConfig ); session.put("webpieces.httpServerSocket", httpServerSocket); } return httpServerSocket; } ServerDataListener(TimedRequestListener timedRequestListener, Http11DataListener http11DataListener, HttpParser httpParser, HpackParser http2Parser, FrontendConfig frontendConfig) { this.timedRequestListener = timedRequestListener; this.http11DataListener = http11DataListener; this.httpParser = httpParser; this.http2Parser = http2Parser; this.frontendConfig = frontendConfig; } @Override public void connectionOpened(TCPChannel tcpChannel, boolean isReadyForWrites) { HttpServerSocket socket = getHttpServerSocketForChannel(tcpChannel); // TODO: replace 'false' with ALPN check if((isReadyForWrites && tcpChannel.isSslChannel() && false) || frontendConfig.alwaysHttp2) { // If ALPN, upgrade to HTTP2 socket.upgradeHttp2(Optional.empty()); } timedRequestListener.openedConnection(socket, isReadyForWrites); } @Override public void incomingData(Channel channel, ByteBuffer b) { getHttpServerSocketForChannel(channel).getDataListener().incomingData(channel, b); } @Override public void farEndClosed(Channel channel) { getHttpServerSocketForChannel(channel).getDataListener().farEndClosed(channel); } @Override public void failure(Channel channel, ByteBuffer data, Exception e) { getHttpServerSocketForChannel(channel).getDataListener().failure(channel, data, e); } @Override public void applyBackPressure(Channel channel) { getHttpServerSocketForChannel(channel).getDataListener().applyBackPressure(channel); } @Override public void releaseBackPressure(Channel channel) { getHttpServerSocketForChannel(channel).getDataListener().releaseBackPressure(channel); } }