code: private void getObject(WebContext ctx, Bucket bucket, String id, boolean sendFile) throws IOException {
          StoredObject object = bucket.getObject(id);
          if (!object.exists()) {
              signalObjectError(ctx, HttpResponseStatus.NOT_FOUND, "Object does not exist");
              return;
          }
          Response response = ctx.respondWith();
          Properties properties = object.getProperties();
          for (Map.Entry<Object, Object> entry : properties.entrySet()) {
              response.addHeader(entry.getKey().toString(), entry.getValue().toString());
          }
          for (Map.Entry<String, String> entry : getOverridenHeaders(ctx).entrySet()) {
              response.setHeader(entry.getKey(), entry.getValue());
          }
  
          String etag = properties.getProperty(HTTP_HEADER_NAME_ETAG);
          if (Strings.isEmpty(etag)) {
              HashCode hash = Files.hash(object.getFile(), Hashing.md5());
              etag = BaseEncoding.base16().encode(hash.asBytes());
              Map<String, String> data = new HashMap<>();
              properties.forEach((key, value) -> data.put(key.toString(), String.valueOf(value)));
              data.put(HTTP_HEADER_NAME_ETAG, etag);
              object.storeProperties(data);
          }
  
          response.addHeader(HTTP_HEADER_NAME_ETAG, etag(etag));
          response.addHeader(HttpHeaderNames.ACCESS_CONTROL_EXPOSE_HEADERS, HTTP_HEADER_NAME_ETAG);
          if (sendFile) {
              response.file(object.getFile());
          } else {
              String contentType = MimeHelper.guessMimeType(object.getFile().getName());
              response.addHeader(HttpHeaderNames.CONTENT_TYPE, contentType);
              response.addHeader(HttpHeaderNames.LAST_MODIFIED,
                                 RFC822_INSTANT.format(Instant.ofEpochMilli(object.getFile().lastModified())));
              response.addHeader(HttpHeaderNames.CONTENT_LENGTH, object.getFile().length());
              response.status(HttpResponseStatus.OK);
          }
          signalObjectSuccess(ctx);
      }
docs: Handles GET /bucket/id
  
  @param ctx    the context describing the current request
  @param bucket the bucket containing the object to download
  @param id     name of the object to use as download