private EntityTagHeaderValue(EntityTagHeaderValue source) { Contract.Requires(source != null); this.tag = source.tag; this.isWeak = source.isWeak; }
private EntityTagHeaderValue(EntityTagHeaderValue source) { Contract.Requires(source != null); _tag = source._tag; _isWeak = source._isWeak; }
private RangeConditionHeaderValue(RangeConditionHeaderValue source) { Contract.Requires(source != null); _entityTag = source._entityTag; _date = source._date; }
/// <summary> /// The on action executed. /// </summary> /// <param name="context"> /// The context. /// </param> public override void OnActionExecuted(HttpActionExecutedContext context) { var request = context.Request; var key = GetKey(request); EntityTagHeaderValue etag = null; bool isGet = request.Method == HttpMethod.Get; bool isPutOrPost = request.Method == HttpMethod.Put || request.Method == HttpMethod.Post; if (isPutOrPost) { ////empty the dictionary because the resource has been changed.So now all tags will be cleared and data //// will be fetched from server. It would be good to implement a logic in which only change the ETags //// of that urls which are affected by this post or put method rather than clearing entire dictionary etags.Clear(); //// generate new ETag for Put or Post because the resource is changed. etag = new EntityTagHeaderValue("\"" + Guid.NewGuid().ToString() + "\""); etags.AddOrUpdate(key, etag, (k, val) => etag); } //if ((isGet && !etags.TryGetValue(key, out etag)) || isPutOrPost) //{ // //// generate new ETag for Put or Post because the resource is changed. // etag = new EntityTagHeaderValue("\"" + Guid.NewGuid().ToString() + "\""); // etags.AddOrUpdate(key, etag, (k, val) => etag); //} if (isGet) { context.Response.Headers.ETag = etag; } }
private EntityTagHeaderValue(EntityTagHeaderValue source) { Debug.Assert(source != null); _tag = source._tag; _isWeak = source._isWeak; }
public void Equals() { var tfhv = new EntityTagHeaderValue ("\"abc\""); Assert.AreEqual (tfhv, new EntityTagHeaderValue ("\"abc\""), "#1"); Assert.AreNotEqual (tfhv, new EntityTagHeaderValue ("\"AbC\""), "#2"); Assert.AreNotEqual (tfhv, new EntityTagHeaderValue ("\"AA\""), "#3"); }
public RangeConditionHeaderValue (EntityTagHeaderValue entityTag) { if (entityTag == null) throw new ArgumentNullException ("entityTag"); EntityTag = entityTag; }
private RangeConditionHeaderValue(RangeConditionHeaderValue source) { Debug.Assert(source != null); _entityTag = source._entityTag; _date = source._date; }
public IDictionary<string, object> ParseETag(EntityTagHeaderValue etagHeaderValue) { if (etagHeaderValue == null) { throw Error.ArgumentNull("etagHeaderValue"); } string tag = etagHeaderValue.Tag.Trim('\"'); // split etag string[] rawValues = tag.Split(Separator); IDictionary<string, object> properties = new Dictionary<string, object>(); for (int index = 0; index < rawValues.Length; index++) { string rawValue = rawValues[index]; // base64 decode byte[] bytes = Convert.FromBase64String(rawValue); string valueString = Encoding.UTF8.GetString(bytes); object obj = ODataUriUtils.ConvertFromUriLiteral(valueString, ODataVersion.V3); if (obj is ODataUriNullValue) { obj = null; } properties.Add(index.ToString(CultureInfo.InvariantCulture), obj); } return properties; }
protected HttpResponseMessage GetInternal(string path) { var pathInfo = PathInfo.Create(path); var filePath = _fileSystem.Path.Combine(this.FilePath, pathInfo); if (!_fileSystem.FileExists(filePath)) return new HttpResponseMessage(HttpStatusCode.NotFound); var eTag = new EntityTagHeaderValue(string.Concat("\"", _fileSystem.GetFileInfo(filePath).Etag, "\"")); if (Request.Headers.IfNoneMatch != null) { foreach (var noneMatch in Request.Headers.IfNoneMatch) { if (eTag.Equals(noneMatch)) return new HttpResponseMessage(HttpStatusCode.NotModified); } } var stream = _fileSystem.OpenRead(filePath); var message = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(stream) }; message.Content.Headers.ContentType = new MediaTypeHeaderValue(GetMimeType(_fileSystem.Path.GetExtension(pathInfo).ToLower())); message.Headers.ETag = eTag; // remove Pragma message.Headers.Remove("Pragma"); message.Headers.CacheControl = new CacheControlHeaderValue {Private = true, MaxAge = TimeSpan.Zero}; message.Content.Headers.Expires = DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(1)); //message.Content.Headers.LastModified return message; }
public NotModifiedResponse(HttpRequestMessage request, EntityTagHeaderValue etag) : base(HttpStatusCode.NotModified) { if(etag!=null) this.Headers.ETag = etag; this.RequestMessage = request; }
public RangeConditionHeaderValue(EntityTagHeaderValue entityTag) { if (entityTag == null) { throw new ArgumentNullException(nameof(entityTag)); } _entityTag = entityTag; }
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request.Method == HttpMethod.Get) { // should we ignore trailing slash var resource = request.RequestUri.ToString(); ICollection<EntityTagHeaderValue> etags = request.Headers.IfNoneMatch; // compare the Etag with the one in the cache // do conditional get. EntityTagHeaderValue actualEtag = null; if (etags.Count > 0 && ETagHandler.ETagCache.TryGetValue(resource, out actualEtag)) { if (etags.Any(etag => etag.Tag == actualEtag.Tag)) { return Task.Factory.StartNew<HttpResponseMessage>(task => new NotModifiedResponse(), cancellationToken); } } } else if (request.Method == HttpMethod.Put) { // should we ignore trailing slash var resource = request.RequestUri.ToString(); ICollection<EntityTagHeaderValue> etags = request.Headers.IfMatch; // compare the Etag with the one in the cache // do conditional get. EntityTagHeaderValue actualEtag = null; if (etags.Count > 0 && ETagHandler.ETagCache.TryGetValue(resource, out actualEtag)) { var matchFound = etags.Any(etag => etag.Tag == actualEtag.Tag); if (!matchFound) { return Task.Factory.StartNew<HttpResponseMessage>(task => new ConflictResponse(), cancellationToken); } } } return base.SendAsync(request, cancellationToken).ContinueWith(task => { var httpResponse = task.Result; var eTagKey = request.RequestUri.ToString(); EntityTagHeaderValue eTagValue; // Post would invalidate the collection, put should invalidate the individual item if (!ETagCache.TryGetValue(eTagKey, out eTagValue) || request.Method == HttpMethod.Put || request.Method == HttpMethod.Post) { eTagValue = new EntityTagHeaderValue("\"" + Guid.NewGuid().ToString() + "\""); ETagCache.AddOrUpdate(eTagKey, eTagValue, (key, existingVal) => eTagValue); } httpResponse.Headers.ETag = eTagValue; return httpResponse; }); }
public LiveScmEditorController(ITracer tracer, IOperationLock operationLock, IEnvironment environment, IRepository repository) : base(tracer, environment, environment.RepositoryPath) { _operationLock = operationLock; _repository = repository; _currentEtag = GetCurrentEtag(); }
public static void SetEntityTagHeader(this HttpResponseMessage httpResponseMessage, EntityTagHeaderValue etag, DateTime lastModified) { if (httpResponseMessage.Content == null) { httpResponseMessage.Content = new NullContent(); } httpResponseMessage.Headers.ETag = etag; httpResponseMessage.Content.Headers.LastModified = lastModified; }
public void ToString_UseDifferentETags_AllSerializedCorrectly() { EntityTagHeaderValue etag = new EntityTagHeaderValue("\"e tag\""); Assert.Equal("\"e tag\"", etag.ToString()); etag = new EntityTagHeaderValue("\"e tag\"", true); Assert.Equal("W/\"e tag\"", etag.ToString()); etag = new EntityTagHeaderValue("\"\"", false); Assert.Equal("\"\"", etag.ToString()); }
public void Test_GetETagEntityTagHeaderValueFromETagString() { //Arrange string Version = "10"; string Expected = WeakETagString(Version); //Act System.Net.Http.Headers.EntityTagHeaderValue Result = Pyro.Common.Tools.HttpHeaderSupport.GetETagEntityTagHeaderValueFromETagString(Expected); //Assert Assert.AreEqual(Result.ToString(), Expected); }
public void Test_GetVersionString() { //Arrange string Version = "10"; System.Net.Http.Headers.EntityTagHeaderValue EntityTagHeaderValue = new System.Net.Http.Headers.EntityTagHeaderValue($"{'"'}{Version}{'"'}", true); string Expected = WeakETagString(Version); //Act string Result = Pyro.Common.Tools.HttpHeaderSupport.GetVersionString(EntityTagHeaderValue); //Assert Assert.AreEqual(Result, Version); }
public void Should_return_Conflict_for_Put_if_key_is_in_header_but_match_not_found_in_cache() { var eTagHandler = GetHandler(); var requestMessage = new HttpRequestMessage(HttpMethod.Put, etag.Key); requestMessage.Headers.Add("If-Match", etag.Value.Tag); var newRandomValue = new EntityTagHeaderValue("\"" + Guid.NewGuid() + "\""); AddETagValue(new KeyValuePair<string, EntityTagHeaderValue>(etag.Key, newRandomValue)); var response = ExecuteRequest(eTagHandler, requestMessage); response.StatusCode.ShouldEqual(HttpStatusCode.Conflict); }
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { var request = actionExecutedContext.Request; var key = GetKey(request); EntityTagHeaderValue entityTag; if (!_etTagHeaderValues.TryGetValue(key, out entityTag) || request.Method == HttpMethod.Post || request.Method == HttpMethod.Post) { entityTag = new EntityTagHeaderValue("\"" + Guid.NewGuid().ToString() + "\""); _etTagHeaderValues.AddOrUpdate(key, entityTag, (k, val) => entityTag); } actionExecutedContext.Response.Headers.ETag = entityTag; SetCacheControl(actionExecutedContext.Response); }
public void GetHashCode_UseSameAndDifferentETags_SameOrDifferentHashCodes() { EntityTagHeaderValue etag1 = new EntityTagHeaderValue("\"tag\""); EntityTagHeaderValue etag2 = new EntityTagHeaderValue("\"TAG\""); EntityTagHeaderValue etag3 = new EntityTagHeaderValue("\"tag\"", true); EntityTagHeaderValue etag4 = new EntityTagHeaderValue("\"tag1\""); EntityTagHeaderValue etag5 = new EntityTagHeaderValue("\"tag\""); EntityTagHeaderValue etag6 = EntityTagHeaderValue.Any; Assert.NotEqual(etag1.GetHashCode(), etag2.GetHashCode()); Assert.NotEqual(etag1.GetHashCode(), etag3.GetHashCode()); Assert.NotEqual(etag1.GetHashCode(), etag4.GetHashCode()); Assert.NotEqual(etag1.GetHashCode(), etag6.GetHashCode()); Assert.Equal(etag1.GetHashCode(), etag5.GetHashCode()); }
private void CheckValidParsedValue(string input, int startIndex, EntityTagHeaderValue expectedResult, int expectedIndex, bool supportsMultipleValues) { HttpHeaderParser parser = null; if (supportsMultipleValues) { parser = GenericHeaderParser.MultipleValueEntityTagParser; } else { parser = GenericHeaderParser.SingleValueEntityTagParser; } object result = null; Assert.True(parser.TryParseValue(input, null, ref startIndex, out result), string.Format("TryParse returned false. Input: '{0}', AllowMultipleValues/Any: {1}", input, supportsMultipleValues)); Assert.Equal(expectedIndex, startIndex); Assert.Equal(result, expectedResult); }
/// <summary> /// Checks if the request is conditional having a <c>If-None-Match</c> HTTP header field with a value that matches the /// <paramref name="current"/> value. In the case of <c>true</c> this can be used to indicate that a /// 304 (Not Modified) or a 412 (Precondition Failed) status code should be used. /// </summary> /// <param name="request">The request to match.</param> /// <param name="current">The current etag for the resource. If there is no current etag (i.e. the resource does not yet /// exist) then use <c>null</c>.</param> /// <returns>Returns <c>true</c> if one of the <c>If-None-Match</c> values match the current etag; or the /// <c>If-None-Match</c> value is "*" and <paramref name="current"/> is not null; otherwise false.</returns> public static bool IsIfNoneMatch(this HttpRequestMessage request, EntityTagHeaderValue current) { if (request == null) { throw new ArgumentNullException("request"); } if (request.Headers.IfNoneMatch != null) { foreach (EntityTagHeaderValue etag in request.Headers.IfNoneMatch) { if (current != null && (etag == EntityTagHeaderValue.Any || current.Equals(etag))) { return true; } } } return false; }
public object GetModule(string name) { var module = ViewModuleProvider.ResolveViewModule(name); if (module == null) return NotFound(); var eTagHeaderValue = new EntityTagHeaderValue("\"" + module.ETag + "\""); if (Request.Headers.IfNoneMatch.Contains(eTagHeaderValue)) return new HttpResponseMessage(HttpStatusCode.NotModified); var lastModifiedTime = (DateTimeOffset?)module.LastModifiedTime; if (Request.Headers.IfModifiedSince >= lastModifiedTime) return new HttpResponseMessage(HttpStatusCode.NotModified); var response = new HttpResponseMessage(HttpStatusCode.OK); response.Headers.ETag = eTagHeaderValue; response.Headers.CacheControl = new CacheControlHeaderValue() { Public = true }; response.Content = new PushStreamContent((s, c, t) => { module.Write(s); s.Close(); }); response.Content.Headers.ContentType = new MediaTypeHeaderValue(module.ContentType); response.Content.Headers.LastModified = lastModifiedTime; return response; }
protected HttpResponseMessage GetInternal(string path) { var pathInfo = PathInfo.Create(path); var filePath = _fileSystem.Path.Combine(this.FilePath, pathInfo); if (!_fileSystem.FileExists(filePath)) return new HttpResponseMessage(HttpStatusCode.NotFound); var eTag = new EntityTagHeaderValue(string.Concat("\"", _fileSystem.GetFileInfo(filePath).Etag, "\"")); if (Request.Headers.IfNoneMatch != null) { foreach (var noneMatch in Request.Headers.IfNoneMatch) { if (eTag.Equals(noneMatch)) return new HttpResponseMessage(HttpStatusCode.NotModified); } } var stream = _fileSystem.OpenRead(filePath); var message = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(stream) }; message.Content.Headers.ContentType = new MediaTypeHeaderValue(GetMimeType(_fileSystem.Path.GetExtension(pathInfo).ToLower())); message.Headers.ETag = eTag; return message; }
private static void SetEtag(HttpResponseMessage message, string etag) { if (etag != null) { var eTag = new EntityTagHeaderValue(@"""" + etag.Replace("\"", string.Empty) + @""""); message.Headers.ETag = eTag; } }
public void CreateEntry_SetsEtagToNotNull_IfWithConcurrencyProperty() { // Arrange Mock<IEdmStructuralProperty> mockConcurrencyProperty = new Mock<IEdmStructuralProperty>(); mockConcurrencyProperty.SetupGet(s => s.ConcurrencyMode).Returns(EdmConcurrencyMode.Fixed); mockConcurrencyProperty.SetupGet(s => s.Name).Returns("City"); SelectExpandNode selectExpandNode = new SelectExpandNode { SelectedStructuralProperties = { new Mock<IEdmStructuralProperty>().Object, mockConcurrencyProperty.Object } }; ODataProperty[] properties = new[] { new ODataProperty(), new ODataProperty() }; Mock<ODataEntityTypeSerializer> serializer = new Mock<ODataEntityTypeSerializer>(_serializerProvider); serializer.CallBase = true; serializer .Setup(s => s.CreateStructuralProperty(selectExpandNode.SelectedStructuralProperties.ElementAt(0), _entityInstanceContext)) .Returns(properties[0]); serializer .Setup(s => s.CreateStructuralProperty(selectExpandNode.SelectedStructuralProperties.ElementAt(1), _entityInstanceContext)) .Returns(properties[1]); MockHttpRequestMessage request = new MockHttpRequestMessage(); HttpConfiguration configuration = new HttpConfiguration(); Mock<IETagHandler> mockETagHandler = new Mock<IETagHandler>(); string tag = "\"'anycity'\""; EntityTagHeaderValue etagHeaderValue = new EntityTagHeaderValue(tag, isWeak: true); mockETagHandler.Setup(e => e.CreateETag(It.IsAny<IDictionary<string, object>>())).Returns(etagHeaderValue); configuration.SetETagHandler(mockETagHandler.Object); request.SetConfiguration(configuration); _entityInstanceContext.Request = request; // Act ODataEntry entry = serializer.Object.CreateEntry(selectExpandNode, _entityInstanceContext); // Assert Assert.Equal(etagHeaderValue.ToString(), entry.ETag); }
public void ETag_ReadAndWriteProperty_CallsForwardedToHttpGeneralHeaders() { Assert.Null(headers.ETag); EntityTagHeaderValue etag = new EntityTagHeaderValue("\"tag\"", true); headers.ETag = etag; Assert.Same(etag, headers.ETag); headers.ETag = null; Assert.Null(headers.ETag); Assert.False(headers.Contains("ETag"), "Header store should not contain a header 'ETag' after setting it to null."); }
public void GetETag_ThrowsInvalidOperation_EmptyRequest() { // Arrange HttpRequestMessage request = new HttpRequestMessage(); EntityTagHeaderValue headerValue = new EntityTagHeaderValue("\"any\""); // Act & Assert Assert.Throws<InvalidOperationException>(() => request.GetETag(headerValue), "Request message does not contain an HttpConfiguration object."); }
public void GetETag_ThrowsArgumentNull_Request() { // Arrange HttpRequestMessage request = null; EntityTagHeaderValue headerValue = new EntityTagHeaderValue("\"any\""); // Act & Assert Assert.ThrowsArgumentNull(() => request.GetETag(headerValue), "request"); }
public void Equals_UseSameAndDifferentETags_EqualOrNotEqualNoExceptions() { EntityTagHeaderValue etag1 = new EntityTagHeaderValue("\"tag\""); EntityTagHeaderValue etag2 = new EntityTagHeaderValue("\"TAG\""); EntityTagHeaderValue etag3 = new EntityTagHeaderValue("\"tag\"", true); EntityTagHeaderValue etag4 = new EntityTagHeaderValue("\"tag1\""); EntityTagHeaderValue etag5 = new EntityTagHeaderValue("\"tag\""); EntityTagHeaderValue etag6 = EntityTagHeaderValue.Any; Assert.False(etag1.Equals(etag2)); Assert.False(etag2.Equals(etag1)); Assert.False(etag1.Equals(null)); Assert.False(etag1.Equals(etag3)); Assert.False(etag3.Equals(etag1)); Assert.False(etag1.Equals(etag4)); Assert.False(etag1.Equals(etag6)); Assert.True(etag1.Equals(etag5)); }
public async Task DeleteItemDeletesFileIfETagMatches(EntityTagHeaderValue etag) { // Arrange var date = new DateTime(2012, 07, 06); string path = @"/foo/bar.txt"; var fileInfo = new Mock<FileInfoBase>(); fileInfo.SetupGet(f => f.Attributes).Returns(FileAttributes.Normal); fileInfo.SetupGet(f => f.LastWriteTimeUtc).Returns(date); var dirInfo = new Mock<DirectoryInfoBase>(); dirInfo.SetupGet(d => d.Attributes).Returns(FileAttributes.Normal); var fileSystem = CreateFileSystem(path, dirInfo.Object, fileInfo.Object); FileSystemHelpers.Instance = fileSystem; var controller = CreateController(path); controller.Request.Headers.IfMatch.Add(new EntityTagHeaderValue("\"this-will-not-match\"")); controller.Request.Headers.IfMatch.Add(etag); // Act var response = await controller.DeleteItem(); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); fileInfo.Verify(f => f.Delete()); }
internal static int GetRangeConditionLength(string input, int startIndex, out object parsedValue) { Contract.Requires(startIndex >= 0); parsedValue = null; // Make sure we have at least 2 characters if (string.IsNullOrEmpty(input) || (startIndex + 1 >= input.Length)) { return(0); } int current = startIndex; // Caller must remove leading whitespaces. DateTimeOffset date = DateTimeOffset.MinValue; EntityTagHeaderValue entityTag = null; // Entity tags are quoted strings optionally preceded by "W/". By looking at the first two character we // can determine whether the string is en entity tag or a date. char firstChar = input[current]; char secondChar = input[current + 1]; if ((firstChar == '\"') || (((firstChar == 'w') || (firstChar == 'W')) && (secondChar == '/'))) { // trailing whitespaces are removed by GetEntityTagLength() int entityTagLength = EntityTagHeaderValue.GetEntityTagLength(input, current, out entityTag); if (entityTagLength == 0) { return(0); } current = current + entityTagLength; // RangeConditionHeaderValue only allows 1 value. There must be no delimiter/other chars after an // entity tag. if (current != input.Length) { return(0); } } else { if (!HttpRuleParser.TryStringToDate(input.Substring(current), out date)) { return(0); } // If we got a valid date, then the parser consumed the whole string (incl. trailing whitespaces). current = input.Length; } RangeConditionHeaderValue result = new RangeConditionHeaderValue(); if (entityTag == null) { result._date = date; } else { result._entityTag = entityTag; } parsedValue = result; return(current - startIndex); }