io.netty.channel.ServerChannel Java Examples

The following examples show how to use io.netty.channel.ServerChannel. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: HelloWebServer.java    From FrameworkBenchmarks with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
private void doRun(EventLoopGroup loupGroup, Class<? extends ServerChannel> serverChannelClass, IoMultiplexer multiplexer) throws InterruptedException {
	try {
		InetSocketAddress inet = new InetSocketAddress(port);

		ServerBootstrap b = new ServerBootstrap();

		if (multiplexer == IoMultiplexer.EPOLL) {
			b.option(EpollChannelOption.SO_REUSEPORT, true);
		}
		
		b.option(ChannelOption.SO_BACKLOG, 8192);
		b.option(ChannelOption.SO_REUSEADDR, true);
		b.group(loupGroup).channel(serverChannelClass).childHandler(new HelloServerInitializer(loupGroup.next()));
		b.childOption(ChannelOption.SO_REUSEADDR, true);

		Channel ch = b.bind(inet).sync().channel();

		System.out.printf("Httpd started. Listening on: %s%n", inet.toString());

		ch.closeFuture().sync();
	} finally {
		loupGroup.shutdownGracefully().sync();
	}
}
 
Example #2
Source File: ProxyServer.java    From flashback with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Start proxy server
 * */
public void start()
    throws InterruptedException {
  ServerBootstrap serverBootstrap = new ServerBootstrap();
  serverBootstrap.group(_acceptorGroup, _upstreamWorkerGroup);
  serverBootstrap.channelFactory(new ChannelFactory<ServerChannel>() {
    @Override
    public ServerChannel newChannel() {
      return new NioServerSocketChannel();
    }
  });
  serverBootstrap.childHandler(new ProxyInitializer(this));

  //bind
  ChannelFuture future = serverBootstrap.bind(_host, _port);

  //wait for the future
  future.awaitUninterruptibly();
  if (!future.isSuccess()) {
    future.channel().closeFuture().awaitUninterruptibly();
    throw new ChannelException(String.format("Failed to bind to: %s:%d", _host, _port), future.cause());
  } else {
    _allChannels.add(future.channel());
  }
}
 
Example #3
Source File: DefaultChannelGroup.java    From netty4.0.27Learn with Apache License 2.0 6 votes vote down vote up
@Override
public boolean remove(Object o) {
    if (!(o instanceof Channel)) {
        return false;
    }
    boolean removed;
    Channel c = (Channel) o;
    if (c instanceof ServerChannel) {
        removed = serverChannels.remove(c);
    } else {
        removed = nonServerChannels.remove(c);
    }
    if (!removed) {
        return false;
    }

    c.closeFuture().removeListener(remover);
    return true;
}
 
Example #4
Source File: BaseServer.java    From blynk-server with GNU General Public License v3.0 6 votes vote down vote up
private void buildServerAndRun(EventLoopGroup bossGroup, EventLoopGroup workerGroup,
                               Class<? extends ServerChannel> channelClass) throws Exception {

    var b = new ServerBootstrap();
    try {
        b.group(bossGroup, workerGroup)
                .channel(channelClass)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(getChannelInitializer());

        var listenTo = (listenAddress == null || listenAddress.isEmpty())
                ? new InetSocketAddress(port)
                : new InetSocketAddress(listenAddress, port);
        this.cf = b.bind(listenTo).sync();
    } catch (Exception e) {
        log.error("Error initializing {}, port {}", getServerName(), port, e);
        throw e;
    }

    log.info("{} server listening at {} port.", getServerName(), port);
}
 
Example #5
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 6 votes vote down vote up
private static ServerChannel createServer(
    Class<? extends ServerChannel> serverChannelClass,
    IntFunction<EventLoopGroup> newEventLoopGroup,
    SocketAddress socketAddress,
    ChannelHandler handler) {
  EventLoopGroup eventLoop = newEventLoopGroup.apply(1);
  ServerBootstrap sb =
      new ServerBootstrap()
          .group(eventLoop)
          .channel(serverChannelClass)
          .childHandler(
              new ChannelInitializer<Channel>() {
                @Override
                protected void initChannel(Channel ch) {
                  ch.pipeline().addLast(new HttpServerCodec());
                  ch.pipeline().addLast(new HttpObjectAggregator(1000));
                  ch.pipeline().addLast(handler);
                }
              });
  try {
    return ((ServerChannel) sb.bind(socketAddress).sync().channel());
  } catch (Exception e) {
    throw new IllegalStateException(e);
  }
}
 
