示例#1
0
        private Task <TResp> SendRequest <TReq, TResp>(TReq request, CancellationToken token) where TResp : IResponse, new() where TReq : IRequest
        {
            request.Timestamp = DateTimeOffset.UtcNow;
            request.RequestId = Guid.NewGuid();

            _logger.LogTrace("Handling {RequestType} with request id {RequestId}", typeof(TReq).Name, request.RequestId);

            S3Config config        = _options.Value;
            Stream?  requestStream = _marshaller.MarshalRequest(request, config);

            _validator.ValidateAndThrow(request);

            StringBuilder sb = StringBuilderPool.Shared.Rent(200);

            RequestHelper.AppendScheme(sb, config);
            int schemeLength = sb.Length;

            RequestHelper.AppendHost(sb, config, request);

            request.SetHeader(HttpHeaders.Host, sb.ToString(schemeLength, sb.Length - schemeLength));
            request.SetHeader(AmzHeaders.XAmzDate, request.Timestamp, DateTimeFormat.Iso8601DateTime);

            if (requestStream != null)
            {
                foreach (IRequestStreamWrapper wrapper in _requestStreamWrappers)
                {
                    if (wrapper.IsSupported(request))
                    {
                        requestStream = wrapper.Wrap(requestStream, request);
                    }
                }
            }

            if (!request.Headers.TryGetValue(AmzHeaders.XAmzContentSha256, out string contentHash))
            {
                if (config.PayloadSignatureMode == SignatureMode.Unsigned)
                {
                    contentHash = "UNSIGNED-PAYLOAD";
                }
                else
                {
                    contentHash = requestStream == null ? "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" : CryptoHelper.Sha256Hash(requestStream, true).HexEncode();
                }

                request.SetHeader(AmzHeaders.XAmzContentSha256, contentHash);
            }

            _logger.LogDebug("ContentSha256 is {ContentSha256}", contentHash);

            //We add the authorization header here because we need ALL other headers to be present when we do
            _authBuilder.BuildAuthorization(request);

            RequestHelper.AppendUrl(sb, config, request);
            RequestHelper.AppendQueryParameters(sb, request);
            string url = sb.ToString();

            StringBuilderPool.Shared.Return(sb);

            return(HandleResponse <TReq, TResp>(request, url, requestStream, token));
        }
示例#2
0
        public void Setup()
        {
            {
                S3Config config = new S3Config();
                config.Region      = AwsRegion.EuWest1;
                config.Credentials = new StringAccessKey("keyidkeyidkeyidkeyid", "accesskeyacceskey123accesskeyacceskey123");

                IOptions <S3Config> options = Options.Create(config);

                SigningKeyBuilder signingKeyBuilder = new SigningKeyBuilder(options, NullLogger <SigningKeyBuilder> .Instance);
                ScopeBuilder      scopeBuilder      = new ScopeBuilder(options);
                SignatureBuilder  signatureBuilder  = new SignatureBuilder(signingKeyBuilder, scopeBuilder, NullLogger <SignatureBuilder> .Instance, options);

                _builder = new HeaderAuthorizationBuilder(options, scopeBuilder, signatureBuilder, NullLogger <HeaderAuthorizationBuilder> .Instance);

                _request = new DummyRequest();
                _request.SetHeader(AmzHeaders.XAmzContentSha256, "UNSIGNED-PAYLOAD");
            }

            {
                _request2    = new HttpRequestMessage(System.Net.Http.HttpMethod.Get, "https://dummyurl");
                _credentials = new ImmutableCredentials("keyidkeyidkeyidkeyid", "accesskeyacceskey123accesskeyacceskey123", null);

                // Add required headers
                _request2.AddHeader(HeaderKeys.XAmzDateHeader, DateTime.UtcNow.ToIso8601BasicDateTime());

                // Add conditional headers
                _request2.AddHeaderIf(_credentials.UseToken, HeaderKeys.XAmzSecurityTokenHeader, _credentials.Token);
                _request2.AddHeaderIf(!_request2.Headers.Contains(HeaderKeys.HostHeader), HeaderKeys.HostHeader, _request2.RequestUri.Host);
            }
        }
