Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EntityTagHeaderOptions"/> class.
 /// </summary>
 /// <remarks>
 /// The following table shows the initial property values for an instance of <see cref="EntityTagHeaderOptions"/>.
 /// <list type="table">
 ///     <listheader>
 ///         <term>Property</term>
 ///         <description>Initial Value</description>
 ///     </listheader>
 ///     <item>
 ///         <term><see cref="EntityTagParser"/></term>
 ///         <description>A delegate that computes a MD5 hash of the body and add or update the necessary HTTP response headers needed to provide entity tag header information.</description>
 ///     </item>
 /// </list>
 /// </remarks>
 public EntityTagHeaderOptions()
 {
     EntityTagParser = (body, request, response) =>
     {
         var builder = new ChecksumBuilder(body.ComputeHash(o =>
         {
             o.AlgorithmType   = HashAlgorithmType.MD5;
             o.LeaveStreamOpen = true;
         }).Value);
         response.SetEntityTagHeaderInformation(request, builder);
     };
 }
        public void Mutate_Stream_Test()
        {
            var thisAssemblyFilePath = Assembly.GetExecutingAssembly().Location;

            using (var fileStream = File.OpenRead(thisAssemblyFilePath))
            {
                var checksum = new ChecksumBuilder()
                               .Mutate(fileStream)
                               .Calculate()
                               .ToString();

                Assert.That(checksum, Is.Not.Null.Or.Empty);
            }
        }
Пример #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="HttpEntityTagHeaderOptions"/> class.
 /// </summary>
 /// <remarks>
 /// The following table shows the initial property values for an instance of <see cref="HttpEntityTagHeaderOptions"/>.
 /// <list type="table">
 ///     <listheader>
 ///         <term>Property</term>
 ///         <description>Initial Value</description>
 ///     </listheader>
 ///     <item>
 ///         <term><see cref="EntityTagProvider"/></term>
 ///         <description><code>
 ///            (integrity, context) =>
 ///            {
 ///                var builder = new ChecksumBuilder(integrity.Checksum.Value);
 ///                context.Response.SetEntityTagHeaderInformation(context.Request, builder, integrity.ChecksumStrength == ChecksumStrength.Weak);
 ///            };
 ///         </code></description>
 ///     </item>
 ///     <item>
 ///         <term><see cref="EntityTagResponseParser"/></term>
 ///         <description><code>
 ///             (body, request, response) =>
 ///             {
 ///                  var builder = new ChecksumBuilder(body.ComputeHash(o =>
 ///                  {
 ///                      o.AlgorithmType = HashAlgorithmType.MD5;
 ///                      o.LeaveStreamOpen = true;
 ///                  }).Value);
 ///                 response.SetEntityTagHeaderInformation(request, builder);
 ///             };
 ///         </code></description>
 ///     </item>
 ///     <item>
 ///         <term><see cref="UseEntityTagResponseParser"/></term>
 ///         <description><c>false</c></description>
 ///     </item>
 /// </list>
 /// </remarks>
 public HttpEntityTagHeaderOptions()
 {
     EntityTagProvider = (integrity, context) =>
     {
         var builder = new ChecksumBuilder(integrity.Checksum.Value);
         context.Response.SetEntityTagHeaderInformation(context.Request, builder, integrity.Validation == ChecksumStrength.Weak);
     };
     EntityTagResponseParser = (body, request, response) =>
     {
         var builder = new ChecksumBuilder(body.ComputeHash(o =>
         {
             o.AlgorithmType   = HashAlgorithmType.MD5;
             o.LeaveStreamOpen = true;
         }).Value);
         response.SetEntityTagHeaderInformation(request, builder);
     };
     UseEntityTagResponseParser = false;
 }
