我正在尝试在我的App Engine代码中创建一个已签名的URL并将其传递给客户端以进行初始POST调用以获取可恢复的上载位置,遵循文档中的以下建议:
在未启动的区域内执行可恢复上传 导致上传速度慢。为避免这种情况,您可以进行初始POST 请求由服务器构造和签名,但随后给出签名 客户端的URL,以便从其位置启动上载。
但是,当客户端对签名URL进行POST调用时,此调用会导致错误401,这会告诉我Cloud Storage需要授权标头。
这是我签名的网址的样子:
我在App Engine端使用相同的代码来生成下载的签名URL,它们工作正常。
这是组合初始POST调用的URL的正确方法吗?是否有其他原因导致此错误?
修改
生成网址的代码:
long expiration = System.currentTimeMillis()/1000 + 60;
String unsigned = stringToSign(expiration, gsKey, "POST");
String signature = sign(unsigned);
return new StringBuilder("https://www.googleapis.com/upload/storage/v1/b/")
.append(BUCKET)
.append("/o?uploadType=resumable&name=")
.append(gsKey)
.append("&GoogleAccessId=")
.append(identityService.getServiceAccountName())
.append("&Expires=")
.append(expiration)
.append("&Signature=")
.append(URLEncoder.encode(signature, "UTF-8"))
.toString();
private static String stringToSign(final long expiration, String gsKey, String httpVerb) {
String contentType = "";
String contentMD5 = "";
String canonicalizedExtensionHeaders = "";
String canonicalizedResource = "/" + BUCKET + "/" + gsKey;
String stringToSign = httpVerb + "\n" +
contentMD5 + "\n" +
contentType + "\n" +
expiration + "\n" +
canonicalizedExtensionHeaders + "\n" +
canonicalizedResource;
return stringToSign;
}
private static String sign(final String stringToSign) throws UnsupportedEncodingException {
SigningResult signingResult = identityService.signForApp(stringToSign.getBytes());
String encodedSignature = new String(Base64.encodeBase64(signingResult.getSignature(), false), "UTF-8");
return encodedSignature;
}