示例#3
0
        public static void AppendHost <TReq>(StringBuilder sb, S3Config config, TReq request) where TReq : IRequest
        {
            string?bucketName = null;

            if (request is IHasBucketName bn)
            {
                bucketName = bn.BucketName;
            }

            Uri?endpoint = config.Endpoint;

            if (endpoint != null)
            {
                sb.Append(endpoint.Host);

                if (!endpoint.IsDefaultPort)
                {
                    sb.Append(':').Append(endpoint.Port);
                }
            }
            else if (bucketName != null && config.NamingMode == NamingMode.VirtualHost)
            {
                sb.Append(bucketName).Append(".s3.").Append(ValueHelper.EnumToString(config.Region)).Append(".amazonaws.com");
            }
            else
            {
                sb.Append("s3.").Append(ValueHelper.EnumToString(config.Region)).Append(".amazonaws.com");
            }
        }
示例#4
0
        internal RootConfig()
        {
            Logging  = new LoggingConfig();
            DynamoDB = new DynamoDBConfig();
            S3       = new S3Config();
            EC2      = new EC2Config();
            Proxy    = new ProxyConfig();

            EndpointDefinition = AWSConfigs._endpointDefinition;
            Region             = AWSConfigs._awsRegion;
            ProfileName        = AWSConfigs._awsProfileName;
            ProfilesLocation   = AWSConfigs._awsAccountsLocation;

        #if !WIN_RT && !WINDOWS_PHONE
            //var root = AWSConfigs.GetSection<AWSSection>(_rootAwsSectionName);

//	            Logging.Configure(root.Logging);
//	            DynamoDB.Configure(root.DynamoDB);
//	            S3.Configure(root.S3);
//	            EC2.Configure(root.EC2);
//	            Proxy.Configure(root.Proxy);
//
//	            EndpointDefinition = Choose(EndpointDefinition, root.EndpointDefinition);
//	            Region = Choose(Region, root.Region);
//	            ProfileName = Choose(ProfileName, root.ProfileName);
//	            ProfilesLocation = Choose(ProfilesLocation, root.ProfilesLocation);
        #endif
        }
示例#5
0
        public S3Client(S3Config config, HttpMessageHandler messageHandler)
        {
            ServiceCollection services = new ServiceCollection();

            services.AddSingleton(x => Options.Create(config));

            IS3ClientBuilder   builder     = services.AddSimpleS3Core();
            IHttpClientBuilder httpBuilder = builder.UseHttpClientFactory();

            if (messageHandler != null)
            {
                httpBuilder.ConfigurePrimaryHttpMessageHandler(x => messageHandler);
            }

            httpBuilder.SetHandlerLifetime(TimeSpan.FromMinutes(5));

            Random random = new Random();

            // Policy is:
            // Retries: 3
            // Timeout: 2^attempt seconds (2, 4, 8 seconds) + -100 to 100 ms jitter
            httpBuilder.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3,
                                                                             retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
                                                                             + TimeSpan.FromMilliseconds(random.Next(-100, 100))));

            _provider      = services.BuildServiceProvider();
            _objectClient  = _provider.GetRequiredService <IS3ObjectClient>();
            _bucketClient  = _provider.GetRequiredService <IS3BucketClient>();
            _serviceClient = _provider.GetRequiredService <IS3ServiceClient>();
        }
        public ActionResult Index()
        {
            var config = new S3Config
            {
                // Unique Policy ID and duration
                Uuid           = Guid.NewGuid(),
                ExpirationTime = TimeSpan.FromHours(1),

                // Authentication
                AccessKey       = "YOUR_ACCESS_KEY",
                SecretAccessKey = "YOUR_SECRET_KEY",

                // Bucket name and key prefix (folder)
                Bucket    = "YOUR_BUCKET",
                BucketUrl = "http://YOUR_BUCKET.s3.amazonaws.com/",
                KeyPrefix = "YOUR_UPLOAD_ROOT/",

                // See http://docs.aws.amazon.com/AmazonS3/latest/dev/ACLOverview.html#CannedACL
                Acl = "private",

                // Mime type prefix
                ContentTypePrefix = "image/",

                // Fully qualified URL of an "empty document" in the same origin
                // Required for IE < 10
                SuccessUrl = "http://localhost:62629/home/success"
            };

            ViewBag.Policy          = Policy(config);
            ViewBag.PolicySignature = Sign(ViewBag.Policy, config.SecretAccessKey);
            ViewBag.S3Config        = config;

            return(View());
        }
 public PatreonOauthTokenProvider(IOptions <PatreonConfig> config, S3ClientProvider <S3Config> s3ClientProvider,
                                  S3Config s3Config,
                                  ILogger <PatreonOauthTokenProvider> logger)
 {
     _s3Client = s3ClientProvider.S3Client;
     _s3Config = s3Config;
     _logger   = logger;
     _config   = config.Value;
 }
