/// <summary> /// Set 'x-amz-content-sha256' http header. /// </summary> /// <param name="requestBuilder">Instantiated requestBuilder object</param> private void SetContentSha256(HttpRequestMessageBuilder requestBuilder) { if (this.isAnonymous) { return; } // No need to compute SHA256 if endpoint scheme is https if (isSecure) { requestBuilder.AddHeaderParameter("x-amz-content-sha256", "UNSIGNED-PAYLOAD"); return; } if (requestBuilder.Method == HttpMethod.Put || requestBuilder.Method.Equals(HttpMethod.Post)) { var body = requestBuilder.Content; if (body == null) { requestBuilder.AddHeaderParameter("x-amz-content-sha256", sha256EmptyFileHash); return; } var sha256 = SHA256.Create(); byte[] hash = sha256.ComputeHash(body); string hex = BitConverter.ToString(hash).Replace("-", string.Empty).ToLower(); requestBuilder.AddHeaderParameter("x-amz-content-sha256", hex); } else { requestBuilder.AddHeaderParameter("x-amz-content-sha256", sha256EmptyFileHash); } }
/// <summary> /// Set 'X-Amz-Security-Token' http header. /// </summary> /// <param name="requestBuilder">Instantiated requestBuilder object</param> /// <param name="sessionToken">session token</param> private void SetSessionTokenHeader(HttpRequestMessageBuilder requestBuilder, string sessionToken) { if (!string.IsNullOrEmpty(sessionToken)) { requestBuilder.AddHeaderParameter("X-Amz-Security-Token", sessionToken); } }
/// <summary> /// Set 'x-amz-content-sha256' http header. /// </summary> /// <param name="requestBuilder">Instantiated requestBuilder object</param> private void SetContentSha256(HttpRequestMessageBuilder requestBuilder) { if (this.isAnonymous) { return; } // No need to compute SHA256 if the endpoint scheme is https // or the command method is not a Post to delete multiple files var isMultiDeleteRequest = false; if (requestBuilder.Method == HttpMethod.Post) { isMultiDeleteRequest = requestBuilder.QueryParameters.Any(p => p.Key.Equals("delete", StringComparison.OrdinalIgnoreCase)); } if (isSecure || isMultiDeleteRequest) { requestBuilder.AddOrUpdateHeaderParameter("x-amz-content-sha256", "UNSIGNED-PAYLOAD"); return; } // For insecure, authenticated requests set sha256 header instead of MD5. if (requestBuilder.Method.Equals(HttpMethod.Put) || requestBuilder.Method.Equals(HttpMethod.Post)) { var body = requestBuilder.Content; if (body == null) { requestBuilder.AddOrUpdateHeaderParameter("x-amz-content-sha256", sha256EmptyFileHash); return; } var sha256 = SHA256.Create(); byte[] hash = sha256.ComputeHash(body); string hex = BitConverter.ToString(hash).Replace("-", string.Empty).ToLower(); requestBuilder.AddOrUpdateHeaderParameter("x-amz-content-sha256", hex); } else if (!isSecure && requestBuilder.Content != null) { var md5 = MD5.Create(); byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(requestBuilder.Content.ToString())); string base64 = Convert.ToBase64String(hash); requestBuilder.AddHeaderParameter("Content-Md5", base64); } else { requestBuilder.AddOrUpdateHeaderParameter("x-amz-content-sha256", sha256EmptyFileHash); } }
private async Task <ResponseResult> ExecuteTaskCoreAsync( IEnumerable <ApiResponseErrorHandlingDelegate> errorHandlers, HttpRequestMessageBuilder requestBuilder, CancellationToken cancellationToken = default(CancellationToken)) { var startTime = DateTime.Now; // Logs full url when HTTPtracing is enabled. if (this.trace) { var fullUrl = requestBuilder.RequestUri; Console.WriteLine($"Full URL of Request {fullUrl}"); } var v4Authenticator = new V4Authenticator(this.Secure, this.AccessKey, this.SecretKey, this.Region, this.SessionToken); requestBuilder.AddHeaderParameter("Authorization", v4Authenticator.Authenticate(requestBuilder)); var request = requestBuilder.Request; ResponseResult responseResult; try { if (requestTimeout > 0) { this.HttpClient.Timeout = new TimeSpan(0, 0, 0, 0, requestTimeout); } var response = await this.HttpClient .SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken) .ConfigureAwait(false); responseResult = new ResponseResult(request, response); } catch (OperationCanceledException) { throw; } catch (Exception e) { responseResult = new ResponseResult(request, e); } this.HandleIfErrorResponse(responseResult, errorHandlers, startTime); return(responseResult); }
/// <summary> /// Constructs a HttpRequestMessage builder. For AWS, this function has the side-effect of overriding the baseUrl /// in the HttpClient with region specific host path or virtual style path. /// </summary> /// <param name="method">HTTP method</param> /// <param name="bucketName">Bucket Name</param> /// <param name="objectName">Object Name</param> /// <param name="headerMap">headerMap</param> /// <param name="contentType">Content Type</param> /// <param name="body">request body</param> /// <param name="resourcePath">query string</param> /// <returns>A HttpRequestMessage builder</returns> internal async Task <HttpRequestMessageBuilder> CreateRequest( HttpMethod method, string bucketName = null, string objectName = null, Dictionary <string, string> headerMap = null, string contentType = "application/octet-stream", byte[] body = null, string resourcePath = null) { string region = string.Empty; if (bucketName != null) { utils.ValidateBucketName(bucketName); // Fetch correct region for bucket region = await GetRegion(bucketName).ConfigureAwait(false); } if (objectName != null) { utils.ValidateObjectName(objectName); } // This section reconstructs the url with scheme followed by location specific endpoint (s3.region.amazonaws.com) // or Virtual Host styled endpoint (bucketname.s3.region.amazonaws.com) for Amazon requests. string resource = string.Empty; bool usePathStyle = false; if (bucketName != null) { if (s3utils.IsAmazonEndPoint(this.BaseUrl)) { usePathStyle = false; if (method == HttpMethod.Put && objectName == null && resourcePath == null) { // use path style for make bucket to workaround "AuthorizationHeaderMalformed" error from s3.amazonaws.com usePathStyle = true; } else if (resourcePath != null && resourcePath.Contains("location")) { // use path style for location query usePathStyle = true; } else if (bucketName != null && bucketName.Contains(".") && this.Secure) { // use path style where '.' in bucketName causes SSL certificate validation error usePathStyle = true; } if (usePathStyle) { resource += utils.UrlEncode(bucketName) + "/"; } } else { resource += utils.UrlEncode(bucketName) + "/"; } } // Set Target URL Uri requestUrl = RequestUtil.MakeTargetURL(this.BaseUrl, this.Secure, bucketName, region, usePathStyle); if (objectName != null) { resource += utils.EncodePath(objectName); } // Append query string passed in if (resourcePath != null) { resource += resourcePath; } var messageBuilder = new HttpRequestMessageBuilder(method, requestUrl, resource); if (body != null) { messageBuilder.SetBody(body); } if (headerMap != null) { foreach (var entry in headerMap) { messageBuilder.AddHeaderParameter(entry.Key, entry.Value); } } return(messageBuilder); }
/// <summary> /// Set 'Host' http header. /// </summary> /// <param name="requestBuilder">Instantiated requestBuilder object</param> /// <param name="hostUrl">Host url</param> private void SetHostHeader(HttpRequestMessageBuilder requestBuilder, string hostUrl) { requestBuilder.AddHeaderParameter("Host", hostUrl); }
/// <summary> /// Sets 'x-amz-date' http header. /// </summary> /// <param name="requestBuilder">Instantiated requestBuilder object</param> /// <param name="signingDate">Date for signature to be signed</param> private void SetDateHeader(HttpRequestMessageBuilder requestBuilder, DateTime signingDate) { requestBuilder.AddHeaderParameter("x-amz-date", signingDate.ToString("yyyyMMddTHHmmssZ")); }