@Override
  protected ChannelFuture doOnHead(ChannelHandlerContext context, HttpRequest request) {

    try {
      NettyTransferService<HttpProtocolInfo>.NettyMoverChannel file = open(request, false);
      context
          .write(new HttpGetResponse(file.size(), file))
          .addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
      return context.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
    } catch (IOException | IllegalArgumentException e) {
      return context.writeAndFlush(createErrorResponse(BAD_REQUEST, e.getMessage()));
    } catch (URISyntaxException e) {
      return context.writeAndFlush(
          createErrorResponse(BAD_REQUEST, "URI not valid: " + e.getMessage()));
    } catch (RuntimeException e) {
      return context.writeAndFlush(createErrorResponse(INTERNAL_SERVER_ERROR, e.getMessage()));
    }
  }
  @Override
  protected ChannelFuture doOnPut(ChannelHandlerContext context, HttpRequest request) {
    NettyTransferService<HttpProtocolInfo>.NettyMoverChannel file = null;
    Exception exception = null;

    try {
      checkContentHeader(request.headers().names(), Collections.singletonList(CONTENT_LENGTH));

      file = open(request, true);

      if (file.getIoMode() != IoMode.WRITE) {
        throw new HttpException(METHOD_NOT_ALLOWED.code(), "Resource is not open for writing");
      }

      if (is100ContinueExpected(request)) {
        context
            .writeAndFlush(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE))
            .addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
      }
      _writeChannel = file;
      file = null;
      return null;
    } catch (HttpException e) {
      exception = e;
      return context.writeAndFlush(
          createErrorResponse(HttpResponseStatus.valueOf(e.getErrorCode()), e.getMessage()));
    } catch (URISyntaxException e) {
      exception = e;
      return context.writeAndFlush(
          createErrorResponse(BAD_REQUEST, "URI is not valid: " + e.getMessage()));
    } catch (IllegalArgumentException e) {
      exception = e;
      return context.writeAndFlush(createErrorResponse(BAD_REQUEST, e.getMessage()));
    } catch (RuntimeException e) {
      exception = e;
      return context.writeAndFlush(createErrorResponse(INTERNAL_SERVER_ERROR, e.getMessage()));
    } finally {
      if (file != null) {
        file.release(exception);
        _files.remove(file);
      }
    }
  }