admin管理员组文章数量:1406007
Previously, I used the following approach to allow users to upload files to our cloud storage service:
- Server-side (Python): Generate a time-limited presigned upload URL.
- Client-side (Java): Upload the file using the presigned URL.
Java Code: Uploading a File
private static boolean upload(String urlAsString, File inputFile, String checksum) {
boolean success = false;
HttpURLConnection urlConnection = null;
FileInputStream fileInputStream = null;
OutputStream outputStream = null;
try {
URL url = new URL(urlAsString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod(PUT);
urlConnection.setConnectTimeout(CONNECT_TIMEOUT);
urlConnection.setReadTimeout(READ_TIMEOUT);
//
urlConnection.setDoOutput(true);
//
// Checksum
//
if (checksum != null) {
urlConnection.setRequestProperty("content-md5", checksum);
urlConnection.setRequestProperty("x-amz-meta-md5", checksum);
}
//
// Do this before writting to output stream.
//
final long length = inputFile.length();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
urlConnection.setFixedLengthStreamingMode(length);
}
urlConnection.setRequestProperty("Content-Length", String.valueOf(length));
fileInputStream = new FileInputStream(inputFile);
outputStream = urlConnection.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bufferLength = 0;
while ((bufferLength = fileInputStream.read(buffer)) != -1) {
if (bufferLength > 0) {
outputStream.write(buffer, 0, bufferLength);
}
}
int responseCode = urlConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
success = true;
}
} catch (MalformedURLException e) {
Log.e(TAG, "", e);
} catch (IOException e) {
Log.e(TAG, "", e);
} finally {
close(fileInputStream);
close(outputStream);
if (urlConnection != null) {
urlConnection.disconnect();
}
}
Python Code: Generating a Presigned Upload URL
def get_presigned_upload_url(s3_client, customer_id, key, checksum):
presigned_upload_url = None
if checksum is None:
presigned_upload_url = s3_client.generate_presigned_url(
ClientMethod='put_object',
Params={
'Bucket': constants.S3_BUCKET_NAME,
'Key': get_user_folder_name(customer_id) + key
},
ExpiresIn=constants.EXPIRES_IN
)
else:
presigned_upload_url = s3_client.generate_presigned_url(
ClientMethod='put_object',
Params={
'Bucket': constants.S3_BUCKET_NAME,
'Key': get_user_folder_name(customer_id) + key,
'ContentMD5': checksum,
'Metadata': {
'md5' : checksum
}
},
ExpiresIn=constants.EXPIRES_IN
)
return presigned_upload_url
Issue: HTTP 200 OK, but File Not in S3?
I noticed cases where the client-side upload returns HttpURLConnection.HTTP_OK, but the file does not reach S3. (Is this even possible?!)
To verify the upload's correctness, I implemented an additional verification step after uploading.
Java Code: Verifying the Upload
private static boolean verifyUpload(String headUrl, String checksum) {
boolean success = false;
HttpURLConnection headConnection = null;
try {
headConnection = (HttpURLConnection) new URL(headUrl).openConnection();
headConnection.setRequestMethod("HEAD");
final int headResponseCode = headConnection.getResponseCode();
if (headResponseCode == HttpURLConnection.HTTP_OK) {
final String metaMd5 = headConnection.getHeaderField("x-amz-meta-md5");
success = checksum.equals(metaMd5);
}
} catch (MalformedURLException e) {
Log.e(TAG, "", e);
} catch (IOException e) {
Log.e(TAG, "", e);
} finally {
if (headConnection != null) {
headConnection.disconnect();
}
}
return success;
}
Python Code: Generating a Presigned HEAD URL for Verification
def get_presigned_head_url(s3_client, customer_id, key):
"""
Generate a pre-signed URL to perform a HEAD request on an S3 object.
This URL allows the client to check if the upload was successful.
"""
presigned_head_url = s3_client.generate_presigned_url(
ClientMethod='head_object',
Params={
'Bucket': constants.S3_BUCKET_NAME,
'Key': get_user_folder_name(customer_id) + key
},
ExpiresIn=constants.EXPIRES_IN
)
return presigned_head_url
Does This Approach Make Sense?
Would this method reliably verify uploads, given that HTTP_OK
does not always mean a successful upload to S3? Any feedback would be appreciated.
本文标签: pythonEnsuring Successful File Uploads to S3 Using Presigned URLsStack Overflow
版权声明:本文标题:python - Ensuring Successful File Uploads to S3 Using Presigned URLs - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744961445a2634676.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论