示例#8
0
        public string SignRequest <TReq>(TReq request, TimeSpan expiresIn) where TReq : IRequest
        {
            request.Timestamp = DateTimeOffset.UtcNow;
            request.RequestId = Guid.NewGuid();

            _logger.LogTrace("Handling {RequestType} with request id {RequestId}", typeof(TReq).Name, request.RequestId);

            S3Config config = _options.Value;

            _marshaller.MarshalRequest(request, config);

            _validator.ValidateAndThrow(request);

            StringBuilder sb = StringBuilderPool.Shared.Rent(200);

            RequestHelper.AppendScheme(sb, config);
            int schemeLength = sb.Length;

            RequestHelper.AppendHost(sb, config, request);

            request.SetHeader(HttpHeaders.Host, sb.ToString(schemeLength, sb.Length - schemeLength));

            string scope = _scopeBuilder.CreateScope("s3", request.Timestamp);

            request.SetQueryParameter(AmzParameters.XAmzAlgorithm, SigningConstants.AlgorithmTag);
            request.SetQueryParameter(AmzParameters.XAmzCredential, _options.Value.Credentials.KeyId + '/' + scope);
            request.SetQueryParameter(AmzParameters.XAmzDate, request.Timestamp.ToString(DateTimeFormats.Iso8601DateTime, DateTimeFormatInfo.InvariantInfo));
            request.SetQueryParameter(AmzParameters.XAmzExpires, expiresIn.TotalSeconds.ToString(NumberFormatInfo.InvariantInfo));
            request.SetQueryParameter(AmzParameters.XAmzSignedHeaders, string.Join(";", SigningConstants.FilterHeaders(request.Headers).Select(x => x.Key)));

            //Copy all headers to query parameters
            foreach (KeyValuePair <string, string> header in request.Headers)
            {
                if (header.Key == HttpHeaders.Host)
                {
                    continue;
                }

                request.SetQueryParameter(header.Key, header.Value);
            }

            _authBuilder.BuildAuthorization(request);

            //Clear sensitive material from the request
            if (request is IContainSensitiveMaterial sensitive)
            {
                sensitive.ClearSensitiveMaterial();
            }

            RequestHelper.AppendUrl(sb, config, request);
            RequestHelper.AppendQueryParameters(sb, request);

            string url = sb.ToString();

            StringBuilderPool.Shared.Return(sb);
            return(url);
        }
示例#9
0
        public static (FakeHttpHandler handler, S3Client client) CreateFakeClient()
        {
            S3Config config = new S3Config(new StringAccessKey("ExampleKeyId00000000", "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"), AwsRegion.USEast1);

            FakeHttpHandler fakeHandler = new FakeHttpHandler();

            S3Client client = new S3Client(config, fakeHandler);

            return(fakeHandler, client);
        }
示例#10
0
        public static (FakeNetworkDriver driver, S3Client client) CreateFakeClient()
        {
            S3Config config = new S3Config(new StringAccessKey("ExampleKeyId00000000", "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"), AwsRegion.UsEast1);

            FakeNetworkDriver fakeNetworkDriver = new FakeNetworkDriver();

            S3Client client = new S3Client(Options.Create(config), fakeNetworkDriver, NullLoggerFactory.Instance);

            return(fakeNetworkDriver, client);
        }
        public CanonicalRequestFileTests()
        {
            S3Config config = new S3Config(new StringAccessKey("KeyIdExampleExampleE", "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"), AwsRegion.UsEast1);

            IOptions <S3Config> options = Options.Create(config);

            ISigningKeyBuilder keyBuilder = new SigningKeyBuilder(options, NullLogger <SigningKeyBuilder> .Instance);

            _scopeBuilder = new ScopeBuilder(options);
            _sigBuilder   = new SignatureBuilder(keyBuilder, _scopeBuilder, NullLogger <SignatureBuilder> .Instance, options);
        }