Пример #4
0
        /// <summary>
        /// Determines whether a cached version of the requested resource is found client-side using the If-None-Match HTTP header.
        /// </summary>
        /// <param name="request">An instance of the <see cref="HttpRequest"/> object.</param>
        /// <param name="builder">A <see cref="ChecksumBuilder"/> that represents the integrity of the client.</param>
        /// <returns>
        ///     <c>true</c> if a cached version of the requested content is found client-side; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsClientSideResourceCached(this HttpRequest request, ChecksumBuilder builder)
        {
            Validator.ThrowIfNull(request, nameof(request));
            var headers = new RequestHeaders(request.Headers);

            if (headers.IfNoneMatch != null)
            {
                var clientSideEntityTagHeader = headers.IfNoneMatch.FirstOrDefault();
                var clientSideEntityTag       = clientSideEntityTagHeader == null ? "" : clientSideEntityTagHeader.Tag.Value;
                int indexOfStartQuote         = clientSideEntityTag.IndexOf('"');
                int indexOfEndQuote           = clientSideEntityTag.LastIndexOf('"');
                if (indexOfStartQuote == 0 &&
                    (indexOfEndQuote > 2 && indexOfEndQuote == clientSideEntityTag.Length - 1))
                {
                    clientSideEntityTag = clientSideEntityTag.Remove(indexOfEndQuote, 1);
                    clientSideEntityTag = clientSideEntityTag.Remove(indexOfStartQuote, 1);
                }
                return(builder.Checksum.ToHexadecimal().Equals(clientSideEntityTag));
            }
            return(false);
        }
Пример #5
0
        /// <summary>
        /// This method will either add or update the necessary HTTP response headers needed to provide entity tag header information.
        /// </summary>
        /// <param name="response">The <see cref="HttpResponse"/> to extend.</param>
        /// <param name="request">An instance of the <see cref="HttpRequest"/> object.</param>
        /// <param name="builder">A <see cref="ChecksumBuilder"/> that represents the integrity of the client.</param>
        /// <param name="isWeak">A value that indicates if this entity-tag header is a weak validator.</param>
        public static void SetEntityTagHeaderInformation(this HttpResponse response, HttpRequest request, ChecksumBuilder builder, bool isWeak = false)
        {
            Validator.ThrowIfNull(response, nameof(response));
            Validator.ThrowIfNull(request, nameof(request));
            Validator.ThrowIfNull(builder, nameof(builder));
            builder = builder.CombineWith(request.Headers["Accept"]);
            DateTime utcNow = DateTime.UtcNow;

            if (request.IsClientSideResourceCached(builder))
            {
                response.StatusCode = StatusCodes.Status304NotModified;
            }
            else
            {
                response.Headers.AddOrUpdate(HeaderNames.LastModified, new StringValues(utcNow.ToString("R", DateTimeFormatInfo.InvariantInfo)));
            }
            response.Headers.AddOrUpdate(HeaderNames.ETag, new StringValues(builder.ToEntityTag(isWeak).ToString()));
        }
Пример #6
0
 /// <summary>
 /// Creates an <see cref="EntityTagHeaderValue"/> from the specified <paramref name="builder"/>.
 /// </summary>
 /// <param name="builder">The <see cref="ChecksumBuilder"/> to extend.</param>
 /// <param name="isWeak">A value that indicates if this entity-tag header is a weak validator.</param>
 /// <returns>An <see cref="EntityTagHeaderValue"/> that is initiated with a hexadecimal representation of <see cref="ChecksumBuilder.Checksum"/> and a value that indicates if the tag is weak.</returns>
 public static EntityTagHeaderValue ToEntityTag(this ChecksumBuilder builder, bool isWeak = false)
 {
     Validator.ThrowIfNull(builder, nameof(builder));
     return(new EntityTagHeaderValue(string.Concat("\"", builder.Checksum.ToHexadecimal(), "\""), isWeak));
 }
Пример #7
0
 /// <summary>
 /// This method will either add or update the necessary HTTP response headers needed to provide entity tag header information.
 /// </summary>
 /// <param name="response">The <see cref="HttpResponse"/> to extend.</param>
 /// <param name="request">An instance of the <see cref="HttpRequest"/> object.</param>
 /// <param name="builder">A <see cref="ChecksumBuilder"/> that represents the integrity of the client.</param>
 /// <param name="isWeak">A value that indicates if this entity-tag header is a weak validator.</param>
 public static void SetEntityTagHeaderInformation(this HttpResponse response, HttpRequest request, ChecksumBuilder builder, bool isWeak = false)
 {
     Validator.ThrowIfNull(response, nameof(response));
     Validator.ThrowIfNull(request, nameof(request));
     Validator.ThrowIfNull(builder, nameof(builder));
     builder = builder.CombineWith(request.Headers[HeaderNames.Accept]);
     if (response.IsSuccessStatusCode() && request.IsClientSideResourceCached(builder))
     {
         response.StatusCode = StatusCodes.Status304NotModified;
     }
     response.Headers.AddOrUpdate(HeaderNames.ETag, new StringValues(builder.ToEntityTag(isWeak).ToString()));
 }