/// <summary> /// Upload data to Amazon S3 using HTTP POST. /// </summary> /// <remarks> /// For more information, <see href="http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingHTTPPOST.html"/> /// </remarks> /// <param name="request">Request object which describes the data to POST</param> /// <param name="callback">An Action delegate that is invoked when the operation completes.</param> /// <param name="options">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property.</param> public void PostObjectAsync(PostObjectRequest request, AmazonServiceCallback<PostObjectRequest, PostObjectResponse> callback, AsyncOptions options = null) { options = options == null ? new AsyncOptions() : options; Action<AmazonWebServiceRequest, AmazonWebServiceResponse, Exception, AsyncOptions> callbackHelper = (AmazonWebServiceRequest req, AmazonWebServiceResponse res, Exception ex, AsyncOptions ao) => { AmazonServiceResult<PostObjectRequest, PostObjectResponse> responseObject = new AmazonServiceResult<PostObjectRequest, PostObjectResponse>((PostObjectRequest)req, (PostObjectResponse)res, ex, ao.State); if (callback != null) callback(responseObject); }; ThreadPool.QueueUserWorkItem(new WaitCallback(delegate { // Provide a default policy if user doesn't set it. try { InferContentType(request); if (request.SignedPolicy == null) { CreateSignedPolicy(request); } PostObject(request, options, callbackHelper); } catch (Exception e) { callback(new AmazonServiceResult<PostObjectRequest, PostObjectResponse>(request, null, e, options.State)); } })); }
private void CreateSignedPolicy(PostObjectRequest request) { if (request.ContentType == null) { int pos = request.Key.LastIndexOf('.'); string ext = null; if (pos != -1) { ext = request.Key.Substring(pos, request.Key.Length - pos); request.ContentType = AmazonS3Util.MimeTypeFromExtension(ext); } else { request.ContentType = "application/octet-stream"; } } string policyString = null; int position = request.Key.LastIndexOf('/'); if (position == -1) { policyString = "{\"expiration\": \"" + DateTime.UtcNow.AddHours(24).ToString("yyyy-MM-ddTHH:mm:ssZ") + "\",\"conditions\": [{\"bucket\": \"" + request.Bucket + "\"},[\"starts-with\", \"$key\", \"" + "\"],{\"acl\": \"private\"},[\"eq\", \"$Content-Type\", " + "\"" + request.ContentType + "\"" + "]]}"; } else { policyString = "{\"expiration\": \"" + DateTime.UtcNow.AddHours(24).ToString("yyyy-MM-ddTHH:mm:ssZ") + "\",\"conditions\": [{\"bucket\": \"" + request.Bucket + "\"},[\"starts-with\", \"$key\", \"" + request.Key.Substring(0, position) + "/\"],{\"acl\": \"private\"},[\"eq\", \"$Content-Type\", " + "\"" + request.ContentType + "\"" + "]]}"; } request.SignedPolicy = S3PostUploadSignedPolicy.GetSignedPolicy(policyString, base.Credentials); }
private void InferContentType(PostObjectRequest request) { if (String.IsNullOrEmpty(request.Headers.ContentType)) { if (request.Key.IndexOf('.') > -1) request.Headers.ContentType = AmazonS3Util.MimeTypeFromExtension(request.Key.Substring(request.Key.LastIndexOf('.'))); else if (!String.IsNullOrEmpty(request.Path) && request.Path.IndexOf('.') > -1) request.Headers.ContentType = AmazonS3Util.MimeTypeFromExtension(request.Key.Substring(request.Path.LastIndexOf('.'))); else request.Headers.ContentType = "application/octet-stream"; } }
public static PostObjectResponse PostObjectHelper(AmazonS3Client client, string bucketName, string key, PostObjectRequestManipulator manipulator = null) { using (MemoryStream stream = new MemoryStream()) { PostObjectResponse r = null; Exception responseException = null; StreamWriter writer = new StreamWriter(stream); writer.Write(TestContent); writer.Flush(); stream.Position = 0; AutoResetEvent ars = new AutoResetEvent(false); var request = new PostObjectRequest() { Bucket = bucketName, Key = key, InputStream = stream }; if (manipulator != null) { manipulator(request); } client.PostObjectAsync(request, (response) => { responseException = response.Exception; if (responseException == null) { r = response.Response; } else { Debug.LogWarning(new StreamReader((responseException as Amazon.Runtime.Internal.HttpErrorResponseException).Response.ResponseBody.OpenResponse()).ReadToEnd()); } ars.Set(); }, new AsyncOptions { ExecuteCallbackOnMainThread = false }); ars.WaitOne(); if (responseException != null) { throw responseException; } return r; } }
private void PostObject(PostObjectRequest request, AsyncOptions options, Action<AmazonWebServiceRequest, AmazonWebServiceResponse, Exception, AsyncOptions> callbackHelper) { string url; string subdomain = request.Region.Equals(RegionEndpoint.USEast1) ? "s3" : "s3-" + request.Region.SystemName; IDictionary<string, string> headers = new Dictionary<string, string>(); if (request.Bucket.IndexOf('.') > -1) url = string.Format(CultureInfo.InvariantCulture, "https://{0}.amazonaws.com/{1}/", subdomain, request.Bucket); else url = string.Format(CultureInfo.InvariantCulture, "https://{0}.{1}.amazonaws.com", request.Bucket, subdomain); Uri uri = new Uri(url); UnityWebRequest webRequest = new UnityWebRequest(uri); var boundary = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Replace('=', 'z'); headers[HeaderKeys.ContentTypeHeader] = string.Format(CultureInfo.InvariantCulture, "multipart/form-data; boundary={0}", boundary); headers[HeaderKeys.UserAgentHeader] = AWSSDKUtils.UserAgentHeader; webRequest.Method = "POST"; using (var reqStream = new MemoryStream()) { request.WriteFormData(boundary, reqStream); byte[] boundaryBytes = Encoding.UTF8.GetBytes(string.Format(CultureInfo.InvariantCulture, "--{0}\r\nContent-Disposition: form-data; name=\"file\"\r\n\r\n", boundary)); reqStream.Write(boundaryBytes, 0, boundaryBytes.Length); using (var inputStream = null == request.Path ? request.InputStream : File.OpenRead(request.Path)) { byte[] buf = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.Read(buf, 0, 1024)) > 0) { reqStream.Write(buf, 0, bytesRead); } } byte[] endBoundaryBytes = Encoding.UTF8.GetBytes(string.Format(CultureInfo.InvariantCulture, "\r\n--{0}--", boundary)); reqStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); webRequest.WriteToRequestBody(null, reqStream.ToArray(), headers); } var executionContext = new AsyncExecutionContext( new AsyncRequestContext(this.Config.LogMetrics) { ClientConfig = this.Config, OriginalRequest = request, Action = callbackHelper, AsyncOptions = options, IsAsync = true }, new AsyncResponseContext() ); webRequest.SetRequestHeaders(headers); executionContext.RuntimeState = webRequest; executionContext.ResponseContext.AsyncResult = new RuntimeAsyncResult(executionContext.RequestContext.Callback, executionContext.RequestContext.State); executionContext.ResponseContext.AsyncResult.AsyncOptions = executionContext.RequestContext.AsyncOptions; executionContext.ResponseContext.AsyncResult.Action = executionContext.RequestContext.Action; executionContext.ResponseContext.AsyncResult.Request = executionContext.RequestContext.OriginalRequest; webRequest.BeginGetResponse(new AsyncCallback(ProcessPostResponse), executionContext); }
/// <summary> /// Post Object to S3 Bucket. /// </summary> public void PostObject() { ResultText.text = "Retrieving the file"; string fileName = GetFileHelper(); var stream = new FileStream(Application.persistentDataPath + Path.DirectorySeparatorChar + fileName, FileMode.Open, FileAccess.Read, FileShare.Read); ResultText.text += "\nCreating request object"; var request = new PostObjectRequest() { Bucket = S3BucketName, Key = fileName, InputStream = stream, CannedACL = S3CannedACL.Private }; ResultText.text += "\nMaking HTTP post call"; Client.PostObjectAsync(request, (responseObj) => { if (responseObj.Exception == null) { ResultText.text += string.Format("\nobject {0} posted to bucket {1}", responseObj.Request.Key, responseObj.Request.Bucket); } else { ResultText.text += "\nException while posting the result object"; ResultText.text += string.Format("\n receieved error {0}", responseObj.Response.HttpStatusCode.ToString()); } }); }
private void CreateSignedPolicy(PostObjectRequest request) { StringBuilder metadataPolicy = new StringBuilder(); foreach (var kvp in request.Metadata) { var metakey = kvp.Key.StartsWith(S3Constants.PostFormDataXAmzPrefix, StringComparison.Ordinal) ? kvp.Key : S3Constants.PostFormDataMetaPrefix + kvp.Key; metadataPolicy.Append(string.Format(",{{\"{0}\": \"{1}\"}}", metakey, kvp.Value)); } StringBuilder headersPolicy = new StringBuilder(); foreach (var key in request.Headers.Keys) { headersPolicy.Append(string.Format(",{{\"{0}\": \"{1}\"}}", key, request.Headers[key])); } string policyString = null; int position = request.Key.LastIndexOf('/'); if (position == -1) { policyString = "{\"expiration\": \"" + DateTime.UtcNow.AddHours(24).ToString("yyyy-MM-ddTHH:mm:ssZ") + "\",\"conditions\": [{\"bucket\": \"" + request.Bucket + "\"},[\"starts-with\", \"$key\", \"" + "\"],{\"acl\": \"" + request.CannedACL.Value + "\"},[\"eq\", \"$Content-Type\", " + "\"" + request.Headers.ContentType + "\"" + "]" + metadataPolicy.ToString() + headersPolicy.ToString() + "]}"; } else { policyString = "{\"expiration\": \"" + DateTime.UtcNow.AddHours(24).ToString("yyyy-MM-ddTHH:mm:ssZ") + "\",\"conditions\": [{\"bucket\": \"" + request.Bucket + "\"},[\"starts-with\", \"$key\", \"" + request.Key.Substring(0, position) + "/\"],{\"acl\": \"" + request.CannedACL.Value + "\"},[\"eq\", \"$Content-Type\", " + "\"" + request.Headers.ContentType + "\"" + "]" + metadataPolicy.ToString() + headersPolicy.ToString() + "]}"; } if (Config.SignatureVersion == "2") { request.SignedPolicy = S3PostUploadSignedPolicy.GetSignedPolicy(policyString, base.Credentials); } else { request.SignedPolicy = S3PostUploadSignedPolicy.GetSignedPolicyV4(policyString, base.Credentials, request.Region); } }