Example #6
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 6 votes vote down vote up
public UnixDomainServer(
    Class<? extends ServerChannel> serverChannelClass,
    IntFunction<EventLoopGroup> newEventLoopGroup) {
  EventLoopGroup eventLoop = newEventLoopGroup.apply(1);
  ServerBootstrap sb =
      new ServerBootstrap()
          .group(eventLoop)
          .channel(serverChannelClass)
          .childHandler(
              new ChannelInitializer<Channel>() {
                @Override
                protected void initChannel(Channel ch) {
                  ch.pipeline().addLast(new HttpServerCodec());
                  ch.pipeline().addLast(new HttpObjectAggregator(1000));
                  ch.pipeline().addLast(Preconditions.checkNotNull(handler));
                }
              });
  try {
    ServerChannel actual = ((ServerChannel) sb.bind(newDomainSocketAddress()).sync().channel());
    this.serverChannel = mock(ServerChannel.class, AdditionalAnswers.delegatesTo(actual));
  } catch (Exception e) {
    throw new IllegalStateException(e);
  }
}
 
Example #7
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 6 votes vote down vote up
@Test(expected = UploadTimeoutException.class, timeout = 30000)
public void uploadTimeout() throws Exception {
  ServerChannel server = null;
  try {
    server =
        testServer.start(
            new SimpleChannelInboundHandler<FullHttpRequest>() {
              @Override
              protected void channelRead0(
                  ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) {
                // Don't respond and force a client timeout.
              }
            });

    Credentials credentials = newCredentials();
    HttpCacheClient blobStore = createHttpBlobStore(server, /* timeoutSeconds= */ 1, credentials);
    byte[] data = "File Contents".getBytes(Charsets.US_ASCII);
    getFromFuture(blobStore.uploadBlob(DIGEST_UTIL.compute(data), ByteString.copyFrom(data)));
    fail("Exception expected");
  } finally {
    testServer.stop(server);
  }
}
 
Example #8
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 6 votes vote down vote up
@Test(expected = DownloadTimeoutException.class, timeout = 30000)
public void downloadTimeout() throws Exception {
  ServerChannel server = null;
  try {
    server =
        testServer.start(
            new SimpleChannelInboundHandler<FullHttpRequest>() {
              @Override
              protected void channelRead0(
                  ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) {
                // Don't respond and force a client timeout.
              }
            });

    Credentials credentials = newCredentials();
    HttpCacheClient blobStore = createHttpBlobStore(server, /* timeoutSeconds= */ 1, credentials);
    getFromFuture(blobStore.downloadBlob(DIGEST, new ByteArrayOutputStream()));
    fail("Exception expected");
  } finally {
    testServer.stop(server);
  }
}
 
Example #9
Source File: Server.java    From simulacron with Apache License 2.0 6 votes vote down vote up
private Server(
    AddressResolver addressResolver,
    EventLoopGroup eventLoopGroup,
    Class<? extends ServerChannel> channelClass,
    boolean customEventLoop,
    Timer timer,
    boolean customTimer,
    long bindTimeoutInNanos,
    StubStore stubStore,
    boolean activityLogging) {
  this(
      addressResolver,
      eventLoopGroup,
      customEventLoop,
      timer,
      customTimer,
      bindTimeoutInNanos,
      stubStore,
      activityLogging,
      new ServerBootstrap()
          .group(eventLoopGroup)
          .channel(channelClass)
          .childHandler(new Initializer()));
}
 
