/// <summary>
        /// Indicates whether this is a If-None-Match request with a matching etag.
        /// </summary>
        protected bool IsIfNoneMatchRequest(EntityTagHeaderValue currentEtag)
        {
            // CORE TODO Now using Microsoft.Net.Http.Headers, make sure it still has the same semantics
            // (null vs empty string, etc.)
            var headers = Request.GetTypedHeaders();

            return(currentEtag != null && headers.IfNoneMatch != null &&
                   headers.IfNoneMatch.Any(entityTag => currentEtag.Compare(entityTag, false)));
        }
        private static bool EtagEquals(HttpRequest request, EntityTagHeaderValue currentEtag)
        {
            // CORE TODO Double check this... before I found the GetTypedHeaders() extension method, I didn't think there was a typed implementation of the IfNoneMatch header
            // anymore, so I reimplemented based on the response caching middleware's implementation, leaving out the * match. See
            // https://github.com/aspnet/ResponseCaching/blob/52e8ffefb9b22c7c591aec15845baf07ed99356c/src/Microsoft.AspNetCore.ResponseCaching/ResponseCachingMiddleware.cs#L454-L478

            var ifNoneMatchHeader = request.Headers["If-None-Match"];

            if (StringValues.IsNullOrEmpty(ifNoneMatchHeader))
            {
                return(false);
            }
            return(EntityTagHeaderValue.TryParseList(ifNoneMatchHeader, out IList <Microsoft.Net.Http.Headers.EntityTagHeaderValue> ifNoneMatchEtags) &&
                   ifNoneMatchEtags.Any(t => currentEtag.Compare(t, useStrongComparison: false)));
        }
 public void CompareUsingStrongComparison_NonEquivalentPairs_ReturnFalse(EntityTagHeaderValue left, EntityTagHeaderValue right)
 {
     Assert.False(left.Compare(right, useStrongComparison: true));
     Assert.False(right.Compare(left, useStrongComparison: true));
 }
 public void CompareUsingWeakComparison_EquivalentPairs_ReturnTrue(EntityTagHeaderValue left, EntityTagHeaderValue right)
 {
     Assert.True(left.Compare(right, useStrongComparison: false));
     Assert.True(right.Compare(left, useStrongComparison: false));
 }
Exemple #5
0
        protected override async Task <IActionResult> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists)
        {
            // Check that we have a matching conditional If-Match request for existing resources
            if (itemExists)
            {
                var requestHeaders  = Request.GetTypedHeaders();
                var responseHeaders = Response.GetTypedHeaders();

                // Get current etag
                EntityTagHeaderValue currentEtag = CreateEntityTag(info);

                // Existing resources require an etag to be updated.
                if (requestHeaders.IfMatch == null)
                {
                    return(StatusCode(StatusCodes.Status412PreconditionFailed, Resources.VfsController_MissingIfMatch));
                }

                bool isMatch = false;
                foreach (EntityTagHeaderValue etag in requestHeaders.IfMatch)
                {
                    if (currentEtag.Compare(etag, false) || etag == EntityTagHeaderValue.Any)
                    {
                        isMatch = true;
                        break;
                    }
                }

                if (!isMatch)
                {
                    responseHeaders.ETag = currentEtag;
                    return(StatusCode(StatusCodes.Status412PreconditionFailed, Resources.VfsController_EtagMismatch));
                }
            }

            // Save file
            try
            {
                using (Stream fileStream = GetFileWriteStream(localFilePath, fileExists: itemExists))
                {
                    try
                    {
                        await Request.Body.CopyToAsync(fileStream);
                    }
                    catch (Exception ex)
                    {
                        Tracer.TraceError(ex);
                        return(StatusCode(
                                   StatusCodes.Status409Conflict,
                                   RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message)));
                    }
                }

                // Return either 204 No Content or 201 Created response

                // Set updated etag for the file
                info.Refresh();
                Response.SetEntityTagHeader(CreateEntityTag(info), info.LastWriteTimeUtc);
                return(itemExists ? NoContent() : StatusCode(StatusCodes.Status201Created));
            }
            catch (Exception ex)
            {
                Tracer.TraceError(ex);
                return(StatusCode(StatusCodes.Status409Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message)));
            }
        }