Example #1
0
        protected void GenerateNewCredentialsAsync(AmazonServiceCallback callback)
        {
            AmazonServiceResult voidResult = new AmazonServiceResult(null, null);

            IdentityProvider.RefreshAsync(delegate(AmazonServiceResult refreshResult)
            {
                if (refreshResult.Exception != null)
                {
                    voidResult.Exception = refreshResult.Exception;
                    AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
                    return;
                }


                // Pick role to use, depending on Logins
                string roleArn = UnAuthRoleArn;
                if (IdentityProvider.Logins.Count > 0)
                {
                    roleArn = AuthRoleArn;
                }
                if (string.IsNullOrEmpty(roleArn))
                {
                    voidResult.Exception = new AmazonServiceException(
                        new InvalidOperationException(string.Format(CultureInfo.InvariantCulture,
                                                                    "Unable to determine Role ARN. AuthRoleArn = [{0}], UnAuthRoleArn = [{1}], Logins.Count = {2}",
                                                                    AuthRoleArn, UnAuthRoleArn, IdentityProvider.Logins.Count)));
                    AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
                    return;
                }

                // Assume role with Open Id Token
                var assumeRequest = new AssumeRoleWithWebIdentityRequest
                {
                    WebIdentityToken = IdentityProvider.GetCurrentOpenIdToken(),
                    RoleArn          = roleArn,
                    RoleSessionName  = "UnityProviderSession",
                    DurationSeconds  = DefaultDurationSeconds
                };

                sts.AssumeRoleWithWebIdentityAsync(assumeRequest, delegate(AmazonServiceResult result)
                {
                    if (result.Exception != null)
                    {
                        voidResult.Exception = result.Exception;
                        AmazonLogging.LogError(AmazonLogging.AmazonLoggingLevel.Errors, "STS", result.Exception.Message);
                        AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
                        return;
                    }
                    AssumeRoleWithWebIdentityResponse assumeRoleWithWebIdentityResponse = result.Response as AssumeRoleWithWebIdentityResponse;
                    this._currentState = new CredentialsRefreshState
                    {
                        Credentials = assumeRoleWithWebIdentityResponse.Credentials.GetCredentials(),
                        Expiration  = assumeRoleWithWebIdentityResponse.Credentials.Expiration
                    };
                    // success - FinalResponse
                    AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
                    return;
                }, null);
            }, null);
        }
        public override void RefreshDatasetMetadataAsync(AmazonCognitoCallback callback, object state)
        {
            AmazonCognitoResult callbackResult = new AmazonCognitoResult(state);

            cognitoCredentials.GetCredentialsAsync(delegate(AmazonServiceResult getCredentialsResult) {
                if (getCredentialsResult.Exception != null)
                {
                    callbackResult.Exception = getCredentialsResult.Exception;
                    AmazonMainThreadDispatcher.ExecCallback(callback, callbackResult);
                    return;
                }
                remote.GetDatasetsAsync(delegate(AmazonCognitoResult result)
                {
                    if (result.Exception != null)
                    {
                        callbackResult.Exception = result.Exception;
                    }
                    else
                    {
                        GetDatasetsResponse response = result.Response as GetDatasetsResponse;
                        local.UpdateDatasetMetadata(GetIdentityId(), response.Datasets);
                        callbackResult.Response = response;
                    }
                    AmazonMainThreadDispatcher.ExecCallback(callback, callbackResult);
                }, state);
            }, null);
        }
