Exemple #1
0
        public void ChecksumAndOtherTrailingHeaders()
        {
            var contentStream   = new MemoryStream(Encoding.Default.GetBytes("Hello world"));
            var trailingHeaders = new Dictionary <string, string>
            {
                { "header-a", "value-a" },
                { "header-b", "value-b" },
                { "x-amz-checksum-sha256", "" }  // checksum will be calculated as the stream is read then replaced at the end
            };
            var headerSigningResult = new AWS4SigningResult(_accessKey, _fixedSigningTimestamp, "", "", _signingKey, _headerSignature);
            var wrappedStream       = new ChunkedUploadWrapperStream(contentStream, 8192, headerSigningResult, CoreChecksumAlgorithm.SHA256, trailingHeaders);

            var actualContent = new StreamReader(wrappedStream).ReadToEnd();

            var expectedContent =
                "B;chunk-signature=6a4d50a3307c001ad83900a73442136a0a0f203520fd8c0e966f655cc830bbe8\r\n" +
                "Hello world\r\n" +
                "0;chunk-signature=9384094dc67fd7c29a4c7e0aa3866233b3774e41d1470b8f51a96becbd91f60c\r\n" +
                "header-a:value-a\r\n" +
                "header-b:value-b\r\n" +
                "x-amz-checksum-sha256:ZOyIygCyaOW6GjVnihtTFtIS9PNmskdyMlNKiuyjfzw=\r\n" +
                "x-amz-trailer-signature:0e357651fe17d33ea0d4173b2fd745d596354a66347ee8b5e4de44036c62becb\r\n" +
                "\r\n";

            Assert.AreEqual(expectedContent.Length, wrappedStream.Length);
            Assert.AreEqual(expectedContent, actualContent);
        }
Exemple #2
0
        public void NonChecksumTrailingHeaders()
        {
            var contentStream   = new MemoryStream(Encoding.Default.GetBytes("Hello world"));
            var trailingHeaders = new Dictionary <string, string>
            {
                { "header-a", "value-a" },
                { "header-b", "value-b" }
            };
            var headerSigningResult = new AWS4SigningResult(_accessKey, _fixedSigningTimestamp, "", "", _signingKey, _headerSignature);
            var wrappedStream       = new ChunkedUploadWrapperStream(contentStream, 8192, headerSigningResult, CoreChecksumAlgorithm.NONE, trailingHeaders);

            var actualContent = new StreamReader(wrappedStream).ReadToEnd();

            var expectedContent =
                "B;chunk-signature=6a4d50a3307c001ad83900a73442136a0a0f203520fd8c0e966f655cc830bbe8\r\n" +
                "Hello world\r\n" +
                "0;chunk-signature=9384094dc67fd7c29a4c7e0aa3866233b3774e41d1470b8f51a96becbd91f60c\r\n" +
                "header-a:value-a\r\n" +
                "header-b:value-b\r\n" +
                "x-amz-trailer-signature:ff2899b910cb941057f921d11738b5d875f2e117ea9504cfea4f9c7a788a0852\r\n" +
                "\r\n";

            Assert.AreEqual(expectedContent.Length, wrappedStream.Length);
            Assert.AreEqual(expectedContent, actualContent);
        }
Exemple #3
0
        public void LargeData()
        {
            var data            = new string('a', 100000);
            var contentStream   = new MemoryStream(Encoding.Default.GetBytes(data));
            var trailingHeaders = new Dictionary <string, string>
            {
                { "x-amz-checksum-sha256", "" }  // checksum will be calculated as the stream is read then replaced at the end
            };
            var headerSigningResult = new AWS4SigningResult(_accessKey, _fixedSigningTimestamp, "", "", _signingKey, _headerSignature);
            var wrappedStream       = new ChunkedUploadWrapperStream(contentStream, 8192, headerSigningResult, CoreChecksumAlgorithm.SHA256, trailingHeaders);

            var actualContent = new StreamReader(wrappedStream).ReadToEnd();

            var expectedContent =
                "14000;chunk-signature=dd6818ebe851d9f6006431fac25c71960881bf8d86501344f19a43c1a2c2a9a7\r\n" +
                $"{new string('a', 81920)}\r\n" +
                "46A0;chunk-signature=88f059571f2bc312c8fd7ebd2082f587561ca83a6d5bb863e6e3d4ef78819256\r\n" +
                $"{new string('a', 18080)}\r\n" +
                "0;chunk-signature=07857eed4f1a53ae7d042e0c410053d610ed947827ca1c5572ed401666732805\r\n" +
                "x-amz-checksum-sha256:bRzyLXzAmwhd/CXuGh864CZYBMYHvCB0rSU7zIL9ge4=\r\n" +
                "x-amz-trailer-signature:cd8a0ba8bc4abaaa5f6e9921c30ca6e018110bcbaa3ea876e7b777b924bb4009\r\n" +
                "\r\n";

            Assert.AreEqual(expectedContent.Length, wrappedStream.Length);
            Assert.AreEqual(expectedContent, actualContent);
        }
Exemple #4
0
        internal string GetExpectedCanonicalRequestForChunkedTrailersSigningTest()
        {
            var trailingHeaders = new Dictionary <string, string>
            {
                { "x-amz-foo", "bar" }
            };

            return(string.Join('\n',
                               "PUT",
                               "/examplebucket/chunkObject.txt",
                               "",
                               "content-encoding:aws-chunked",
                               "content-length:" + ChunkedUploadWrapperStream.ComputeChunkedContentLength(Chunk1Size + Chunk2Size,
                                                                                                          ChunkedUploadWrapperStream.V4A_SIGNATURE_LENGTH,
                                                                                                          trailingHeaders,
                                                                                                          CoreChecksumAlgorithm.NONE).ToString(),
                               "host:s3.amazonaws.com",
                               "x-amz-content-sha256:STREAMING-AWS4-ECDSA-P256-SHA256-PAYLOAD-TRAILER",
                               "x-amz-date:20150830T123600Z",
                               "x-amz-decoded-content-length:" + (Chunk1Size + Chunk2Size).ToString(),
                               "x-amz-region-set:us-east-1",
                               "x-amz-storage-class:REDUCED_REDUNDANCY",
                               "x-amz-trailer:x-amz-foo",
                               "",
                               "content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-region-set;x-amz-storage-class;x-amz-trailer",
                               "STREAMING-AWS4-ECDSA-P256-SHA256-PAYLOAD-TRAILER"));
        }
Exemple #5
0
 private string BuildV4aChunkedStringToSignHelper(AWS4aSigningResult headerResult, string previousSignature, int chunkSize)
 {
     return(ChunkedUploadWrapperStream.BuildChunkedStringToSign(
                "AWS4-ECDSA-P256-SHA256-PAYLOAD",
                headerResult.ISO8601DateTime,
                headerResult.Scope,
                previousSignature.TrimEnd('*'),
                chunkSize,
                CreateChunkStream(chunkSize).ToArray()));
 }
Exemple #6
0
        public static string SetRequestBodyHash(IRequest request)
        {
            string value = null;
            bool   flag  = request.Headers.TryGetValue("X-Amz-Content-SHA256", out value);

            if (flag && !request.UseChunkEncoding)
            {
                return(value);
            }
            if (request.UseChunkEncoding)
            {
                value = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD";
                if (request.Headers.ContainsKey("Content-Length"))
                {
                    request.Headers["X-Amz-Decoded-Content-Length"] = request.Headers["Content-Length"];
                    long originalLength = long.Parse(request.Headers["Content-Length"], CultureInfo.InvariantCulture);
                    request.Headers["Content-Length"] = ChunkedUploadWrapperStream.ComputeChunkedContentLength(originalLength).ToString(CultureInfo.InvariantCulture);
                }
                if (request.Headers.ContainsKey("Content-Encoding"))
                {
                    string text = request.Headers["Content-Encoding"];
                    if (!text.Contains("aws-chunked"))
                    {
                        request.Headers["Content-Encoding"] = text + ", " + "aws-chunked";
                    }
                }
                else
                {
                    request.Headers["Content-Encoding"] = "aws-chunked";
                }
            }
            else if (request.ContentStream != null)
            {
                value = request.ComputeContentStreamHash();
            }
            else
            {
                byte[] requestPayloadBytes = GetRequestPayloadBytes(request);
                value = AWSSDKUtils.ToHex(CryptoUtilFactory.CryptoInstance.ComputeSHA256Hash(requestPayloadBytes), lowercase: true);
            }
            if (value != null)
            {
                if (flag)
                {
                    request.Headers["X-Amz-Content-SHA256"] = value;
                }
                else
                {
                    request.Headers.Add("X-Amz-Content-SHA256", value);
                }
            }
            return(value);
        }
Exemple #7
0
        /// <summary>
        /// If the caller has already set the x-amz-content-sha256 header with a pre-computed
        /// content hash, or it is present as ContentStreamHash on the request instance, return
        /// the value to be used in request canonicalization.
        /// If not set as a header or in the request, attempt to compute a hash based on
        /// inspection of the style of the request content.
        /// </summary>
        /// <param name="request"></param>
        /// <returns>
        /// The computed hash, whether already set in headers or computed here. Null
        /// if we were not able to compute a hash.
        /// </returns>
        public static string SetRequestBodyHash(IRequest request)
        {
            string computedContentHash = null;

            if (request.Headers.TryGetValue(XAmzContentSha256, out computedContentHash))
            {
                return(computedContentHash);
            }

            if (request.UseChunkEncoding)
            {
                computedContentHash = StreamingBodySha256;
                if (request.Headers.ContainsKey("Content-Length"))
                {
                    // substitute the originally declared content length with the true size of
                    // the data we'll upload, which is inflated with chunk metadata
                    request.Headers[XAmzDecodedContentLength] = request.Headers["Content-Length"];
                    var originalContentLength = long.Parse(request.Headers["Content-Length"], CultureInfo.InvariantCulture);
                    request.Headers["Content-Length"]
                        = ChunkedUploadWrapperStream.ComputeChunkedContentLength(originalContentLength).ToString(CultureInfo.InvariantCulture);
                }
                request.Headers["Content-Encoding"] = "aws-chunked";
            }
            else
            {
                if (request.ContentStream != null)
                {
                    computedContentHash = request.ComputeContentStreamHash();
                }
                else
                {
                    byte[] payloadHashBytes;
                    if (request.Content != null)
                    {
                        payloadHashBytes = CryptoUtilFactory.CryptoInstance.ComputeSHA256Hash(request.Content);
                    }
                    else
                    {
                        var payload = request.UseQueryString ? "" : GetRequestPayload(request);
                        payloadHashBytes = CryptoUtilFactory.CryptoInstance.ComputeSHA256Hash(Encoding.UTF8.GetBytes(payload));
                    }
                    computedContentHash = AWSSDKUtils.ToHex(payloadHashBytes, true);
                }
            }

            if (computedContentHash != null)
            {
                request.Headers.Add(XAmzContentSha256, computedContentHash);
            }

            return(computedContentHash);
        }
Exemple #8
0
        public void TestTrailingChecksum(string checksumKey, CoreChecksumAlgorithm algorithm, string expectedContent)
        {
            var contentStream   = new MemoryStream(Encoding.Default.GetBytes("Hello world"));
            var trailingHeaders = new Dictionary <string, string>
            {
                { checksumKey, "" }  // checksum will be calculated as the stream is read then replaced at the end
            };

            var headerSigningResult = new AWS4SigningResult(_accessKey, _fixedSigningTimestamp, "", "", _signingKey, _headerSignature);
            var wrappedStream       = new ChunkedUploadWrapperStream(contentStream, 8192, headerSigningResult, algorithm, trailingHeaders);

            var actualContent = new StreamReader(wrappedStream).ReadToEnd();

            Assert.AreEqual(expectedContent.Length, wrappedStream.Length);
            Assert.AreEqual(expectedContent, actualContent);
        }
Exemple #9
0
 internal string GetExpectedCanonicalRequestForChunkedSigningTest()
 {
     return(String.Join('\n',
                        "PUT",
                        "/examplebucket/chunkObject.txt",
                        "",
                        "content-encoding:aws-chunked",
                        "content-length:" + ChunkedUploadWrapperStream.ComputeChunkedContentLength(Chunk1Size + Chunk2Size, ChunkedUploadWrapperStream.V4A_SIGNATURE_LENGTH).ToString(),
                        "host:s3.amazonaws.com",
                        "x-amz-content-sha256:STREAMING-AWS4-ECDSA-P256-SHA256-PAYLOAD",
                        "x-amz-date:20150830T123600Z",
                        "x-amz-decoded-content-length:" + (Chunk1Size + Chunk2Size).ToString(),
                        "x-amz-region-set:us-east-1",
                        "x-amz-storage-class:REDUCED_REDUNDANCY",
                        "",
                        "content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-region-set;x-amz-storage-class",
                        "STREAMING-AWS4-ECDSA-P256-SHA256-PAYLOAD"));
 }
Exemple #10
0
        public void SmallBuffer()
        {
            var contentStream   = new MemoryStream(Encoding.Default.GetBytes("Hello world"));
            var trailingHeaders = new Dictionary <string, string>
            {
                { "x-amz-checksum-sha256", "" }  // checksum will be calculated as the stream is read then replaced at the end
            };
            var headerSigningResult = new AWS4SigningResult(_accessKey, _fixedSigningTimestamp, "", "", _signingKey, _headerSignature);
            var wrappedStream       = new ChunkedUploadWrapperStream(contentStream, 1, headerSigningResult, CoreChecksumAlgorithm.SHA256, trailingHeaders);

            var bytesRead      = -1;
            var bufferSize     = 1;
            var buffer         = new byte[bufferSize];
            var outputAsString = "";

            while (bytesRead != 0)
            {
                bytesRead       = wrappedStream.Read(buffer, 0, bufferSize);
                outputAsString += Encoding.Default.GetString(buffer, 0, bytesRead);
            }

            Assert.AreEqual(expectedSHA256Content.Length, wrappedStream.Length);
            Assert.AreEqual(expectedSHA256Content, outputAsString);
        }
        void SetContent(HttpRequestMessage requestMessage, IRequestData state)
        {
            var request = state.Request;

            if (requestMessage.Method == HttpMethod.Get ||
                requestMessage.Method == HttpMethod.Delete ||
                requestMessage.Method == HttpMethod.Head)
            {
                return;
            }

            byte[] requestData;
            if (request.UseQueryString)
            {
                requestMessage.Content = new ByteArrayContent(new Byte[0]);
            }
            else if (request.ContentStream != null)
            {
                var eventStream = new EventStream(request.ContentStream, true);
                var tracker     = new StreamReadTracker(this, request.OriginalRequest.StreamUploadProgressCallback,
                                                        request.ContentStream.Length, this.Config.ProgressUpdateInterval);
                eventStream.OnRead += tracker.ReadProgress;

                Stream        finalStream;
                StreamContent content;
                if (state.Request.UseChunkEncoding && state.Request.AWS4SignerResult != null)
                {
                    finalStream = new ChunkedUploadWrapperStream(eventStream, Config.BufferSize, state.Request.AWS4SignerResult);
                }
                else
                {
                    finalStream = eventStream;
                }

                content = new StreamContent(finalStream, this.Config.BufferSize);
                requestMessage.Content = content;
                requestMessage.Content.Headers.ContentLength = finalStream.Length;
            }
            else if ((requestData = GetRequestData(request)) != null)
            {
                state.Metrics.AddProperty(Metric.RequestSize, requestData.Length);
                requestMessage.Content = new ByteArrayContent(requestData);
            }
            else
            {
                requestMessage.Content = new ByteArrayContent(new Byte[0]);
            }

            requestMessage.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(request.Headers["Content-Type"]);

            if (requestMessage.Content != null)
            {
                if (request.Headers.ContainsKey("Content-Range"))
                {
                    requestMessage.Content.Headers.Add("Content-Range", request.Headers["Content-Range"]);
                }

                if (request.Headers.ContainsKey("Content-MD5"))
                {
                    requestMessage.Content.Headers.TryAddWithoutValidation("Content-MD5", request.Headers["Content-MD5"]);
                }

                if (request.Headers.ContainsKey("Content-Encoding"))
                {
                    requestMessage.Content.Headers.TryAddWithoutValidation("Content-Encoding", request.Headers["Content-Encoding"]);
                }

                if (request.Headers.ContainsKey("Content-Disposition"))
                {
                    requestMessage.Content.Headers.TryAddWithoutValidation("Content-Disposition", request.Headers["Content-Disposition"]);
                }

                DateTime expires;
                if (request.Headers.ContainsKey("Expires") &&
                    DateTime.TryParse(request.Headers["Expires"], CultureInfo.InvariantCulture, DateTimeStyles.None, out expires))
                {
                    requestMessage.Content.Headers.Expires = expires;
                }
            }
        }