如何在App Engine上使用Google Client Library for Java创建Google Cloud Storage可恢复上传网址?

时间:2015-05-15 01:23:24

标签: java google-app-engine google-cloud-storage

我找到了以下注释,其中描述了我想要做的事情:

  

注意:如果您的用户仅将资源(写入)上传到访问控制的存储桶,您可以使用Google云端存储的可恢复上传功能,并避免签名网址或需要Google帐户。在可恢复的上传方案中,您的(服务器端)代码会对Google Cloud Storage进行身份验证并启动上传,而无需实际上传任何数据。启动请求返回上载ID,然后可以在客户端请求中使用上载ID来上载数据。客户端请求不需要签名,因为上载ID实际上充当身份验证令牌。如果选择此路径,请务必通过HTTPS传输上传ID。

https://cloud.google.com/storage/docs/access-control#Signed-URLs

但是,我无法弄清楚如何使用Google Cloud Storage Library for Java。

https://developers.google.com/resources/api-libraries/documentation/storage/v1/java/latest/

我找不到任何可恢复文件的引用,或者在此API中的任何位置获取文件的URL。我怎么能这样做?

3 个答案:

答案 0 :(得分:4)

该库不会将其创建的URL公开给其调用者,这意味着您无法使用它来完成此操作。如果您想使用签名网址或上面提到的技巧,您需要手动实施。

如果可能的话,我建议使用签名的URL解决方案来解决服务器初始化可恢复上载的解决方案。它更灵活,更容易正确,并且有一些奇怪的边缘情况可能会遇到后一种方法。

有人在另一个问题中写了一个快速举例说明从App Engine签署网址:Cloud storage and secure download strategy on app engine. GCS acl or blobstore

答案 1 :(得分:3)

您可以自己构建网址。这是一个例子:

OkHttpClient client = new OkHttpClient();
AppIdentityService appIdentityService = credential.getAppIdentityService();
Collection<String> scopes = credential.getScopes();
String accessToken = appIdentityService.getAccessToken(scopes).getAccessToken();
Request request = new Request.Builder()
        .url("https://www.googleapis.com/upload/storage/v1/b/" + bucket + "/o?name=" + fileName + "&uploadType=resumable")
        .post(RequestBody.create(MediaType.parse(mimeType), new byte[0]))
        .addHeader("X-Upload-Content-Type", mimeType)
        .addHeader("X-Upload-Content-Length", "" + length)
        .addHeader("Origin", "http://localhost:8080")
        .addHeader("Origin", "*")
        .addHeader("authorization", "Bearer "+accessToken)
        .build();
Response response = client.newCall(request).execute();
return response.header("location");

答案 2 :(得分:0)

需要一些挖掘,但我想出了以下做正确的事情。有关如何执行此操作的一些官方文档会很好,特别是因为实际触发可恢复上载的端点与文档调用的端点不同。这里有什么来自使用gsutil工具签署请求然后计算正在做的事情。未充分记录的附加信息是POST到此URL以获取可恢复会话URL的代码必须包含&#34; x-goog-resumable:start&#34;标题以触发上传。从那里开始,所有内容都与执行可恢复上传到GCS的文档相同。

import base64
import datetime
import time
import urllib

from google.appengine.api import app_identity

SIGNED_URL_EXPIRATION = datetime.timedelta(days=7)

def SignResumableUploadUrl(gcs_resource_path):
  """Generates a signed resumable upload URL.

  Note that documentation on this ability is sketchy. The canonical source
  is derived from running the gsutil program to generate a RESUMABLE URL
  with the "-m RESUMABLE" argument. Run "gsutil help signurl" for info and
  the following for an example:
    gsutil -m RESUMABLE -d 10m keyfile gs://bucket/file/name

  Note that this generates a URL different from the standard mechanism for
  deriving a resumable start URL and the initiator needs to add the header:
    x-goog-resumable:start

  Args:
    gcs_resource_path: The path of the GCS resource, including bucket name.

  Returns:
    A full signed URL.
  """
  method = "POST"
  expiration = datetime.datetime.utcnow() + SIGNED_URL_EXPIRATION
  expiration = int(time.mktime(expiration.timetuple()))
  signature_string = "\n".join([
      method,
      "",  # content md5
      "",  # content type
      str(expiration),
      "x-goog-resumable:start",
      gcs_resource_path
  ])
  _, signature_bytes = app_identity.sign_blob(signature_string)
  signature = base64.b64encode(signature_bytes)

  query_params = {
      "GoogleAccessId": app_identity.get_service_account_name(),
      "Expires": str(expiration),
      "Signature": signature,
  }

  return "{endpoint}{resource}?{querystring}".format(
      endpoint="https://storage.googleapis.com",
      resource=gcs_resource_path,
      querystring=urllib.urlencode(query_params))