Example #10
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 6 votes vote down vote up
private void expiredAuthTokensShouldBeRetried_get(
    HttpCacheClientTest.NotAuthorizedHandler.ErrorType errorType) throws Exception {
  ServerChannel server = null;
  try {
    server = testServer.start(new NotAuthorizedHandler(errorType));

    Credentials credentials = newCredentials();
    HttpCacheClient blobStore = createHttpBlobStore(server, /* timeoutSeconds= */ 1, credentials);
    ByteArrayOutputStream out = Mockito.spy(new ByteArrayOutputStream());
    getFromFuture(blobStore.downloadBlob(DIGEST, out));
    assertThat(out.toString(Charsets.US_ASCII.name())).isEqualTo("File Contents");
    verify(credentials, times(1)).refresh();
    verify(credentials, times(2)).getRequestMetadata(any(URI.class));
    verify(credentials, times(2)).hasRequestMetadata();
    // The caller is responsible to the close the stream.
    verify(out, never()).close();
    verifyNoMoreInteractions(credentials);
  } finally {
    testServer.stop(server);
  }
}
 
Example #11
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 6 votes vote down vote up
private void expiredAuthTokensShouldBeRetried_put(
    HttpCacheClientTest.NotAuthorizedHandler.ErrorType errorType) throws Exception {
  ServerChannel server = null;
  try {
    server = testServer.start(new NotAuthorizedHandler(errorType));

    Credentials credentials = newCredentials();
    HttpCacheClient blobStore = createHttpBlobStore(server, /* timeoutSeconds= */ 1, credentials);
    byte[] data = "File Contents".getBytes(Charsets.US_ASCII);
    blobStore.uploadBlob(DIGEST_UTIL.compute(data), ByteString.copyFrom(data)).get();
    verify(credentials, times(1)).refresh();
    verify(credentials, times(2)).getRequestMetadata(any(URI.class));
    verify(credentials, times(2)).hasRequestMetadata();
    verifyNoMoreInteractions(credentials);
  } finally {
    testServer.stop(server);
  }
}
 
Example #12
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 6 votes vote down vote up
private void errorCodeThatShouldNotBeRetried_get(
    HttpCacheClientTest.NotAuthorizedHandler.ErrorType errorType) {
  ServerChannel server = null;
  try {
    server = testServer.start(new NotAuthorizedHandler(errorType));

    Credentials credentials = newCredentials();
    HttpCacheClient blobStore = createHttpBlobStore(server, /* timeoutSeconds= */ 1, credentials);
    getFromFuture(blobStore.downloadBlob(DIGEST, new ByteArrayOutputStream()));
    fail("Exception expected.");
  } catch (Exception e) {
    assertThat(e).isInstanceOf(HttpException.class);
    assertThat(((HttpException) e).response().status())
        .isEqualTo(HttpResponseStatus.UNAUTHORIZED);
  } finally {
    testServer.stop(server);
  }
}
 
Example #13
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 6 votes vote down vote up
private void errorCodeThatShouldNotBeRetried_put(
    HttpCacheClientTest.NotAuthorizedHandler.ErrorType errorType) {
  ServerChannel server = null;
  try {
    server = testServer.start(new NotAuthorizedHandler(errorType));

    Credentials credentials = newCredentials();
    HttpCacheClient blobStore = createHttpBlobStore(server, /* timeoutSeconds= */ 1, credentials);
    byte[] oneByte = new byte[] {0};
    getFromFuture(
        blobStore.uploadBlob(DIGEST_UTIL.compute(oneByte), ByteString.copyFrom(oneByte)));
    fail("Exception expected.");
  } catch (Exception e) {
    assertThat(e).isInstanceOf(HttpException.class);
    assertThat(((HttpException) e).response().status())
        .isEqualTo(HttpResponseStatus.UNAUTHORIZED);
  } finally {
    testServer.stop(server);
  }
}
 
