package com.firefly.server.http2;
import com.firefly.codec.http2.decode.HttpParser.RequestHandler;
import com.firefly.codec.http2.model.*;
import com.firefly.server.http2.HTTP1ServerConnection.HTTP1ServerResponseOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
public class HTTP1ServerRequestHandler implements RequestHandler {
protected static final Logger log = LoggerFactory.getLogger("firefly-system");
protected MetaData.Request request;
protected MetaData.Response response;
protected HTTP1ServerConnection connection;
protected HTTP1ServerResponseOutputStream outputStream;
protected final ServerHTTPHandler serverHTTPHandler;
protected HttpFields trailer;
HTTP1ServerRequestHandler(ServerHTTPHandler serverHTTPHandler) {
this.serverHTTPHandler = serverHTTPHandler;
}
@Override
public boolean startRequest(String method, String uri, HttpVersion version) {
if (log.isDebugEnabled()) {
log.debug("server received the request line, {}, {}, {}", method, uri, version);
}
request = new HTTPServerRequest(method, uri, version);
response = new HTTPServerResponse();
outputStream = new HTTP1ServerResponseOutputStream(response, connection);
return HttpMethod.PRI.is(method) && connection.upgradeProtocolToHTTP2(request, response);
}
@Override
public void parsedHeader(HttpField field) {
request.getFields().add(field);
}
@Override
public boolean headerComplete() {
if (HttpMethod.CONNECT.asString().equalsIgnoreCase(request.getMethod())) {
return serverHTTPHandler.acceptHTTPTunnelConnection(request, response, outputStream, connection);
} else {
String expectedValue = request.getFields().get(HttpHeader.EXPECT);
if ("100-continue".equalsIgnoreCase(expectedValue)) {
boolean skipNext = serverHTTPHandler.accept100Continue(request, response, outputStream, connection);
if (skipNext) {
return true;
} else {
connection.response100Continue();
return serverHTTPHandler.headerComplete(request, response, outputStream, connection);
}
} else {
boolean success = connection.upgradeProtocolToHTTP2(request, response);
return success || serverHTTPHandler.headerComplete(request, response, outputStream, connection);
}
}
}
@Override
public boolean content(ByteBuffer item) {
return serverHTTPHandler.content(item, request, response, outputStream, connection);
}
@Override
public boolean contentComplete() {
return serverHTTPHandler.contentComplete(request, response, outputStream, connection);
}
@Override
public void parsedTrailer(HttpField field) {
if (trailer == null) {
trailer = new HttpFields();
request.setTrailerSupplier(() -> trailer);
}
trailer.add(field);
}
@Override
public boolean messageComplete() {
try {
return connection.upgradeHTTP2Successfully || serverHTTPHandler.messageComplete(request, response, outputStream, connection);
} finally {
connection.getParser().reset();
}
}
@Override
public void badMessage(int status, String reason) {
serverHTTPHandler.badMessage(status, reason, request, response, outputStream, connection);
}
@Override
public void earlyEOF() {
serverHTTPHandler.earlyEOF(request, response, outputStream, connection);
}
@Override
public int getHeaderCacheSize() {
return 1024;
}
}