示例#12
0
        public PreSignedUrlTests()
        {
            //See https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
            S3Config config = new S3Config(new StringAccessKey("AKIAIOSFODNN7EXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"), AwsRegion.UsEast1);

            _options = Options.Create(config);

            SigningKeyBuilder keyBuilder = new SigningKeyBuilder(_options, NullLogger <SigningKeyBuilder> .Instance);

            _scopeBuilder = new ScopeBuilder(_options);
            _sigBuilder   = new SignatureBuilder(keyBuilder, _scopeBuilder, NullLogger <SignatureBuilder> .Instance, _options);
        }
        public CanonicalRequestFileTests()
        {
            S3Config config = new S3Config(new StringAccessKey("AKIDEXAMPLE", "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"), AwsRegion.USEast1);

            IOptions <S3Config> options = Options.Create(config);

            S3ConfigNullCredentialProvider nullCredsProvider = new S3ConfigNullCredentialProvider(options);
            ISigningKeyBuilder             keyBuilder        = new SigningKeyBuilder(options, nullCredsProvider, new NullLogger <SigningKeyBuilder>());

            _scopeBuilder = new ScopeBuilder(options);
            _sigBuilder   = new SignatureBuilder(keyBuilder, _scopeBuilder, new NullLogger <SignatureBuilder>());
        }
示例#14
0
        public static S3Client Create()
        {
            //Public minio playground credentials
            StringAccessKey key = new StringAccessKey("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG");

            //Minio expect the region to always be USEast1
            S3Config config = new S3Config(key, AwsRegion.UsEast1);

            //We have to set the endpoint to point to the Minio Playground server
            config.Endpoint = new Uri("https://play.min.io:9000/");

            return(new S3Client(config));
        }
示例#15
0
        public static void AppendScheme(StringBuilder sb, S3Config config)
        {
            if (config.Endpoint == null)
            {
                sb.Append(config.UseTLS ? "https" : "http");
            }
            else
            {
                sb.Append(config.Endpoint.Scheme);
            }

            sb.Append("://");
        }
        public ChunkedSignatureTests()
        {
            S3Config config = new S3Config(new StringAccessKey("AKIAIOSFODNN7EXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"), AwsRegion.UsEast1);

            _options = Options.Create(config);

            SigningKeyBuilder keyBuilder = new SigningKeyBuilder(_options, NullLogger <SigningKeyBuilder> .Instance);

            _scopeBuilder      = new ScopeBuilder(_options);
            _sigBuilder        = new SignatureBuilder(keyBuilder, _scopeBuilder, NullLogger <SignatureBuilder> .Instance, _options);
            _chunkedSigBuilder = new ChunkedSignatureBuilder(keyBuilder, _scopeBuilder, NullLogger <ChunkedSignatureBuilder> .Instance);
            _authHeaderBuilder = new AuthorizationHeaderBuilder(_options, _scopeBuilder, _sigBuilder, NullLogger <AuthorizationHeaderBuilder> .Instance);
        }
        public IActionResult S3Signature()
        {
            S3Config config = new S3Config
            {
                Bucket    = Environment.GetEnvironmentVariable("AWS_BUCKET"),
                Region    = Environment.GetEnvironmentVariable("AWS_REGION"),
                KeyStart  = Environment.GetEnvironmentVariable("AWS_KEY_START"),
                Acl       = Environment.GetEnvironmentVariable("AWS_ACL"),
                AccessKey = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY"),
                SecretKey = Environment.GetEnvironmentVariable("AWS_SECRET_KEY")
            };

            return(Json(FroalaEditor.S3.GetHash(config)));
        }
