use of org.apache.hc.core5.http2.frame.RawFrame in project httpcomponents-core by apache.
the class H2FileServerExample method main.
public static void main(final String[] args) throws Exception {
if (args.length < 1) {
System.err.println("Please specify document root directory");
System.exit(1);
}
// Document root directory
final File docRoot = new File(args[0]);
int port = 8080;
if (args.length >= 2) {
port = Integer.parseInt(args[1]);
}
final IOReactorConfig config = IOReactorConfig.custom().setSoTimeout(15, TimeUnit.SECONDS).setTcpNoDelay(true).build();
final HttpAsyncServer server = H2ServerBootstrap.bootstrap().setIOReactorConfig(config).setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2).setStreamListener(new H2StreamListener() {
@Override
public void onHeaderInput(final HttpConnection connection, final int streamId, final List<? extends Header> headers) {
for (int i = 0; i < headers.size(); i++) {
System.out.println(connection.getRemoteAddress() + " (" + streamId + ") << " + headers.get(i));
}
}
@Override
public void onHeaderOutput(final HttpConnection connection, final int streamId, final List<? extends Header> headers) {
for (int i = 0; i < headers.size(); i++) {
System.out.println(connection.getRemoteAddress() + " (" + streamId + ") >> " + headers.get(i));
}
}
@Override
public void onFrameInput(final HttpConnection connection, final int streamId, final RawFrame frame) {
}
@Override
public void onFrameOutput(final HttpConnection connection, final int streamId, final RawFrame frame) {
}
@Override
public void onInputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
}
@Override
public void onOutputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
}
}).register("*", new AsyncServerRequestHandler<Message<HttpRequest, Void>>() {
@Override
public AsyncRequestConsumer<Message<HttpRequest, Void>> prepare(final HttpRequest request, final EntityDetails entityDetails, final HttpContext context) throws HttpException {
return new BasicRequestConsumer<>(entityDetails != null ? new DiscardingEntityConsumer<>() : null);
}
@Override
public void handle(final Message<HttpRequest, Void> message, final ResponseTrigger responseTrigger, final HttpContext context) throws HttpException, IOException {
final HttpRequest request = message.getHead();
final URI requestUri;
try {
requestUri = request.getUri();
} catch (final URISyntaxException ex) {
throw new ProtocolException(ex.getMessage(), ex);
}
final String path = requestUri.getPath();
final File file = new File(docRoot, path);
if (!file.exists()) {
System.out.println("File " + file.getPath() + " not found");
responseTrigger.submitResponse(AsyncResponseBuilder.create(HttpStatus.SC_NOT_FOUND).setEntity("<html><body><h1>File" + file.getPath() + " not found</h1></body></html>", ContentType.TEXT_HTML).build(), context);
} else if (!file.canRead() || file.isDirectory()) {
System.out.println("Cannot read file " + file.getPath());
responseTrigger.submitResponse(AsyncResponseBuilder.create(HttpStatus.SC_FORBIDDEN).setEntity("<html><body><h1>Access denied</h1></body></html>", ContentType.TEXT_HTML).build(), context);
} else {
final ContentType contentType;
final String filename = TextUtils.toLowerCase(file.getName());
if (filename.endsWith(".txt")) {
contentType = ContentType.TEXT_PLAIN;
} else if (filename.endsWith(".html") || filename.endsWith(".htm")) {
contentType = ContentType.TEXT_HTML;
} else if (filename.endsWith(".xml")) {
contentType = ContentType.TEXT_XML;
} else {
contentType = ContentType.DEFAULT_BINARY;
}
final HttpCoreContext coreContext = HttpCoreContext.adapt(context);
final EndpointDetails endpoint = coreContext.getEndpointDetails();
System.out.println(endpoint + ": serving file " + file.getPath());
responseTrigger.submitResponse(AsyncResponseBuilder.create(HttpStatus.SC_OK).setEntity(AsyncEntityProducers.create(file, contentType)).build(), context);
}
}
}).create();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("HTTP server shutting down");
server.close(CloseMode.GRACEFUL);
}));
server.start();
final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(port), URIScheme.HTTP);
final ListenerEndpoint listenerEndpoint = future.get();
System.out.print("Listening on " + listenerEndpoint.getAddress());
server.awaitShutdown(TimeValue.ofDays(Long.MAX_VALUE));
}
use of org.apache.hc.core5.http2.frame.RawFrame in project httpcomponents-core by apache.
the class H2MultiStreamExecutionExample method main.
public static void main(final String[] args) throws Exception {
// Create and start requester
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setSoTimeout(5, TimeUnit.SECONDS).build();
final H2Config h2Config = H2Config.custom().setPushEnabled(false).setMaxConcurrentStreams(100).build();
final HttpAsyncRequester requester = H2RequesterBootstrap.bootstrap().setIOReactorConfig(ioReactorConfig).setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2).setH2Config(h2Config).setStreamListener(new H2StreamListener() {
@Override
public void onHeaderInput(final HttpConnection connection, final int streamId, final List<? extends Header> headers) {
for (int i = 0; i < headers.size(); i++) {
System.out.println(connection.getRemoteAddress() + " (" + streamId + ") << " + headers.get(i));
}
}
@Override
public void onHeaderOutput(final HttpConnection connection, final int streamId, final List<? extends Header> headers) {
for (int i = 0; i < headers.size(); i++) {
System.out.println(connection.getRemoteAddress() + " (" + streamId + ") >> " + headers.get(i));
}
}
@Override
public void onFrameInput(final HttpConnection connection, final int streamId, final RawFrame frame) {
}
@Override
public void onFrameOutput(final HttpConnection connection, final int streamId, final RawFrame frame) {
}
@Override
public void onInputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
}
@Override
public void onOutputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
}
}).create();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("HTTP requester shutting down");
requester.close(CloseMode.GRACEFUL);
}));
requester.start();
final HttpHost target = new HttpHost("nghttp2.org");
final String[] requestUris = new String[] { "/httpbin/ip", "/httpbin/user-agent", "/httpbin/headers" };
final Future<AsyncClientEndpoint> future = requester.connect(target, Timeout.ofSeconds(5));
final AsyncClientEndpoint clientEndpoint = future.get();
final CountDownLatch latch = new CountDownLatch(requestUris.length);
for (final String requestUri : requestUris) {
clientEndpoint.execute(AsyncRequestBuilder.get().setHttpHost(target).setPath(requestUri).build(), new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), new FutureCallback<Message<HttpResponse, String>>() {
@Override
public void completed(final Message<HttpResponse, String> message) {
latch.countDown();
final HttpResponse response = message.getHead();
final String body = message.getBody();
System.out.println(requestUri + "->" + response.getCode());
System.out.println(body);
}
@Override
public void failed(final Exception ex) {
latch.countDown();
System.out.println(requestUri + "->" + ex);
}
@Override
public void cancelled() {
latch.countDown();
System.out.println(requestUri + " cancelled");
}
});
}
latch.await();
// Manually release client endpoint when done !!!
clientEndpoint.releaseAndDiscard();
System.out.println("Shutting down I/O reactor");
requester.initiateShutdown();
}
use of org.apache.hc.core5.http2.frame.RawFrame in project httpcomponents-core by apache.
the class AbstractH2StreamMultiplexer method maximizeConnWindow.
private void maximizeConnWindow(final int connWinSize) throws IOException {
final int delta = Integer.MAX_VALUE - connWinSize;
if (delta > 0) {
final RawFrame windowUpdateFrame = frameFactory.createWindowUpdate(0, delta);
commitFrame(windowUpdateFrame);
updateInputWindow(0, connInputWindow, delta);
}
}
use of org.apache.hc.core5.http2.frame.RawFrame in project httpcomponents-core by apache.
the class AbstractH2StreamMultiplexer method onException.
public final void onException(final Exception cause) {
try {
for (; ; ) {
final AsyncPingHandler pingHandler = pingHandlers.poll();
if (pingHandler != null) {
pingHandler.failed(cause);
} else {
break;
}
}
for (; ; ) {
final Command command = ioSession.poll();
if (command != null) {
if (command instanceof ExecutableCommand) {
((ExecutableCommand) command).failed(new ConnectionClosedException());
} else {
command.cancel();
}
} else {
break;
}
}
for (final Iterator<Map.Entry<Integer, H2Stream>> it = streamMap.entrySet().iterator(); it.hasNext(); ) {
final Map.Entry<Integer, H2Stream> entry = it.next();
final H2Stream stream = entry.getValue();
stream.reset(cause);
}
streamMap.clear();
if (!(cause instanceof ConnectionClosedException)) {
if (connState.compareTo(ConnectionHandshake.GRACEFUL_SHUTDOWN) <= 0) {
final H2Error errorCode;
if (cause instanceof H2ConnectionException) {
errorCode = H2Error.getByCode(((H2ConnectionException) cause).getCode());
} else if (cause instanceof ProtocolException) {
errorCode = H2Error.PROTOCOL_ERROR;
} else {
errorCode = H2Error.INTERNAL_ERROR;
}
final RawFrame goAway = frameFactory.createGoAway(processedRemoteStreamId, errorCode, cause.getMessage());
commitFrame(goAway);
}
}
} catch (final IOException ignore) {
} finally {
connState = ConnectionHandshake.SHUTDOWN;
final CloseMode closeMode;
if (cause instanceof ConnectionClosedException) {
closeMode = CloseMode.GRACEFUL;
} else if (cause instanceof IOException) {
closeMode = CloseMode.IMMEDIATE;
} else {
closeMode = CloseMode.GRACEFUL;
}
ioSession.close(closeMode);
}
}
use of org.apache.hc.core5.http2.frame.RawFrame in project httpcomponents-core by apache.
the class AbstractH2StreamMultiplexer method onOutput.
public final void onOutput() throws HttpException, IOException {
ioSession.getLock().lock();
try {
if (!outputBuffer.isEmpty()) {
outputBuffer.flush(ioSession);
}
while (outputBuffer.isEmpty()) {
final RawFrame frame = outputQueue.poll();
if (frame != null) {
if (streamListener != null) {
streamListener.onFrameOutput(this, frame.getStreamId(), frame);
}
outputBuffer.write(frame, ioSession);
} else {
break;
}
}
} finally {
ioSession.getLock().unlock();
}
if (connState.compareTo(ConnectionHandshake.SHUTDOWN) < 0) {
if (connOutputWindow.get() > 0 && remoteSettingState == SettingsHandshake.ACKED) {
produceOutput();
}
final int pendingOutputRequests = outputRequests.get();
boolean outputPending = false;
if (!streamMap.isEmpty() && connOutputWindow.get() > 0) {
for (final Iterator<Map.Entry<Integer, H2Stream>> it = streamMap.entrySet().iterator(); it.hasNext(); ) {
final Map.Entry<Integer, H2Stream> entry = it.next();
final H2Stream stream = entry.getValue();
if (!stream.isLocalClosed() && stream.getOutputWindow().get() > 0 && stream.isOutputReady()) {
outputPending = true;
break;
}
}
}
ioSession.getLock().lock();
try {
if (!outputPending && outputBuffer.isEmpty() && outputQueue.isEmpty() && outputRequests.compareAndSet(pendingOutputRequests, 0)) {
ioSession.clearEvent(SelectionKey.OP_WRITE);
} else {
outputRequests.addAndGet(-pendingOutputRequests);
}
} finally {
ioSession.getLock().unlock();
}
}
if (connState.compareTo(ConnectionHandshake.ACTIVE) <= 0 && remoteSettingState == SettingsHandshake.ACKED) {
processPendingCommands();
}
if (connState.compareTo(ConnectionHandshake.GRACEFUL_SHUTDOWN) == 0) {
int liveStreams = 0;
for (final Iterator<Map.Entry<Integer, H2Stream>> it = streamMap.entrySet().iterator(); it.hasNext(); ) {
final Map.Entry<Integer, H2Stream> entry = it.next();
final H2Stream stream = entry.getValue();
if (stream.isLocalClosed() && stream.isRemoteClosed()) {
stream.releaseResources();
it.remove();
} else {
if (idGenerator.isSameSide(stream.getId()) || stream.getId() <= processedRemoteStreamId) {
liveStreams++;
}
}
}
if (liveStreams == 0) {
connState = ConnectionHandshake.SHUTDOWN;
}
}
if (connState.compareTo(ConnectionHandshake.SHUTDOWN) >= 0) {
if (!streamMap.isEmpty()) {
for (final H2Stream stream : streamMap.values()) {
stream.releaseResources();
}
streamMap.clear();
}
ioSession.getLock().lock();
try {
if (outputBuffer.isEmpty() && outputQueue.isEmpty()) {
ioSession.close();
}
} finally {
ioSession.getLock().unlock();
}
}
}
Aggregations