Example #3
0
        public override void RefreshAsync(AmazonServiceCallback callback, object state)
        {
            //_token = null;
            AmazonServiceResult voidResult = new AmazonServiceResult(null, state);

            if (!IsIdentitySet)
            {
                var getIdRequest = new GetIdRequest
                {
                    AccountId      = null,
                    IdentityPoolId = IdentityPoolId,
                    Logins         = Logins
                };
                cib.GetIdAsync(getIdRequest, delegate(AmazonServiceResult result)
                {
                    if (result.Exception != null)
                    {
                        voidResult.Exception = result.Exception;
                        AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
                        return;
                    }
                    var getIdResponse = result.Response as GetIdResponse;
                    UpdateIdentity(getIdResponse.IdentityId);
                    AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
                }, null);
            }
            else
            {
                AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
            }
        }
    public override void RefreshAsync(AmazonServiceCallback callback, object state)
    {
        try
        {
            if (Logins == null)
            {
                Logins = new Dictionary <string, string>();
            }

            /// Using this call, get an identityId and a valid Cognito openid token from
            ///  your backend to get a reference to both for the local device.
            ///  Call update method to make sure the identityId and token are now
            ///  handy and are utilized appropriately
            /// http://mobile.awsblog.com/post/Tx1YVAQ4NZKBWF5/Amazon-Cognito-Announcing-Developer-Authenticated-Identities
            /// AmazonMainThreadDispatch.ExecCoroutine() is available in case you have to want to yield on a WWW request
            _identityId = "retrievedIdentityID";
            _token      = "retrivedDeveloperToken";

            Logins[getProviderName()] = _token;
            UpdateIdentity(_identityId);
            AmazonMainThreadDispatcher.ExecCallback(callback, new AmazonServiceResult(null, null, null, state));
        }
        catch (Exception ex)
        {
            AmazonMainThreadDispatcher.ExecCallback(callback, new AmazonServiceResult(null, null, new AmazonServiceException(ex), state));
        }
    }
        public override void GetDatasetMetadataAsync(string datasetName, AmazonCognitoCallback callback, object state)
        {
            DescribeDatasetRequest request = new DescribeDatasetRequest();

            //appendUserAgent(request, userAgent);
            request.IdentityPoolId = identityPoolId;
            request.IdentityId     = this.GetCurrentIdentityId();
            request.DatasetName    = datasetName;
            client.DescribeDatasetAsync(request, delegate(AmazonServiceResult describeDatasetResult)
            {
                AmazonCognitoResult callbackResult = new AmazonCognitoResult(state);
                if (describeDatasetResult.Exception != null)
                {
                    callbackResult.Exception = new DataStorageException("Failed to get metadata of dataset: "
                                                                        + datasetName, describeDatasetResult.Exception);
                }
                else
                {
                    callbackResult.Response = new DatasetMetadataResponse
                    {
                        Metadata = ModelToDatasetMetadata((describeDatasetResult.Response as DescribeDatasetResponse).Dataset)
                    };
                }
                AmazonMainThreadDispatcher.ExecCallback(callback, callbackResult);
            }, null);
        }
Example #6
0
        // This method is to avoid having redundant code based on IsIdentitySet check
        private void GetOpenIdMethod(AmazonServiceResult voidResult, AmazonServiceCallback callback)
        {
            var getTokenRequest = new GetOpenIdTokenRequest
            {
                IdentityId = GetCurrentIdentityId(),
                Logins     = this.Logins
            };

            cib.GetOpenIdTokenAsync(getTokenRequest, delegate(AmazonServiceResult getOpenIdTokenResult)
            {
                if (getOpenIdTokenResult.Exception != null)
                {
                    if (callback != null)
                    {
                        voidResult.Exception = getOpenIdTokenResult.Exception;
                        AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
                    }
                    return;
                }
                var getOpenIdTokenResponse = getOpenIdTokenResult.Response as GetOpenIdTokenResponse;
                _token = getOpenIdTokenResponse.Token;

                this.UpdateIdentity(getOpenIdTokenResponse.IdentityId);

                AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
            }, null);
        }
Example #7
0
 internal void InvokeCallback()
 {
     //this.SignalWaitHandle();
     if (!_callbackInvoked && this.Callback != null)
     {
         _callbackInvoked = true;
         AmazonMainThreadDispatcher.ExecCallback(this.Callback, this.ServiceResult);
     }
 }
        private void PopulateListUpdates(string datasetName, long lastSyncCount, List <Record> records, string nextToken, AmazonCognitoCallback callback, object state)
        {
            {
                ListRecordsRequest request = new ListRecordsRequest();
                //appendUserAgent(request, userAgent);
                request.IdentityPoolId = identityPoolId;
                request.IdentityId     = this.GetCurrentIdentityId();
                request.DatasetName    = datasetName;
                request.LastSyncCount  = lastSyncCount;
                // mark it large enough to reduce # of requests
                request.MaxResults = 1024;
                request.NextToken  = nextToken;

                client.ListRecordsAsync(request, delegate(AmazonServiceResult result)
                {
                    if (result.Exception != null)
                    {
                        AmazonMainThreadDispatcher.ExecCallback(callback,
                                                                new AmazonCognitoResult(null, HandleException(result.Exception, "Failed to list records in dataset: " + datasetName), state));

                        return;
                    }

                    ListRecordsResponse listRecordsResponse = result.Response as ListRecordsResponse;
                    foreach (Amazon.CognitoSync.Model.Record remoteRecord in listRecordsResponse.Records)
                    {
                        //builder.addRecord(modelToRecord(remoteRecord));
                        records.Add(this.ModelToRecord(remoteRecord));
                    }
                    if (listRecordsResponse.NextToken == null)
                    {
                        DatasetUpdatesImpl updates = new DatasetUpdatesImpl(
                            datasetName,
                            records,
                            listRecordsResponse.DatasetSyncCount,
                            listRecordsResponse.SyncSessionToken,
                            listRecordsResponse.DatasetExists,
                            listRecordsResponse.DatasetDeletedAfterRequestedSyncCount,
                            listRecordsResponse.MergedDatasetNames
                            );
                        ListUpdatesResponse listUpdatesResponse = new ListUpdatesResponse
                        {
                            DatasetUpdates = updates
                        };
                        AmazonMainThreadDispatcher.ExecCallback(callback,
                                                                new AmazonCognitoResult(listUpdatesResponse, null, state));
                        return;
                    }
                    // update last evaluated key
                    nextToken = listRecordsResponse.NextToken;

                    // emulating the while loop
                    PopulateListUpdates(datasetName, lastSyncCount, records, nextToken, callback, state);
                }, state);
            }
        }
Example #9
0
        // fetching/persisting new credentials in LocalStorage
        public override void GetCredentialsAsync(AmazonServiceCallback callback, object state)
        //internal IEnumerator GetCredentialsCoroutine(VoidResponse voidResponse)
        {
            //lock (this._refreshLock)
            //{

            //
            if (_currentState == null)
            {
                loadCachedCredentials();
            }
            // If credentials are expired, update
            if (ShouldUpdate)
            {
                GenerateNewCredentialsAsync(delegate(AmazonServiceResult voidResult)
                {
                    if (voidResult.Exception != null)
                    {
                        AmazonLogging.LogError(AmazonLogging.AmazonLoggingLevel.Errors, "Cognito", "Error occured during GetCredentialsAsync");
                        AmazonMainThreadDispatcher.ExecCallback(callback, new AmazonServiceResult(null, null, voidResult.Exception, state));
                        return;
                    }
                    // Check if the new credentials are already expired
                    if (ShouldUpdate)
                    {
                        voidResult.Exception = new AmazonServiceException("The retrieved credentials have already expired");
                        AmazonMainThreadDispatcher.ExecCallback(callback, new AmazonServiceResult(null, null, voidResult.Exception, state));
                        return;
                    }

                    // Offset the Expiration by PreemptExpiryTime
                    _currentState.Expiration -= PreemptExpiryTime;

                    if (ShouldUpdate)
                    {
                        // This could happen if the default value of PreemptExpiryTime is
                        // overriden and set too high such that ShouldUpdate returns true.

                        voidResult.Exception = new AmazonClientException(String.Format(
                                                                             "The preempt expiry time is set too high: Current time = {0}, Credentials expiry time = {1}, Preempt expiry time = {2}.",
                                                                             DateTime.Now, _currentState.Expiration, PreemptExpiryTime));
                        AmazonMainThreadDispatcher.ExecCallback(callback, new AmazonServiceResult(null, null, voidResult.Exception, state));
                        return;
                    }
                    saveCredentials();
                    AmazonMainThreadDispatcher.ExecCallback(callback, new AmazonServiceResult(null, null, null, state));
                });
                return;
            }
            AmazonMainThreadDispatcher.ExecCallback(callback, new AmazonServiceResult(null, null, null, state));


            //}
        }
