简体   繁体   English

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

[英]How do I create a Google Cloud Storage resumable upload URL with Google Client Library for Java on App Engine?

I found the follow note, which describes exactly what I'd like to do: 我找到了以下注释,它描述了我想要做的事情:

Note : If your users are only uploading resources (writing) to an access-controlled bucket, you can use the resumable uploads functionality of Google Cloud Storage, and avoid signing URLs or requiring a Google account. 注意 :如果您的用户仅将资源(写入)上传到访问控制的存储桶,则可以使用Google云端存储的可恢复上传功能,并避免签名网址或要求使用Google帐户。 In a resumable upload scenario, your (server-side) code authenticates and initiates an upload to Google Cloud Storage without actually uploading any data. 在可恢复的上传方案中,您的(服务器端)代码会对Google Cloud Storage进行身份验证并启动上传,而无需实际上传任何数据。 The initiation request returns an upload ID, which can then be used in a client request to upload the data. 启动请求返回上载ID,然后可以在客户端请求中使用上载ID来上载数据。 The client request does not need to be signed because the upload ID, in effect, acts as an authentication token. 客户端请求不需要签名,因为上载ID实际上充当身份验证令牌。 If you choose this path, be sure to transmit the upload ID over HTTPS. 如果选择此路径,请确保通过HTTPS传输上载ID。

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

However, I cannot figure out how to do this with the Google Cloud Storage Library for Java. 但是,我无法弄清楚如何使用Google Cloud Storage Library for Java执行此操作。

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

I can't find any reference to resumable files, or getting the URL for a file anywhere in this API. 我找不到任何可恢复文件的引用,或者在此API中的任何位置获取文件的URL。 How can I do this? 我怎样才能做到这一点?

That library does not expose the URLs that it creates to its caller, which means you can't use it to accomplish this. 该库不会将其创建的URL公开给其调用者,这意味着您无法使用它来完成此操作。 If you want to use either signed URLs or the trick you mention above, you'll need to implement it manually. 如果您想使用签名网址或上面提到的技巧,您需要手动实施。

I would advise going with the signed URL solution over the solution where the server initializes the resumable upload, if possible. 如果可能的话,我建议使用签名的URL解决方案来解决服务器初始化可恢复上载的解决方案。 It's more flexible and easier to get right, and there are some odd edge cases with the latter method that you could run into. 它更灵活,更容易正确,并且有一些奇怪的边缘情况与后一种方法,你可能遇到。

Someone wrote a up a quick example of signing a URL from App Engine a while back in another question: Cloud storage and secure download strategy on app engine. 有人在另一个问题上写了一个快速的例子,即从App Engine签署一个URL:应用引擎上的云存储和安全下载策略。 GCS acl or blobstore GCS acl或blobstore

You can build the url yourself. 你可以自己建立网址。 Here is an example : 这是一个例子:

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");

It took some digging, but I came up with the following which does the right thing. 这需要一些挖掘,但我提出了以下做正确的事情。 Some official documentation on how to do this would have been nice, especially because the endpoint for actually triggering the resumable upload is different from what the docs call out. 有关如何执行此操作的一些官方文档会很好,特别是因为实际触发可恢复上载的端点与文档调用的端点不同。 What is here came from using the gsutil tool to sign requests and then working out what was being done. 这里有什么来自使用gsutil工具签署请求然后计算正在做的事情。 The under-documented additional thing is that the code which POSTs to this URL to get a resumable session URL must include the "x-goog-resumable: start" header to trigger the upload. 未充分记录的附加信息是POST到此URL以获取可恢复会话URL的代码必须包含“x-goog-resumable:start”标头以触发上载。 From there, everything is the same as the docs for performing a resumable upload to GCS. 从那里开始,所有内容都与执行可恢复上传到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))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用Google App Engine(Java)创建剩余端点以将多部分数据上传到Google云存储 - How to create a rest endpoint using Google App Engine (Java) to upload multi part data to google cloud storage 通过Google App Engine(Java)将文件上传到Google云端存储 - Upload file to Google cloud storage from Google App Engine (Java) 使用 Java 和 JS 可恢复上传到 Google Cloud Storage - Resumable upload to Google Cloud Storage using Java and JS 适用于Java和Google云存储的Google App Engine - Google App Engine for Java and Google Cloud Storage 使用Java客户端库创建Google Cloud Storage存储桶 - Create a Google Cloud Storage bucket with the Java client library 如何使用Java App Engine正确上传(映像)文件到Google云端存储? - How to properly upload (image) file to Google Cloud Storage using Java App Engine? 带有Gradle的Google云端存储Java客户端库 - Google Cloud Storage Java Client Library with Gradle 通过Google App Engine(JAVA)将文件(图像或视频)从JSP上传到Google云存储 - Upload File (image or video) from JSP to google cloud storage via Google app engine(JAVA) 通过Servlet将文件从HTML表格上传到Google云端存储(使用Google Cloud Storage Client Library for Java) - Upload file from HTML form through Servlet to Google Cloud Storage (using Google Cloud Storage Client Library for Java) 无法使用GCS客户端库+ java将文件从GAE项目上传到Google云存储 - Not able to upload files from GAE project to Google cloud Storage using GCS Client library+java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM