Exemple #1
0
        /// <summary>
        /// Calculates the length in bytes of a TrailingChecksumWrapperStream initialized
        /// with the given trailing headers and optional checksum
        /// </summary>
        /// <param name="trailingHeaders">Dictionary of trailing headers</param>
        /// <param name="checksumAlgorithm">Trailing checksum</param>
        /// <param name="baseStreamLength">Length of the base stream in bytes</param>
        /// <returns>Length of a TrailingChecksumWrapperStream with given parameters, in bytes</returns>
        public static long CalculateLength(IDictionary <string, string> trailingHeaders, CoreChecksumAlgorithm checksumAlgorithm, long baseStreamLength)
        {
            var prefixLength         = baseStreamLength.ToString("X", CultureInfo.InvariantCulture).Length;
            var trailingHeaderLength = 0;

            if (trailingHeaders != null)
            {
                foreach (var key in trailingHeaders.Keys)
                {
                    if (checksumAlgorithm != CoreChecksumAlgorithm.NONE && ChecksumUtils.GetChecksumHeaderKey(checksumAlgorithm) == key)
                    {
                        trailingHeaderLength += key.Length +
                                                CryptoUtilFactory.GetChecksumBase64Length(checksumAlgorithm) + HEADER_ROW_PADDING_LENGTH;
                    }
                    else
                    {
                        trailingHeaderLength += key.Length + trailingHeaders[key].Length + HEADER_ROW_PADDING_LENGTH;
                    }
                }
            }

            return(prefixLength +
                   NEWLINE_LENGTH +
                   baseStreamLength +
                   NEWLINE_LENGTH +
                   EMPTY_CHUNK_LENGTH +
                   trailingHeaderLength +
                   NEWLINE_LENGTH);
        }
Exemple #2
0
        /// <summary>
        /// Computes the total size of the data payload, including the chunk metadata
        /// and optional trailing headers. Called externally so as to be able to set
        /// the correct Content-Length header value.
        /// </summary>
        /// <param name="originalLength">Length of the wrapped stream</param>
        /// <param name="signatureLength">Length of the signature for each chunk, in bytes</param>
        /// <param name="trailingHeaders">Optional trailing headers</param>
        /// <param name="trailingChecksum">Optional checksum algorithm for a trailing header</param>
        /// <returns>Total size of the wrapped payload, in bytes</returns>
        public static long ComputeChunkedContentLength(long originalLength, int signatureLength, IDictionary <string, string> trailingHeaders, CoreChecksumAlgorithm trailingChecksum)
        {
            if (originalLength < 0)
            {
                throw new ArgumentOutOfRangeException("originalLength", "Expected 0 or greater value for originalLength.");
            }

            int  trailingHeaderLength = 0;
            long chunkedContentLength;

            // Calculate the size of the chunked content, before trailing headers/checksum
            if (originalLength == 0)
            {
                chunkedContentLength = CalculateChunkHeaderLength(0, signatureLength);
            }
            else
            {
                var maxSizeChunks  = originalLength / DefaultChunkSize;
                var remainingBytes = originalLength % DefaultChunkSize;

                chunkedContentLength = maxSizeChunks * CalculateChunkHeaderLength(DefaultChunkSize, signatureLength)
                                       + (remainingBytes > 0 ? CalculateChunkHeaderLength(remainingBytes, signatureLength) : 0)
                                       + CalculateChunkHeaderLength(0, signatureLength);
            }

            if (trailingHeaders?.Count > 0)
            {
                foreach (var key in trailingHeaders.Keys)
                {
                    // If the trailing checksum key is already in dictionary, use the
                    // expected length since the checksum value may not be set yet.
                    if (trailingChecksum != CoreChecksumAlgorithm.NONE && ChecksumUtils.GetChecksumHeaderKey(trailingChecksum) == key)
                    {
                        trailingHeaderLength += key.Length +
                                                CryptoUtilFactory.GetChecksumBase64Length(trailingChecksum) + HEADER_ROW_PADDING_LENGTH;
                    }
                    else
                    {
                        trailingHeaderLength += key.Length + trailingHeaders[key].Length + HEADER_ROW_PADDING_LENGTH;
                    }
                }

                trailingHeaderLength += TRAILING_HEADER_SIGNATURE_KEY.Length + signatureLength + HEADER_ROW_PADDING_LENGTH;
            }

            return(chunkedContentLength + trailingHeaderLength);
        }