Example #10
0
 private static void Execute <T>(AsyncCall call, DynamoDBAsyncState <T> result)
 {
     try
     {
         result.Return = call();
         AmazonMainThreadDispatcher.ExecCallback <T>(result.Callback, new AmazonDynamoResult <T>((T)result.Return, null, result.State));
         return;
     }
     catch (Exception ex)
     {
         AmazonLogging.LogException(AmazonLogging.AmazonLoggingLevel.Errors, result.Operation, ex);
         AmazonMainThreadDispatcher.ExecCallback <T>(result.Callback, new AmazonDynamoResult <T>(default(T), ex, result.State));
         return;
     }
 }
Example #11
0
        private void PopulateCredentialsWithCognito(AmazonServiceCallback callback)
        {
            AmazonServiceResult voidResult = new AmazonServiceResult(null, null);

            GetCredentialsForIdentityRequest request = new GetCredentialsForIdentityRequest();

            request.IdentityId = IdentityProvider.GetCurrentIdentityId();
            String token = IdentityProvider.GetCurrentOpenIdToken();

            if (token != null && token.Length != 0)
            {
                request.Logins = new Dictionary <string, string>();
                request.Logins.Add("cognito-identity.amazonaws.com", token);
            }
            else
            {
                request.Logins = IdentityProvider.Logins;
            }

            IdentityProvider.cib.GetCredentialsForIdentityAsync(request, delegate(AmazonServiceResult result){
                if (result.Exception != null)
                {
                    voidResult.Exception = result.Exception;
                    Debug.LogError(result.Exception.Message);
                    AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
                    return;
                }
                GetCredentialsForIdentityResult credentialsResult = result.Response as GetCredentialsForIdentityResult;

                ///Calling this will trigger clear _sessionCredentials, so it's important to do it before
                if (credentialsResult.IdentityId != IdentityProvider.GetCurrentIdentityId())
                {
                    IdentityProvider.UpdateIdentity(credentialsResult.IdentityId);
                }

                this._sessionCredentials = new CredentialsRefreshState
                {
                    Credentials = new ImmutableCredentials(credentialsResult.Credentials.AccessKeyId,
                                                           credentialsResult.Credentials.SecretKey,
                                                           credentialsResult.Credentials.SessionToken),
                    Expiration = credentialsResult.Credentials.Expiration.ToUniversalTime()
                };

                // success - FinalResponse
                AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
            }, null);
        }
        public override void PutRecordsAsync(string datasetName, List <Record> records, string syncSessionToken, AmazonCognitoCallback callback, object state)
        {
            UpdateRecordsRequest request = new UpdateRecordsRequest();

            //appendUserAgent(request, userAgent);
            request.DatasetName      = datasetName;
            request.IdentityPoolId   = identityPoolId;
            request.IdentityId       = this.GetCurrentIdentityId();
            request.SyncSessionToken = syncSessionToken;

            // create patches
            List <RecordPatch> patches = new List <RecordPatch>();

            foreach (Record record in records)
            {
                patches.Add(this.RecordToPatch(record));
            }
            request.RecordPatches = patches;

            List <Record> updatedRecords = new List <Record>();

            client.UpdateRecordsAsync(request, delegate(AmazonServiceResult result)
            {
                AmazonCognitoResult callbackResult = new AmazonCognitoResult(state);

                if (result.Exception != null)
                {
                    callbackResult.Exception = HandleException(result.Exception, "Failed to update records in dataset: " + datasetName);
                }
                else
                {
                    UpdateRecordsResponse updateRecordsResponse = result.Response as UpdateRecordsResponse;
                    foreach (Amazon.CognitoSync.Model.Record remoteRecord in updateRecordsResponse.Records)
                    {
                        updatedRecords.Add(ModelToRecord(remoteRecord));
                    }
                    callbackResult.Response = new PutRecordsResponse {
                        UpdatedRecords = updatedRecords
                    };
                }

                AmazonMainThreadDispatcher.ExecCallback(callback, callbackResult);
            }, null);
        }
