package org.webpieces.frontend2.impl; import java.nio.ByteBuffer; import java.util.concurrent.CompletableFuture; import org.webpieces.frontend2.api.HttpRequestListener; import org.webpieces.frontend2.api.Protocol; import org.webpieces.util.logging.Logger; import org.webpieces.util.logging.LoggerFactory; import com.webpieces.hpack.api.dto.Http2Headers; import com.webpieces.http2engine.api.StreamWriter; import com.webpieces.http2engine.api.server.ResponseHandler; import com.webpieces.http2engine.api.server.ServerEngineListener; import com.webpieces.http2engine.api.server.StreamReference; import com.webpieces.http2parser.api.Http2Exception; import com.webpieces.http2parser.api.dto.lib.Http2Header; import com.webpieces.http2parser.api.dto.lib.Http2HeaderName; public class Layer3Http2EngineListener implements ServerEngineListener { private static final Logger log = LoggerFactory.getLogger(Layer3Http2EngineListener.class); private FrontendSocketImpl socket; private HttpRequestListener httpListener; private String scheme; public Layer3Http2EngineListener(FrontendSocketImpl socket, HttpRequestListener httpListener, boolean isHttps) { this.socket = socket; this.httpListener = httpListener; if(isHttps) scheme = "https"; else scheme = "http"; } @Override public StreamReference sendRequestToServer(Http2Headers request, ResponseHandler responseHandler) { Http2Header header = request.getHeaderLookupStruct().getHeader(Http2HeaderName.SCHEME); if(header != null) { verifyAndResetScheme(header); } else { request.addHeader(new Http2Header(Http2HeaderName.SCHEME, scheme)); } //every request received is a new stream Http2StreamImpl stream = new Http2StreamImpl(socket, responseHandler); StreamWriter writer = httpListener.incomingRequest(stream, request, Protocol.HTTP2); return new StreamRefImpl(stream, httpListener, writer); } private void verifyAndResetScheme(Http2Header header) { String value = header.getValue(); if(!scheme.equals(value)) log.error("incoming request says it is scheme="+value+" but it is actually coming from port="+scheme+" so we are overriding"); header.setValue(scheme); } @Override public CompletableFuture<Void> sendToSocket(ByteBuffer newData) { return socket.getChannel().write(newData).thenApply(c -> null); } public void closeSocket(Http2Exception reason) { socket.internalClose(); } }