in httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpService.java [196:295]
public void handleRequest(
final HttpServerConnection conn,
final HttpContext localContext) throws IOException, HttpException {
final AtomicBoolean responseSubmitted = new AtomicBoolean();
final HttpCoreContext context = HttpCoreContext.cast(localContext);
try {
final ClassicHttpRequest request = conn.receiveRequestHeader();
if (request == null) {
conn.close();
return;
}
if (streamListener != null) {
streamListener.onRequestHead(conn, request);
}
conn.receiveRequestEntity(request);
final ProtocolVersion transportVersion = request.getVersion();
if (transportVersion != null && transportVersion.greaterEquals(HttpVersion.HTTP_2)) {
throw new UnsupportedHttpVersionException(transportVersion);
}
context.setProtocolVersion(transportVersion != null ? transportVersion : http1Config.getVersion());
context.setRequest(request);
context.setSSLSession(conn.getSSLSession());
context.setEndpointDetails(conn.getEndpointDetails());
this.processor.process(request, request.getEntity(), context);
this.requestHandler.handle(request, new HttpServerRequestHandler.ResponseTrigger() {
@Override
public void sendInformation(final ClassicHttpResponse response) throws HttpException, IOException {
if (responseSubmitted.get()) {
throw new HttpException("Response already submitted");
}
if (response.getCode() >= HttpStatus.SC_SUCCESS) {
throw new HttpException("Invalid intermediate response");
}
if (streamListener != null) {
streamListener.onResponseHead(conn, response);
}
conn.sendResponseHeader(response);
conn.flush();
}
@Override
public void submitResponse(final ClassicHttpResponse response) throws HttpException, IOException {
try {
final ProtocolVersion transportVersion = response.getVersion();
if (transportVersion != null) {
if (!transportVersion.lessEquals(http1Config.getVersion())) {
throw new UnsupportedHttpVersionException(transportVersion);
}
context.setProtocolVersion(transportVersion);
}
context.setResponse(response);
processor.process(response, response.getEntity(), context);
responseSubmitted.set(true);
conn.sendResponseHeader(response);
if (streamListener != null) {
streamListener.onResponseHead(conn, response);
}
if (MessageSupport.canResponseHaveBody(request.getMethod(), response)) {
conn.sendResponseEntity(response);
}
// Make sure the request content is fully consumed
EntityUtils.consume(request.getEntity());
final boolean keepAlive = connReuseStrategy.keepAlive(request, response, context);
if (streamListener != null) {
streamListener.onExchangeComplete(conn, keepAlive);
}
if (!keepAlive) {
conn.close();
}
conn.flush();
} finally {
response.close();
}
}
}, context);
} catch (final HttpException ex) {
if (responseSubmitted.get()) {
throw ex;
}
try (final ClassicHttpResponse errorResponse = new BasicClassicHttpResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR)) {
handleException(ex, errorResponse);
errorResponse.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
context.setResponse(errorResponse);
this.processor.process(errorResponse, errorResponse.getEntity(), context);
conn.sendResponseHeader(errorResponse);
if (streamListener != null) {
streamListener.onResponseHead(conn, errorResponse);
}
conn.sendResponseEntity(errorResponse);
conn.close();
}
}
}