示例#18
0
        public static string BuildFullUrl <TReq>(S3Config config, TReq request) where TReq : IRequest
        {
            StringBuilder sb = StringBuilderPool.Shared.Rent(200);

            AppendScheme(sb, config);
            AppendHost(sb, config, request);
            AppendUrl(sb, config, request);
            AppendQueryParameters(sb, request);

            string url = sb.ToString();

            StringBuilderPool.Shared.Return(sb);
            return(url);
        }
示例#19
0
        public static void AppendUrl <TReq>(StringBuilder sb, S3Config config, TReq request) where TReq : IRequest
        {
            sb.Append('/');

            if (config.NamingMode == NamingMode.PathStyle && request is IHasBucketName bn)
            {
                sb.Append(bn.BucketName).Append('/');
            }

            if (request is IHasObjectKey ok)
            {
                sb.Append(UrlHelper.UrlPathEncode(ok.ObjectKey));
            }
        }
        public ChunkedSignatureTests()
        {
            S3Config config = new S3Config(new StringAccessKey("AKIAIOSFODNN7EXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"), AwsRegion.UsEast1);

            //The tests here have signatures built using path style
            config.NamingMode = NamingMode.PathStyle;

            _options = Options.Create(config);

            SigningKeyBuilder keyBuilder = new SigningKeyBuilder(_options, NullLogger <SigningKeyBuilder> .Instance);

            _scopeBuilder      = new ScopeBuilder(_options);
            _sigBuilder        = new SignatureBuilder(keyBuilder, _scopeBuilder, NullLogger <SignatureBuilder> .Instance, _options);
            _chunkedSigBuilder = new ChunkedSignatureBuilder(keyBuilder, _scopeBuilder, NullLogger <ChunkedSignatureBuilder> .Instance);
            _authBuilder       = new HeaderAuthorizationBuilder(_options, _scopeBuilder, _sigBuilder, NullLogger <HeaderAuthorizationBuilder> .Instance);
        }
        private string Policy(S3Config config)
        {
            var policyJson = JsonConvert.SerializeObject(new
            {
                expiration = DateTime.UtcNow.Add(config.ExpirationTime).ToString("yyyy-MM-ddTHH:mm:ssZ"),
                conditions = new object[] {
                    new { bucket = config.Bucket },
                    new [] { "starts-with", "$key", config.KeyPrefix },
                    new { acl = config.Acl },
                    new [] { "starts-with", "$success_action_redirect", "" },
                    new [] { "starts-with", "$Content-Type", config.ContentTypePrefix },
                    new Dictionary <string, string> {
                        { "x-amz-meta-uuid", config.Uuid.ToString() }
                    }
                }
            });

            return(Convert.ToBase64String(Encoding.UTF8.GetBytes(policyJson)));
        }
示例#22
0
        private void ConfigureS3(S3Config config)
        {
            //Set the configuration from the config file
            _configRoot.Bind(config);

            StringAccessKey secret = new StringAccessKey(_configRoot[nameof(StringAccessKey.KeyId)], _configRoot[nameof(StringAccessKey.AccessKey)]);

            if (string.IsNullOrWhiteSpace(secret.KeyId))
            {
                throw new Exception("Did you forget to set a KeyId? See Readme.txt on how to run live tests");
            }

            if (secret.AccessKey == null)
            {
                throw new Exception("Did you forget to set a secret key? See Readme.txt on how to run live tests");
            }

            config.Credentials = secret;
        }
示例#23
0
        public SignatureBenchmarks()
        {
            S3Config config = new S3Config(new StringAccessKey("AKIAIOSFODNN7EXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"), AwsRegion.UsEast1);

            config.PayloadSignatureMode = SignatureMode.FullSignature;

            IOptions <S3Config> options = Options.Create(config);

            _signingKeyBuilder = new SigningKeyBuilder(options, NullLogger <SigningKeyBuilder> .Instance);
            IScopeBuilder scopeBuilder = new ScopeBuilder(options);

            _signatureBuilder = new SignatureBuilder(_signingKeyBuilder, scopeBuilder, NullLogger <SignatureBuilder> .Instance, options);
            _chunkSigBuilder  = new ChunkedSignatureBuilder(_signingKeyBuilder, scopeBuilder, NullLogger <ChunkedSignatureBuilder> .Instance);

            byte[] data = Encoding.UTF8.GetBytes("Hello world");

            _req = new PutObjectRequest("examplebucket", "benchmark", new MemoryStream(data));
            _req.SetHeader(AmzHeaders.XAmzContentSha256, CryptoHelper.Sha256Hash(data).HexEncode());

            _date = DateTimeOffset.UtcNow;
        }
