in httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicServerExchangeHandler.java [106:251]
public final void handleRequest(
final HttpRequest request,
final EntityDetails entityDetails,
final ResponseChannel responseChannel,
final HttpContext context) throws HttpException, IOException {
final AtomicBoolean responseCommitted = new AtomicBoolean(false);
final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
final HttpResponse responseWrapper = new HttpResponseWrapper(response){
private void ensureNotCommitted() {
Asserts.check(!responseCommitted.get(), "Response already committed");
}
@Override
public void addHeader(final String name, final Object value) {
ensureNotCommitted();
super.addHeader(name, value);
}
@Override
public void setHeader(final String name, final Object value) {
ensureNotCommitted();
super.setHeader(name, value);
}
@Override
public void setVersion(final ProtocolVersion version) {
ensureNotCommitted();
super.setVersion(version);
}
@Override
public void setCode(final int code) {
ensureNotCommitted();
super.setCode(code);
}
@Override
public void setReasonPhrase(final String reason) {
ensureNotCommitted();
super.setReasonPhrase(reason);
}
@Override
public void setLocale(final Locale locale) {
ensureNotCommitted();
super.setLocale(locale);
}
};
final InputStream inputStream;
if (entityDetails != null) {
inputBuffer = new SharedInputBuffer(initialBufferSize);
inputStream = new ContentInputStream(inputBuffer);
} else {
inputStream = null;
}
outputBuffer = new SharedOutputBuffer(initialBufferSize);
final OutputStream outputStream = new ContentOutputStream(outputBuffer) {
private void triggerResponse() throws IOException {
try {
if (responseCommitted.compareAndSet(false, true)) {
responseChannel.sendResponse(response, new EntityDetails() {
@Override
public long getContentLength() {
return -1;
}
@Override
public String getContentType() {
final Header h = response.getFirstHeader(HttpHeaders.CONTENT_TYPE);
return h != null ? h.getValue() : null;
}
@Override
public String getContentEncoding() {
final Header h = response.getFirstHeader(HttpHeaders.CONTENT_ENCODING);
return h != null ? h.getValue() : null;
}
@Override
public boolean isChunked() {
return false;
}
@Override
public Set<String> getTrailerNames() {
return null;
}
}, context);
}
} catch (final HttpException ex) {
throw new IOException(ex.getMessage(), ex);
}
}
@Override
public void close() throws IOException {
triggerResponse();
super.close();
}
@Override
public void write(final byte[] b, final int off, final int len) throws IOException {
triggerResponse();
super.write(b, off, len);
}
@Override
public void write(final byte[] b) throws IOException {
triggerResponse();
super.write(b);
}
@Override
public void write(final int b) throws IOException {
triggerResponse();
super.write(b);
}
};
if (state.compareAndSet(State.IDLE, State.ACTIVE)) {
executor.execute(() -> {
try {
handle(request, inputStream, responseWrapper, outputStream, context);
Closer.close(inputStream);
outputStream.close();
} catch (final Exception ex) {
exception.compareAndSet(null, ex);
if (inputBuffer != null) {
inputBuffer.abort();
}
outputBuffer.abort();
} finally {
state.set(State.COMPLETED);
}
});
}
}