Example #14
Source File: HelloWebServer.java    From crow-benchmark with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
private void doRun(EventLoopGroup loupGroup, Class<? extends ServerChannel> serverChannelClass) throws InterruptedException {
try {
    ServerBootstrap b = new ServerBootstrap();
    b.option(ChannelOption.SO_BACKLOG, 1024);
    b.option(ChannelOption.SO_REUSEADDR, true);
    b.group(loupGroup).channel(serverChannelClass).childHandler(new HelloServerInitializer(loupGroup.next()));
    b.option(ChannelOption.MAX_MESSAGES_PER_READ, Integer.MAX_VALUE);
    b.childOption(ChannelOption.ALLOCATOR, new PooledByteBufAllocator(true));
    b.childOption(ChannelOption.SO_REUSEADDR, true);
    b.childOption(ChannelOption.MAX_MESSAGES_PER_READ, Integer.MAX_VALUE);

    Channel ch = b.bind(port).sync().channel();
    ch.closeFuture().sync();
} finally {
    loupGroup.shutdownGracefully().sync();
}
   }
 
Example #15
Source File: BuilderUtils.java    From servicetalk with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the correct {@link Class} to use with the given {@link EventLoopGroup}.
 *
 * @param group        the {@link EventLoopGroup} for which the class is needed
 * @param addressClass The class of the address that the server socket will be bound to.
 * @return the class that should be used for bootstrapping
 */
public static Class<? extends ServerChannel> serverChannel(EventLoopGroup group,
                                                           Class<? extends SocketAddress> addressClass) {
    if (useEpoll(group)) {
        return DomainSocketAddress.class.isAssignableFrom(addressClass) ? EpollServerDomainSocketChannel.class :
                EpollServerSocketChannel.class;
    } else if (useKQueue(group)) {
        return DomainSocketAddress.class.isAssignableFrom(addressClass) ? KQueueServerDomainSocketChannel.class :
                KQueueServerSocketChannel.class;
    } else {
        return NioServerSocketChannel.class;
    }
}
 
Example #16
Source File: Connector.java    From serve with Apache License 2.0 5 votes vote down vote up
public Class<? extends ServerChannel> getServerChannel() {
    if (useNativeIo && Epoll.isAvailable()) {
        return uds ? EpollServerDomainSocketChannel.class : EpollServerSocketChannel.class;
    } else if (useNativeIo && KQueue.isAvailable()) {
        return uds ? KQueueServerDomainSocketChannel.class : KQueueServerSocketChannel.class;
    }

    return NioServerSocketChannel.class;
}
 
Example #17
Source File: DefaultChannelGroup.java    From netty4.0.27Learn with Apache License 2.0 5 votes vote down vote up
@Override
public boolean contains(Object o) {
    if (o instanceof Channel) {
        Channel c = (Channel) o;
        if (o instanceof ServerChannel) {
            return serverChannels.contains(c);
        } else {
            return nonServerChannels.contains(c);
        }
    } else {
        return false;
    }
}
 
Example #18
Source File: DefaultChannelGroup.java    From netty4.0.27Learn with Apache License 2.0 5 votes vote down vote up
@Override
public boolean add(Channel channel) {
    ConcurrentSet<Channel> set =
        channel instanceof ServerChannel? serverChannels : nonServerChannels;

    boolean added = set.add(channel);
    if (added) {
        channel.closeFuture().addListener(remover);
    }
    return added;
}
 
Example #19
Source File: UtilsTest.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Test
public void defaultServerChannelFactory_whenEpollIsAvailable() {
  assume().that(Utils.isEpollAvailable()).isTrue();

  ChannelFactory<? extends ServerChannel> channelFactory = Utils.DEFAULT_SERVER_CHANNEL_FACTORY;

  assertThat(channelFactory.toString())
      .isEqualTo("ReflectiveChannelFactory(EpollServerSocketChannel.class)");
}
 
Example #20
Source File: Utils.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
private static ChannelFactory<ServerChannel> nioServerChannelFactory() {
  return new ChannelFactory<ServerChannel>() {
    @Override
    public ServerChannel newChannel() {
      return new NioServerSocketChannel();
    }
  };
}
 
