docs: public String getPresignedObjectUrl(Method method, String bucketName, String objectName, Integer expires,
                                        Map<String, String> reqParams)
      throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException,
             InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException,
             InternalException, InvalidExpiresRangeException {
      // Validate input.
      if (expires < 1 || expires > DEFAULT_EXPIRY_TIME) {
        throw new InvalidExpiresRangeException(expires, "expires must be in range of 1 to " + DEFAULT_EXPIRY_TIME);
      }
  
      byte[] body = null;
      if (method == Method.PUT || method == Method.POST) {
        body = new byte[0];
      }
  
      Multimap<String, String> queryParamMap = null;
      if (reqParams != null) {
        queryParamMap = HashMultimap.create();
        for (Map.Entry<String, String> m: reqParams.entrySet()) {
          queryParamMap.put(m.getKey(), m.getValue());
        }
      }
  
      String region = getRegion(bucketName);
      Request request = createRequest(method, bucketName, objectName, region, null, queryParamMap, null, body, 0);
      HttpUrl url = Signer.presignV4(request, region, accessKey, secretKey, expires);
      return url.toString();
    }