Example #13
0
        protected void GenerateNewCredentialsAsync(AmazonServiceCallback callback)
        {
            AmazonServiceResult voidResult = new AmazonServiceResult(null, null);

            AmazonServiceCallback refreshCallback = null;

            refreshCallback = delegate(AmazonServiceResult refreshResult)
            {
                if (refreshResult.Exception != null)
                {
                    if (refreshResult.Exception is ResourceNotFoundException)
                    {
                        //Try again
                        IdentityProvider.UpdateIdentity(null);
                        IdentityProvider.RefreshAsync(refreshCallback, null);
                    }
                    else if (refreshResult.Exception is AmazonServiceException && (refreshResult.Exception as AmazonServiceException).ErrorCode == "ValidationException")
                    {
                        IdentityProvider.UpdateIdentity(null);
                        IdentityProvider.RefreshAsync(refreshCallback, null);
                    }
                    else
                    {
                        Debug.LogError("RefreshAsync failed");
                        voidResult.Exception = refreshResult.Exception;
                        AmazonMainThreadDispatcher.ExecCallback(callback, voidResult);
                        return;
                    }
                }

                if (sts != null)
                {
                    PopulateCredentialsWithSTS(callback);
                }
                else
                {
                    PopulateCredentialsWithCognito(callback);
                }
            };

            IdentityProvider.RefreshAsync(refreshCallback, null);
        }