Example #21
Source File: ServerChannelConfiguration.java    From xio with Apache License 2.0 5 votes vote down vote up
ServerChannelConfiguration(
    EventLoopGroup bossGroup,
    EventLoopGroup workerGroup,
    Class<? extends ServerChannel> channelClass) {
  this.bossGroup = bossGroup;
  this.workerGroup = workerGroup;
  this.channelClass = channelClass;
}
 
Example #22
Source File: Utils.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
private static Class<? extends ServerChannel> epollServerChannelType() {
  try {
    Class<? extends ServerChannel> serverSocketChannel =
        Class
            .forName("io.netty.channel.epoll.EpollServerSocketChannel")
            .asSubclass(ServerChannel.class);
    return serverSocketChannel;
  } catch (ClassNotFoundException e) {
    throw new RuntimeException("Cannot load EpollServerSocketChannel", e);
  }
}
 
Example #23
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 5 votes vote down vote up
public ServerChannel start(ChannelInboundHandler handler) {
  return createServer(
      NioServerSocketChannel.class,
      NioEventLoopGroup::new,
      new InetSocketAddress("localhost", 0),
      handler);
}
 
Example #24
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 5 votes vote down vote up
public void stop(ServerChannel serverChannel) {
  try {
    serverChannel.close();
    serverChannel.closeFuture().sync();
    serverChannel.eventLoop().shutdownGracefully().sync();
  } catch (Exception e) {
    throw new IllegalStateException(e);
  }
}
 
Example #25
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 5 votes vote down vote up
public void stop(ServerChannel serverChannel) {
  // Note: In the tests, we expect that connecting to a closed server channel results
  // in a channel connection error. Netty doesn't seem to handle closing domain socket
  // addresses very well-- often connecting to a closed domain socket will result in a
  // read timeout instead of a connection timeout.
  //
  // This is a hack to ensure connection timeouts are "received" by the tests for this
  // dummy domain socket server. In particular, this lets the timeoutShouldWork_connect
  // test work for both inet and domain sockets.
  //
  // This is also part of the workaround for https://github.com/netty/netty/issues/7047.
  when(this.serverChannel.localAddress()).thenReturn(new DomainSocketAddress(""));
  this.handler = null;
}
 
Example #26
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 5 votes vote down vote up
@Test
public void testUploadAtMostOnce() throws Exception {
  ServerChannel server = null;
  try {
    ConcurrentHashMap<String, byte[]> cacheContents = new ConcurrentHashMap<>();
    server = testServer.start(new HttpCacheServerHandler(cacheContents));

    HttpCacheClient blobStore =
        createHttpBlobStore(server, /* timeoutSeconds= */ 1, /* credentials= */ null);

    ByteString data = ByteString.copyFrom("foo bar", StandardCharsets.UTF_8);
    Digest digest = DIGEST_UTIL.compute(data.toByteArray());
    blobStore.uploadBlob(digest, data).get();

    assertThat(cacheContents).hasSize(1);
    String cacheKey = "/cas/" + digest.getHash();
    assertThat(cacheContents).containsKey(cacheKey);
    assertThat(cacheContents.get(cacheKey)).isEqualTo(data.toByteArray());

    // Clear the remote cache contents
    cacheContents.clear();

    blobStore.uploadBlob(digest, data).get();

    // Nothing should have been uploaded again.
    assertThat(cacheContents).isEmpty();

  } finally {
    testServer.stop(server);
  }
}
 
Example #27
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 5 votes vote down vote up
@Test(expected = ConnectException.class, timeout = 30000)
public void connectTimeout() throws Exception {
  ServerChannel server = testServer.start(new ChannelInboundHandlerAdapter() {});
  testServer.stop(server);

  Credentials credentials = newCredentials();
  HttpCacheClient blobStore = createHttpBlobStore(server, /* timeoutSeconds= */ 1, credentials);
  getFromFuture(blobStore.downloadBlob(DIGEST, new ByteArrayOutputStream()));

  fail("Exception expected");
}
 
