code: private void copyObject(WebContext ctx, Bucket bucket, String id, String copy) throws IOException {
          StoredObject object = bucket.getObject(id);
          if (!copy.contains(PATH_DELIMITER)) {
              signalObjectError(ctx, HttpResponseStatus.BAD_REQUEST, "Source must contain '/'");
              return;
          }
          String srcBucketName = copy.substring(1, copy.lastIndexOf(PATH_DELIMITER));
          String srcId = copy.substring(copy.lastIndexOf(PATH_DELIMITER) + 1);
          Bucket srcBucket = storage.getBucket(srcBucketName);
          if (!srcBucket.exists()) {
              signalObjectError(ctx, HttpResponseStatus.BAD_REQUEST, "Source bucket does not exist");
              return;
          }
          StoredObject src = srcBucket.getObject(srcId);
          if (!src.exists()) {
              signalObjectError(ctx, HttpResponseStatus.BAD_REQUEST, "Source object does not exist");
              return;
          }
          Files.copy(src.getFile(), object.getFile());
          if (src.getPropertiesFile().exists()) {
              Files.copy(src.getPropertiesFile(), object.getPropertiesFile());
          }
          HashCode hash = Files.hash(object.getFile(), Hashing.md5());
          String etag = BaseEncoding.base16().encode(hash.asBytes());
  
          XMLStructuredOutput structuredOutput = ctx.respondWith().addHeader(HTTP_HEADER_NAME_ETAG, etag(etag)).xml();
          structuredOutput.beginOutput("CopyObjectResult");
          structuredOutput.beginObject("LastModified");
          structuredOutput.text(RFC822_INSTANT.format(object.getLastModifiedInstant()));
          structuredOutput.endObject();
          structuredOutput.beginObject(HTTP_HEADER_NAME_ETAG);
          structuredOutput.text(etag(etag));
          structuredOutput.endObject();
          structuredOutput.endOutput();
          signalObjectSuccess(ctx);
      }
docs: Handles GET /bucket/id with an <tt>x-amz-copy-source</tt> header.
  
  @param ctx    the context describing the current request
  @param bucket the bucket containing the object to use as destination
  @param id     name of the object to use as destination