@Override
  protected void doHandle(RestRequest restRequest, RestResponseChannel restResponseChannel,
      Callback<ReadableStreamChannel> callback) throws RestServiceException {
    RequestPath requestPath = (RequestPath) restRequest.getArgs().get(REQUEST_PATH);
    if (S3BaseHandler.isGetObjectLockConfigurationRequest(restRequest)) {
      // We don't support Bucket Object Configuration. So always return NOT_FOUND
      new DefaultCallbackChain(restRequest, securityService, frontendMetrics, accountAndContainerInjector, callback,
          "Object Lock configuration is not set.", RestServiceErrorCode.NotFound).start();
    }  else if (S3BaseHandler.isMultipartListPartRequest(restRequest)) {
      s3MultipartUploadHandler.handle(restRequest, restResponseChannel, callback);
    } else if (S3BaseHandler.isListObjectRequest(restRequest)) {
      restRequest.setArg(LIST_REQUEST, "true");
      if(!restRequest.getArgs().containsKey(PREFIX_PARAM_NAME)) {
        restRequest.setArg(PREFIX_PARAM_NAME, EMPTY_PREFIX);
      }
      s3ListHandler.handle(restRequest, restResponseChannel, callback);
    } else {
      getBlobHandler.handle(requestPath, restRequest, restResponseChannel,
          buildCallback(frontendMetrics.s3GetHandleMetrics, (r) -> {
            // Set content-length for S3 requests since S3 java client seems to be looking for it
            long contentLength = Long.parseLong((String) restResponseChannel.getHeader(RestUtils.Headers.BLOB_SIZE));
            String contentRangeLength = RestUtils.getHeader(restRequest.getArgs(), CONTENT_RANGE_LENGTH, false);
            if (contentRangeLength != null) {
              // If is a range request, update the content length
              contentLength = Long.parseLong(contentRangeLength);
            }
            restResponseChannel.setHeader(RestUtils.Headers.CONTENT_LENGTH, contentLength);
            callback.onCompletion(r, null);
          }, restRequest.getUri(), LOGGER, callback));
    }
  }
Handles a S3 Get Request.
@param restRequest the {@link RestRequest} that contains the request parameters and body.
@param restResponseChannel the {@link RestResponseChannel} where headers should be set.
@param callback the {@link Callback} to invoke when the response is ready (or if there is an exception).
@throws RestServiceException exception when the processing fails
ambry-frontend/src/main/java/com/github/ambry/frontend/s3/S3GetHandler.java