我想創建一個簽名的URL,並從我的電腦上傳文件到谷歌雲存儲使用它。無法成功上傳文件使用簽名的URL到谷歌雲存儲從高級REST客戶端
我正在使用高級REST客戶端(ARC)作爲客戶端應用程序。在服務器端,我有一個在Appengine上運行的基於球衣的服務器。
我首先從ARC發送一個GET請求,接收哪個app引擎生成一個簽名的URL並將它返回給響應。
之後,我做了一個PUT請求,我要在正文中上傳文件,請求URL設置爲在GET響應中收到的內容。
的代碼片斷創建簽署網址:
String encodedUrl = null;
String contentMD5 = "";
String contentType = "";
String httpVerb;
httpVerb = "PUT";
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 10);
long expiration = calendar.getTimeInMillis()/1000L;
String canonicalizedResource = "/" + bucketName + "/" + objectName;
String baseURL = "https://storage.googleapis.com" + canonicalizedResource;
String stringToSign =
httpVerb + "\n" + contentMD5 + "\n" + contentType + "\n" + expiration + "\n"
+ canonicalizedResource;
AppIdentityService service = AppIdentityServiceFactory.getAppIdentityService();
String googleAccessId = service.getServiceAccountName();
SigningResult signingResult = service.signForApp(stringToSign.getBytes());
String encodedSignature = null;
try {
encodedSignature =
new String(Base64.encodeBase64(signingResult.getSignature(), false), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new InternalServerErrorException();
}
String signature = null;
try {
signature = URLEncoder.encode(encodedSignature, "UTF-8").toString();
} catch (UnsupportedEncodingException e) {
throw new InternalServerErrorException();
}
encodedUrl =
baseURL + "?GoogleAccessId=" + googleAccessId + "&Expires=" + expiration
+ "&Signature=" + signature;
System.out.println("Signed URL is: "+encodedUrl);
但是我觀察了以下問題:
每當我發送任何文件類型的PUT請求,我得到以下錯誤:
錯誤 - 403
碼 - SignatureDoesNotMatch消息 - 我們計算的請求籤名與您提供的簽名不匹配。檢查您的Google祕密密鑰和簽名方法
請注意,在我的代碼中,我在創建要簽名的字符串時將內容類型設置爲「」。同時創建PUT請求時,我不包含任何Content-type標頭。
據我所知,如果我在創建簽名URL時不在stringToSign中包含contentType,並且在發送PUT請求時沒有將其作爲頭添加,它應該沒問題。那麼錯誤的原因是什麼?
- 之後,我通過代碼進行了更改,並在代碼中創建stringToSign時添加了contentType,並在發送PUT請求時給出了相應的Content-Type頭。
在這種情況下,我可以上傳文件,但上傳的文件被修改/損壞。我嘗試使用text/plain和image/jpeg。
的問題是,下面的文字是在文件的開頭說:
------WebKitFormBoundaryZX8rPPhnm1WXPrUf
Content-Disposition: form-data; name="fileUpload5"; filename="blob"
Content-Type: text/plain
我可以在文本文件,並在十六進制編輯器打開.jpg文件看到這一點。 .jpg在標準圖像應用程序中無法打開,因爲文件已被開頭的文本損壞
我在這裏丟失了什麼嗎?這是高級REST客戶端中的任何問題嗎? 實際上,無論何時我發送PUT請求與正文中的某個文件,我都會在ARC中收到一條消息: 內容類型標題將在發送請求時最終更改爲multipart/form-data 但是,我保存將所有消息導出到ARC的文件中,但沒有發現任何Content-type頭部設置爲multipart/form-data的消息。 那麼爲什麼這個消息來了,它實際上是一個問題?
謝謝。正如您所提到的那樣,高級REST客戶端似乎存在一些問題,因爲即使指定了其他內容類型,它也會將上載作爲多部分表單數據進行上傳。我找不到如何更改設置,但我現在使用curl命令行工具進行上傳/下載,並且工作正常。 –