Example #28
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 5 votes vote down vote up
@Test
public void uploadResponseTooLarge() throws Exception {
  ServerChannel server = null;
  try {
    server =
        testServer.start(
            new SimpleChannelInboundHandler<FullHttpRequest>() {
              @Override
              protected void channelRead0(
                  ChannelHandlerContext channelHandlerContext, FullHttpRequest request) {
                ByteBuf longMessage =
                    channelHandlerContext.alloc().buffer(50000).writerIndex(50000);
                DefaultFullHttpResponse response =
                    new DefaultFullHttpResponse(
                        HttpVersion.HTTP_1_1,
                        HttpResponseStatus.INTERNAL_SERVER_ERROR,
                        longMessage);
                channelHandlerContext
                    .writeAndFlush(response)
                    .addListener(ChannelFutureListener.CLOSE);
              }
            });

    Credentials credentials = newCredentials();
    HttpCacheClient blobStore = createHttpBlobStore(server, /* timeoutSeconds= */ 1, credentials);
    ByteString data = ByteString.copyFrom("File Contents", Charsets.US_ASCII);
    IOException e =
        assertThrows(
            IOException.class,
            () ->
                getFromFuture(
                    blobStore.uploadBlob(DIGEST_UTIL.compute(data.toByteArray()), data)));
    assertThat(e.getCause()).isInstanceOf(TooLongFrameException.class);
  } finally {
    testServer.stop(server);
  }
}
 
Example #29
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 5 votes vote down vote up
@Test
public void testDownloadFailsOnDigestMismatch() throws Exception {
  // Test that the download fails when a blob/file has a different content hash than expected.

  ServerChannel server = null;
  try {
    server =
        testServer.start(
            new SimpleChannelInboundHandler<FullHttpRequest>() {
              @Override
              protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
                ByteBuf data = ctx.alloc().buffer();
                ByteBufUtil.writeUtf8(data, "bar");
                DefaultFullHttpResponse response =
                    new DefaultFullHttpResponse(
                        HttpVersion.HTTP_1_1, HttpResponseStatus.OK, data);
                HttpUtil.setContentLength(response, data.readableBytes());

                ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
              }
            });

    Credentials credentials = newCredentials();
    HttpCacheClient blobStore =
        createHttpBlobStore(
            server, /* timeoutSeconds= */ 1, /* remoteVerifyDownloads= */ true, credentials);
    Digest fooDigest = DIGEST_UTIL.compute("foo".getBytes(Charsets.UTF_8));
    try (OutputStream out = new ByteArrayOutputStream()) {
      IOException e =
          assertThrows(
              IOException.class, () -> getFromFuture(blobStore.downloadBlob(fooDigest, out)));
      assertThat(e).hasMessageThat().contains(fooDigest.getHash());
      assertThat(e).hasMessageThat().contains(DIGEST_UTIL.computeAsUtf8("bar").getHash());
    }
  } finally {
    testServer.stop(server);
  }
}
 
Example #30
Source File: HttpCacheClientTest.java    From bazel with Apache License 2.0 5 votes vote down vote up
@Test
public void testDisablingDigestVerification() throws Exception {
  // Test that when digest verification is disabled a corrupted download works.

  ServerChannel server = null;
  try {
    server =
        testServer.start(
            new SimpleChannelInboundHandler<FullHttpRequest>() {
              @Override
              protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
                ByteBuf data = ctx.alloc().buffer();
                ByteBufUtil.writeUtf8(data, "bar");
                DefaultFullHttpResponse response =
                    new DefaultFullHttpResponse(
                        HttpVersion.HTTP_1_1, HttpResponseStatus.OK, data);
                HttpUtil.setContentLength(response, data.readableBytes());

                ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
              }
            });

    Credentials credentials = newCredentials();
    HttpCacheClient blobStore =
        createHttpBlobStore(
            server, /* timeoutSeconds= */ 1, /* remoteVerifyDownloads= */ false, credentials);
    Digest fooDigest = DIGEST_UTIL.compute("foo".getBytes(Charsets.UTF_8));
    try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
      getFromFuture(blobStore.downloadBlob(fooDigest, out));
      assertThat(out.toByteArray()).isEqualTo("bar".getBytes(Charsets.UTF_8));
    }
  } finally {
    testServer.stop(server);
  }
}