示例#24
0
 /// <summary>Creates a new instance of <see cref="S3Client" /></summary>
 /// <param name="config">The configuration you want to use</param>
 /// <param name="proxy">A web proxy (optional)</param>
 public S3Client(S3Config config, WebProxy proxy = null) : this(config, new HttpClientHandler {
     Proxy = proxy
 })
 {
 }
 protected override void ConfigureConfig(S3Config config)
 {
     //We force streaming signatures as it is the only one that supports non-seekable streams
     config.StreamingChunkSize   = 8096;
     config.PayloadSignatureMode = SignatureMode.StreamingSignature;
 }
 public HomeController(IConfiguration configuration)
 {
     config   = configuration;
     s3config = config.GetSection("S3Config").Get <S3Config>();
 }
        public async Task <TResp> SendRequestAsync <TReq, TResp>(TReq request, CancellationToken cancellationToken = default) where TResp : IResponse, new() where TReq : IRequest
        {
            cancellationToken.ThrowIfCancellationRequested();

            request.Timestamp = DateTimeOffset.UtcNow;
            request.RequestId = Guid.NewGuid();

            _logger.LogTrace("Sending {RequestType} with request id {RequestId}", typeof(TReq).Name, request.RequestId);

            S3Config config = _options.Value;

            Stream requestStream = _marshaller.MarshalRequest(request, config);

            _validator.ValidateAndThrow(request);

            string bucketName = null;

            if (request is IHasBucketName bn)
            {
                bucketName = bn.BucketName;
            }

            string objectKey = null;

            if (request is IHasObjectKey ok)
            {
                objectKey = ok.ObjectKey;
            }

            //Ensure that the object key is encoded
            string encodedResource = objectKey != null?UrlHelper.UrlPathEncode(objectKey) : null;

            if (config.Endpoint == null || config.NamingMode == NamingMode.PathStyle)
            {
                if (bucketName != null)
                {
                    objectKey = bucketName + '/' + encodedResource;
                }
                else
                {
                    objectKey = encodedResource;
                }
            }
            else
            {
                objectKey = encodedResource;
            }

            StringBuilder sb = StringBuilderPool.Shared.Rent(100);

            Uri endpoint = config.Endpoint;

            if (endpoint != null)
            {
                sb.Append(endpoint.Host);

                if (!endpoint.IsDefaultPort)
                {
                    sb.Append(':').Append(endpoint.Port);
                }
            }
            else
            {
                if (config.NamingMode == NamingMode.VirtualHost)
                {
                    if (bucketName != null)
                    {
                        sb.Append(bucketName).Append(".s3.").Append(ValueHelper.EnumToString(config.Region)).Append(".amazonaws.com");
                    }
                    else
                    {
                        sb.Append("s3.").Append(ValueHelper.EnumToString(config.Region)).Append(".amazonaws.com");
                    }
                }
                else
                {
                    sb.Append("s3.").Append(ValueHelper.EnumToString(config.Region)).Append(".amazonaws.com");
                }
            }

            request.SetHeader(HttpHeaders.Host, sb.ToString());
            request.SetHeader(AmzHeaders.XAmzDate, request.Timestamp, DateTimeFormat.Iso8601DateTime);

            if (requestStream != null)
            {
                foreach (IRequestStreamWrapper wrapper in _requestStreamWrappers)
                {
                    if (wrapper.IsSupported(request))
                    {
                        requestStream = wrapper.Wrap(requestStream, request);
                    }
                }
            }

            if (!request.Headers.TryGetValue(AmzHeaders.XAmzContentSha256, out string contentHash))
            {
                if (config.PayloadSignatureMode == SignatureMode.Unsigned)
                {
                    contentHash = "UNSIGNED-PAYLOAD";
                }
                else
                {
                    contentHash = requestStream == null ? "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" : CryptoHelper.Sha256Hash(requestStream, true).HexEncode();
                }

                request.SetHeader(AmzHeaders.XAmzContentSha256, contentHash);
            }

            _logger.LogDebug("ContentSha256 is {ContentSha256}", contentHash);

            //We add the authorization header here because we need ALL other headers to be present when we do
            request.SetHeader(HttpHeaders.Authorization, _authBuilder.BuildAuthorization(request));

            sb.Append('/').Append(objectKey);

            //Map all the parameters on to the url
            if (request.QueryParameters.Count > 0)
            {
                sb.Append('?').Append(UrlHelper.CreateQueryString(request.QueryParameters));
            }

            string scheme  = endpoint == null ? config.UseTLS ? "https" : "http" : endpoint.Scheme;
            string fullUrl = scheme + "://" + sb;

            StringBuilderPool.Shared.Return(sb);

            _logger.LogDebug("Building request for {Url}", fullUrl);

            (int statusCode, IDictionary <string, string> headers, Stream responseStream) = await _networkDriver.SendRequestAsync(request.Method, fullUrl, request.Headers, requestStream, cancellationToken).ConfigureAwait(false);

            //Clear sensitive material from the request
            if (request is IContainSensitiveMaterial sensitive)
            {
                sensitive.ClearSensitiveMaterial();
            }

            TResp response = new TResp();

            response.StatusCode       = statusCode;
            response.ContentLength    = headers.GetHeaderLong(HttpHeaders.ContentLength);
            response.ConnectionClosed = "closed".Equals(headers.GetHeader(HttpHeaders.Connection), StringComparison.OrdinalIgnoreCase);
            response.Date             = headers.GetHeaderDate(HttpHeaders.Date, DateTimeFormat.Rfc1123);
            response.Server           = headers.GetHeader(HttpHeaders.Server);
            response.ResponseId       = headers.GetHeader(AmzHeaders.XAmzId2);
            response.RequestId        = headers.GetHeader(AmzHeaders.XAmzRequestId);

            // https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
            response.IsSuccess = !(statusCode == 403 || //Forbidden
                                   statusCode == 400 || //BadRequest
                                   statusCode == 500 || //InternalServerError
                                   statusCode == 416 || //RequestedRangeNotSatisfiable
                                   statusCode == 405 || //MethodNotAllowed
                                   statusCode == 411 || //LengthRequired
                                   statusCode == 404 || //NotFound
                                   statusCode == 501 || //NotImplemented
                                   statusCode == 504 || //GatewayTimeout
                                   statusCode == 301 || //MovedPermanently
                                   statusCode == 412 || //PreconditionFailed
                                   statusCode == 307 || //TemporaryRedirect
                                   statusCode == 409 || //Conflict
                                   statusCode == 503);    //ServiceUnavailable

            //Only marshal successful responses
            if (response.IsSuccess)
            {
                _marshaller.MarshalResponse(config, request, response, headers, responseStream);
            }
            else
            {
                MemoryStream ms = new MemoryStream();
                responseStream.CopyTo(ms);

                if (ms.Length > 0)
                {
                    ms.Seek(0, SeekOrigin.Begin);

                    using (responseStream)
                        response.Error = ErrorHandler.Create(ms);

                    _logger.LogError("Received error: '{Message}'. Details: '{Details}'", response.Error.Message, response.Error.GetExtraData());
                }
            }

            return(response);
        }
示例#28
0
 /// <summary>Creates a new instance of <see cref="S3Client" /></summary>
 /// <param name="config">The configuration you want to use</param>
 /// <param name="proxy">A web proxy (optional)</param>
 public S3Client(S3Config config, IWebProxy?proxy = null) : this(Options.Create(config), proxy)
 {
 }
 public S3Repository(IAmazonS3 amazonS3Client, S3Config config)
 {
     _amazonS3Client = amazonS3Client;
     _config         = config;
 }
示例#30
0
 protected virtual void ConfigureConfig(S3Config config)
 {
 }