Example #14
0
    public override void RefreshAsync(AmazonServiceCallback callback, object state)
    {
        try
        {
            /// Using this call, get an identityId and a valid Cognito openid token from your
            /// backend to get a reference to both for the local device and call UpdateIdentity
            /// http://mobile.awsblog.com/post/Tx1YVAQ4NZKBWF5/Amazon-Cognito-Announcing-Developer-Authenticated-Identities
            /// AmazonMainThreadDispatcher.ExecCoroutine() can be useful in case you have to want
            /// to yield on a WWW request: AmazonMainThreadDispatcher.ExecCoroutine(ContactWebBackend(callback));

            _token = "retrivedDeveloperToken";
            Logins[getProviderName()] = _token;
            UpdateIdentity("retrievedIdentityID");

            AmazonMainThreadDispatcher.ExecCallback(callback, new AmazonServiceResult(null, null, null, state));
        }
        catch (Exception ex)
        {
            AmazonMainThreadDispatcher.ExecCallback(callback, new AmazonServiceResult(null, null, new AmazonServiceException(ex), state));
        }
    }
        private void PopulateGetDatasets(string nextToken, List <DatasetMetadata> datasets, AmazonCognitoCallback callback, object state)
        {
            ListDatasetsRequest request = new ListDatasetsRequest();

            //appendUserAgent(request, userAgent);
            request.IdentityPoolId = identityPoolId;
            request.IdentityId     = this.GetCurrentIdentityId();
            // a large enough number to reduce # of requests
            request.MaxResults = 64;
            request.NextToken  = nextToken;

            client.ListDatasetsAsync(request, delegate(AmazonServiceResult result)
            {
                if (result.Exception != null)
                {
                    AmazonMainThreadDispatcher.ExecCallback(callback, new AmazonCognitoResult(null,
                                                                                              HandleException(result.Exception, "Failed to list dataset metadata"), state));
                    return;
                }

                ListDatasetsResponse response = result.Response as ListDatasetsResponse;
                foreach (Amazon.CognitoSync.Model.Dataset dataset in response.Datasets)
                {
                    datasets.Add(ModelToDatasetMetadata(dataset));
                }

                nextToken = response.NextToken;

                if (nextToken == null)
                {
                    GetDatasetsResponse getDatasetsResponse = new GetDatasetsResponse
                    {
                        Datasets = datasets
                    };
                    AmazonMainThreadDispatcher.ExecCallback(callback, new AmazonCognitoResult(getDatasetsResponse, null, state));
                    return;
                }
                PopulateGetDatasets(nextToken, datasets, callback, state);
            }, null);
        }
        public override void DeleteDatasetAsync(string datasetName, AmazonCognitoCallback callback, object state)
        {
            DeleteDatasetRequest request = new DeleteDatasetRequest();

            //appendUserAgent(request, userAgent);
            request.IdentityPoolId = identityPoolId;
            request.IdentityId     = this.GetCurrentIdentityId();
            request.DatasetName    = datasetName;
            client.DeleteDatasetAsync(request, delegate(AmazonServiceResult deleteDatasetResult)
            {
                AmazonCognitoResult result = new AmazonCognitoResult(state);
                if (deleteDatasetResult.Exception == null)
                {
                    result.Exception = HandleException(deleteDatasetResult.Exception, "Failed to delete dataset: " + datasetName);
                }
                else
                {
                    result.Exception = new Exception("Unsupported DeleteDatasetAsync");
                    //result.Response = deleteDatasetResult.Response;
                }
                AmazonMainThreadDispatcher.ExecCallback(callback, result);
            }, null);
        }
        /// <summary>
        /// Perform signing, setup WWWRequestData with headers, binary data(for POST request)
        /// and enqueues to the RequestQueue for Main thread
        /// </summary>
        /// <param name="asyncResult"></param>
        private void ProcessHttpRequest(AsyncResult asyncResult)
        {
            try
            {
                // prepare request
                IRequest wrappedRequest = asyncResult.Request;

                WWWRequestData requestData = new WWWRequestData();
                if (HttpOverrideSupportedServices.Contains(asyncResult.Request.ServiceName))
                {
                    asyncResult.Request.Headers.Add("X-HTTP-Method-Override", asyncResult.Request.HttpMethod);

                    if (asyncResult.Request.HttpMethod == "GET")
                    {
                        string emptyString = "{}";
                        asyncResult.Request.ContentStream = new MemoryStream(Encoding.UTF8.GetBytes(emptyString));
                        requestData.Data = Encoding.Default.GetBytes(emptyString);
                    }
                }

#if UNITY_WEBPLAYER
                wrappedRequest.Headers.Remove("User-Agent");
                wrappedRequest.Headers.Remove("Host");
#endif

                SignRequest(asyncResult);

                if (asyncResult.RetriesAttempt > 0)
                {
                    HandleRetry(asyncResult);
                }


                requestData.Url = ComposeUrl(wrappedRequest, wrappedRequest.Endpoint).ToString();

                if (!wrappedRequest.UseQueryString && !(wrappedRequest.HttpMethod.Equals("GET", StringComparison.OrdinalIgnoreCase)))
                {
                    if (wrappedRequest.ContentStream != null)
                    {
                        if (wrappedRequest.OriginalRequest.IncludeSHA256Header &&
                            !wrappedRequest.Headers.ContainsKey(HeaderKeys.XAmzContentSha256Header))
                        {
                            requestData.Headers.Add(HeaderKeys.XAmzContentSha256Header, wrappedRequest.ComputeContentStreamHash());
                        }
                    }
                }

                AddHeaders2(requestData, wrappedRequest.Headers);

                if (asyncResult.Unmarshaller is JsonResponseUnmarshaller)
                {
                    requestData.Headers.Add(HeaderKeys.AcceptHeader, "application/json");
                }

                if (!asyncResult.Request.HttpMethod.Equals("GET", StringComparison.OrdinalIgnoreCase))
                {
                    if (asyncResult.Request.Content != null && asyncResult.Request.Content.Length > 0)
                    {
                        requestData.Data = asyncResult.Request.Content;
                    }
                    else if (asyncResult.Request.ContentStream != null && asyncResult.Request.ContentStream.Length > 0)
                    {
                        using (asyncResult.Request.ContentStream)
                        {
                            requestData.Data = StreamToByteArray.Convert(asyncResult.Request.ContentStream, this.Config.BufferSize);

                            StreamTransferProgressArgs args = new StreamTransferProgressArgs(asyncResult.Request.ContentStream.Length, asyncResult.Request.ContentStream.Length, asyncResult.Request.ContentStream.Length);
                            if (asyncResult.Request.OriginalRequest.StreamUploadProgressCallback != null)
                            {
                                asyncResult.Request.OriginalRequest.StreamUploadProgressCallback(this, args);
                            }

                            if (args.PercentDone >= 100)
                            {
                                asyncResult.Request.OriginalRequest.StreamUploadProgressCallback = null;
                            }
                        }
                    }
                    else if (asyncResult.Request.Parameters != null && asyncResult.Request.Parameters.Count > 0)
                    {
                        requestData.Data = GetRequestData(asyncResult.Request);
                    }
                }

                asyncResult.RequestData = requestData;

                // setting up callback for response handling
                asyncResult.WaitCallback = this.ProcessHttpResponse;

                // switching to main thread to make the network call
                AmazonMainThreadDispatcher.QueueAWSRequest(asyncResult);
            }
            catch (Exception e)
            {
                AmazonLogging.LogException(AmazonLogging.AmazonLoggingLevel.Errors, asyncResult.Request.ServiceName, e);

                asyncResult.IsCompleted = true;
                asyncResult.HandleException(e);
                return;
            }
        }
        private void ProcessS3PostRequest(AsyncResult asyncResult, PostObjectRequest request)
        {
            try
            {
                WWWRequestData requestData = new WWWRequestData();
                string         subdomain   = request.Region.Equals(RegionEndpoint.USEast1) ? "s3" : "s3-" + request.Region.SystemName;

                if (request.Bucket.IndexOf('.') > -1)
                {
                    requestData.Url = string.Format(CultureInfo.InvariantCulture, "http://{0}.amazonaws.com/{1}/", subdomain, request.Bucket);
                }
                else
                {
                    requestData.Url = string.Format(CultureInfo.InvariantCulture, "http://{0}.{1}.amazonaws.com", request.Bucket, subdomain);
                }


                // prepare WWW
                var boundary = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Replace('=', 'z');
                requestData.Headers.Add(HeaderKeys.ContentTypeHeader, string.Format(CultureInfo.InvariantCulture, "multipart/form-data; boundary={0}", boundary));
#if !UNITY_WEBPLAYER
                requestData.Headers.Add(HeaderKeys.UserAgentHeader, UNITY_USER_AGENT);
#endif

                // append upload data

                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);
                    AmazonLogging.Log(AmazonLogging.AmazonLoggingLevel.Verbose, "S3", requestData.Url);

                    requestData.Data = reqStream.ToArray();
                }
                AmazonLogging.Log(AmazonLogging.AmazonLoggingLevel.Verbose, "S3", Encoding.Default.GetString(requestData.Data));

                asyncResult.RequestData  = requestData;
                asyncResult.WaitCallback = ProcessS3PostResponse;

                // switching to main thread
                AmazonMainThreadDispatcher.QueueAWSRequest(asyncResult);
            }
            catch (Exception e)
            {
                AmazonLogging.LogError(AmazonLogging.AmazonLoggingLevel.Errors, "S3", e.Message);
                asyncResult.IsCompleted = true;
                asyncResult.HandleException(e);
                return;
            }
        }