public static bool TryParse(string timedETagValue, out TimedEntityTagHeaderValue value) { value = null; if (timedETagValue == null) { return(false); } var strings = timedETagValue.Split(new[] { "\r\n" }, StringSplitOptions.None); if (strings.Length != 2) { return(false); } EntityTagHeaderValue etag = null; DateTimeOffset lastModified; if (!EntityTagHeaderValue.TryParse(strings[0], out etag)) { return(false); } if (!DateTimeOffset.TryParse(strings[1], out lastModified)) { return(false); } value = new TimedEntityTagHeaderValue(etag.Tag, etag.IsWeak) { LastModified = lastModified }; return(true); }
private void CheckInvalidTryParse(string input) { EntityTagHeaderValue result = null; Assert.False(EntityTagHeaderValue.TryParse(input, out result)); Assert.Null(result); }
private void CheckInvalidParse(string input) { Assert.Throws <FormatException>(() => { EntityTagHeaderValue.Parse(input); }); Assert.False(EntityTagHeaderValue.TryParse(input, out EntityTagHeaderValue result)); Assert.Null(result); }
public void TryParse() { EntityTagHeaderValue res; Assert.IsTrue(EntityTagHeaderValue.TryParse("\"\"", out res), "#1"); Assert.AreEqual("\"\"", res.Tag, "#2"); }
public void TryParse_Invalid() { EntityTagHeaderValue res; Assert.IsFalse(EntityTagHeaderValue.TryParse("", out res), "#1"); Assert.IsNull(res, "#2"); }
public async Task <CacheCandidateState> CheckRemoteCacheAsync(string url, string appPageVersionCurrent) { var request = new HttpRequestMessage(HttpMethod.Get, url); // Check for remote content based on the app page version if (EntityTagHeaderValue.TryParse(appPageVersionCurrent, out var eTagValue)) { request.Headers.IfNoneMatch.Add(eTagValue); } var serverResponse = await _httpClient.SendAsync(request).ConfigureAwait(false); var contentType = serverResponse?.Content?.Headers?.ContentType?.MediaType; // Check if request returned some content if (serverResponse.StatusCode == HttpStatusCode.NotModified || contentType == null) { return(null); } // Check if we have a new entity tag var appPageVersion = serverResponse.Headers.ETag?.ToString() ?? string.Empty; var responseStream = await serverResponse.Content.ReadAsStreamAsync(); return(new CacheCandidateState { ResponseStream = responseStream, StatusCode = serverResponse.StatusCode, AppPageVersion = appPageVersion, ContentType = contentType, ContentLength64 = responseStream.Length }); }
private void CheckValidTryParse(string input, EntityTagHeaderValue expectedResult) { EntityTagHeaderValue result = null; Assert.True(EntityTagHeaderValue.TryParse(input, out result)); Assert.Equal(expectedResult, result); }
public async Task <FetchTogglesResult> FetchToggles(string etag, CancellationToken cancellationToken) { const string resourceUri = "api/client/features"; using (var request = new HttpRequestMessage(HttpMethod.Get, resourceUri)) { SetRequestHeaders(request, ClientRequestHeaders); if (!string.IsNullOrEmpty(etag) && EntityTagHeaderValue.TryParse(etag, out var etagHeaderValue)) { request.Headers.IfNoneMatch.Add(etagHeaderValue); } using (var response = await httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false)) { if (response.StatusCode == HttpStatusCode.NotModified || (!string.IsNullOrEmpty(etag) && (response.Headers.ETag?.Tag?.Equals(etag) ?? false))) { return(new FetchTogglesResult { HasChanged = false, Etag = response.Headers.ETag.Tag, ToggleCollection = null }); } if (!response.IsSuccessStatusCode) { await HandleError(response, resourceUri); return(new FetchTogglesResult { HasChanged = false, Etag = null }); } var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); var toggleCollection = JsonSerializer.Deserialize <ToggleCollection>(stream); if (toggleCollection == null) { return(new FetchTogglesResult { HasChanged = false }); } // Success return(new FetchTogglesResult { HasChanged = true, Etag = response.Headers.ETag?.Tag, ToggleCollection = toggleCollection }); } } }
/// <summary> /// Expects a Etag string e.g(W/"3141") and returns an EntityTagHeaderValue instance /// </summary> /// <param name="ETag"></param> /// <returns>EntityTagHeaderValue</returns> public static EntityTagHeaderValue GetETagEntityTagHeaderValueFromETagString(string ETag) { EntityTagHeaderValue TempEtag; if (EntityTagHeaderValue.TryParse(ETag, out TempEtag)) { return(TempEtag); } throw new FormatException("ETag is not formated correctly, string was: " + ETag); }
private async Task <bool> ContinueExecution( string concatenatedEtags, string modifiedDate, string representationId, Func <DateTime, ConcurrentObject, bool> checkDateCallback, Func <ConcurrentObject, List <EntityTagHeaderValue>, bool> checkEtagCorrectCallback) { if (string.IsNullOrWhiteSpace(concatenatedEtags) && string.IsNullOrWhiteSpace(modifiedDate)) { return(true); } // Check a representation exists var lastRepresentation = await _concurrencyManager.TryGetRepresentationAsync(representationId); if (lastRepresentation == null) { throw new ArgumentNullException($"the representation {representationId} doesn't exist"); } if (string.IsNullOrWhiteSpace(concatenatedEtags) || concatenatedEtags == "*") { // Process the date DateTime dateTime; if (!DateTime.TryParse(modifiedDate, out dateTime)) { return(true); } return(checkDateCallback(dateTime, lastRepresentation)); } else { // Check etags are correct var etagsStr = concatenatedEtags.Split(','); var etags = new List <EntityTagHeaderValue>(); foreach (var etagStr in etagsStr) { EntityTagHeaderValue et = null; if (EntityTagHeaderValue.TryParse(etagStr, out et)) { etags.Add(et); } } if (checkEtagCorrectCallback(lastRepresentation, etags)) { return(true); } } return(false); }
internal static bool ContentIsNotModified(ResponseCachingContext context) { var cachedResponseHeaders = context.CachedResponseHeaders; var ifNoneMatchHeader = context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch]; if (!StringValues.IsNullOrEmpty(ifNoneMatchHeader)) { if (ifNoneMatchHeader.Count == 1 && StringSegment.Equals(ifNoneMatchHeader[0], EntityTagHeaderValue.Any.Tag, StringComparison.OrdinalIgnoreCase)) { context.Logger.LogNotModifiedIfNoneMatchStar(); return(true); } EntityTagHeaderValue eTag; IList <EntityTagHeaderValue> ifNoneMatchEtags; if (!StringValues.IsNullOrEmpty(cachedResponseHeaders[HeaderNames.ETag]) && EntityTagHeaderValue.TryParse(cachedResponseHeaders[HeaderNames.ETag].ToString(), out eTag) && EntityTagHeaderValue.TryParseList(ifNoneMatchHeader, out ifNoneMatchEtags)) { for (var i = 0; i < ifNoneMatchEtags.Count; i++) { var requestETag = ifNoneMatchEtags[i]; if (eTag.Compare(requestETag, useStrongComparison: false)) { context.Logger.LogNotModifiedIfNoneMatchMatched(requestETag); return(true); } } } } else { var ifModifiedSince = context.HttpContext.Request.Headers[HeaderNames.IfModifiedSince]; if (!StringValues.IsNullOrEmpty(ifModifiedSince)) { DateTimeOffset modified; if (!HeaderUtilities.TryParseDate(cachedResponseHeaders[HeaderNames.LastModified].ToString(), out modified) && !HeaderUtilities.TryParseDate(cachedResponseHeaders[HeaderNames.Date].ToString(), out modified)) { return(false); } DateTimeOffset modifiedSince; if (HeaderUtilities.TryParseDate(ifModifiedSince.ToString(), out modifiedSince) && modified <= modifiedSince) { context.Logger.LogNotModifiedIfModifiedSinceSatisfied(modified, modifiedSince); return(true); } } } return(false); }
public static ActionResult IntoBinaryResult <TError>(this Result <BinaryContent, TError> result) where TError : Error { if (result == null) { return(new StatusCodeResult(StatusCodes.Status422UnprocessableEntity)); } return(result.Match <ActionResult>( ok => { if (ok == null) { return new StatusCodeResult(StatusCodes.Status422UnprocessableEntity); } if (ok.Data == null) { return new StatusCodeResult(StatusCodes.Status304NotModified); } var mime = ok.MimeType ?? "application/octet-stream"; var res = new FileContentResult(ok.Data, mime); if (!string.IsNullOrEmpty(ok.ContentHash)) { EntityTagHeaderValue entityTagHeaderValue; bool isValid = EntityTagHeaderValue.TryParse($"\"{ok.ContentHash}\"", out entityTagHeaderValue); if (!isValid) { isValid = EntityTagHeaderValue.TryParse(ok.ContentHash, out entityTagHeaderValue); } if (!isValid) { throw new ServerErrorException($"Unprocessable ETag: {ok.ContentHash}"); } res.EntityTag = entityTagHeaderValue; } return res; }, err => { var res = new ObjectResult(err); res.StatusCode = err.ErrorCode.IntoStatusCode(); return res; })); }
public async Task GetEntityWithIfNoneMatchShouldReturnNotModifiedETagsTest_ForDouble() { // Arrange HttpClient client = CreateClient(); string eTag; var getUri = "double/ETagsCustomers?$format=json"; // Act using (var response = await client.GetAsync(getUri)) { // Assert Assert.True(response.IsSuccessStatusCode); var json = await response.Content.ReadAsObject <JObject>(); var result = json.GetValue("value") as JArray; Assert.NotNull(result); // check the first unchanged, the first unchanged could be "3" // because #0, #1, #2 will change potentially running in parallel by other tests. eTag = result[3]["@odata.etag"].ToString(); Assert.False(String.IsNullOrEmpty(eTag)); Assert.Equal("W/\"OC4w\"", eTag); EntityTagHeaderValue parsedValue; Assert.True(EntityTagHeaderValue.TryParse(eTag, out parsedValue)); IDictionary <string, object> tags = this.ParseETag(parsedValue); KeyValuePair <string, object> pair = Assert.Single(tags); Single value = Assert.IsType <Single>(pair.Value); Assert.Equal((Single)8.0, value); } // Arrange var getRequestWithEtag = new HttpRequestMessage(HttpMethod.Get, "double/ETagsCustomers(3)"); getRequestWithEtag.Headers.IfNoneMatch.ParseAdd(eTag); // Act using (var response = await client.SendAsync(getRequestWithEtag)) { // Assert Assert.Equal(HttpStatusCode.NotModified, response.StatusCode); } }
private int? GetIfMatchFromHeader() { var header = HttpContext.Request.Headers.GetHeaderValue(HeaderConstants.IfMatch); if (header == null) return null; _ = EntityTagHeaderValue.TryParse(header, out var entityTagHeaderValue); if (entityTagHeaderValue == null) return null; var version = entityTagHeaderValue.Tag.Replace("\"", string.Empty); if (int.TryParse(version, out var numericValue)) return numericValue; return null; }
public async Task GetEntryWithIfNoneMatchShouldReturnNotModifiedETagsTest_ForDouble() { string eTag; var getUri = this.BaseAddress + "/double/ETagsCustomers?$format=json"; using (var response = await Client.GetAsync(getUri)) { Assert.True(response.IsSuccessStatusCode); var json = await response.Content.ReadAsAsync <JObject>(); var result = json.GetValue("value") as JArray; Assert.NotNull(result); // check the first eTag = result[0]["@odata.etag"].ToString(); Assert.False(String.IsNullOrEmpty(eTag)); Assert.Equal("W/\"Mi4w\"", eTag); EntityTagHeaderValue parsedValue; Assert.True(EntityTagHeaderValue.TryParse(eTag, out parsedValue)); HttpConfiguration config = new HttpConfiguration(); IETagHandler handler = config.GetETagHandler(); IDictionary <string, object> tags = handler.ParseETag(parsedValue); KeyValuePair <string, object> pair = Assert.Single(tags); Single value = Assert.IsType <Single>(pair.Value); Assert.Equal((Single)2.0, value); } var getRequestWithEtag = new HttpRequestMessage(HttpMethod.Get, this.BaseAddress + "/double/ETagsCustomers(0)"); getRequestWithEtag.Headers.IfNoneMatch.ParseAdd(eTag); using (var response = await Client.SendAsync(getRequestWithEtag)) { Assert.Equal(HttpStatusCode.NotModified, response.StatusCode); } }
public async Task GetEntryWithIfNoneMatchShouldReturnNotModifiedETagsTest_ForShort() { string eTag; var getUri = this.BaseAddress + "/short/ETagsCustomers?$format=json"; using (var response = await Client.GetAsync(getUri)) { Assert.True(response.IsSuccessStatusCode); var json = await response.Content.ReadAsObject <JObject>(); var result = json.GetValue("value") as JArray; Assert.NotNull(result); // check the second eTag = result[1]["@odata.etag"].ToString(); Assert.False(String.IsNullOrEmpty(eTag)); Assert.Equal("W/\"MzI3NjY=\"", eTag); EntityTagHeaderValue parsedValue; Assert.True(EntityTagHeaderValue.TryParse(eTag, out parsedValue)); IDictionary <string, object> tags = this.ParseETag(parsedValue); KeyValuePair <string, object> pair = Assert.Single(tags); int value = Assert.IsType <int>(pair.Value); Assert.Equal((short)32766, value); } var getRequestWithEtag = new HttpRequestMessage(HttpMethod.Get, this.BaseAddress + "/short/ETagsCustomers(1)"); getRequestWithEtag.Headers.IfNoneMatch.ParseAdd(eTag); using (var response = await Client.SendAsync(getRequestWithEtag)) { Assert.Equal(HttpStatusCode.NotModified, response.StatusCode); } }
public async Task <FetchTogglesResult> FetchToggles(string etag, CancellationToken cancellationToken) { const string resourceUri = "api/client/features"; using (var request = new HttpRequestMessage(HttpMethod.Get, resourceUri)) { SetRequestHeaders(request, clientRequestHeaders); if (EntityTagHeaderValue.TryParse(etag, out var etagHeaderValue)) { request.Headers.IfNoneMatch.Add(etagHeaderValue); } using (var response = await httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false)) { if (!response.IsSuccessStatusCode) { var error = await response.Content.ReadAsStringAsync().ConfigureAwait(false); Logger.Trace($"UNLEASH: Error {response.StatusCode} from server in '{nameof(FetchToggles)}': " + error); return(new FetchTogglesResult { HasChanged = false, Etag = null, }); } var newEtag = response.Headers.ETag?.Tag; if (newEtag == etag) { return(new FetchTogglesResult { HasChanged = false, Etag = newEtag, ToggleCollection = null, }); } var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); var toggleCollection = jsonSerializer.Deserialize <ToggleCollection>(stream); if (toggleCollection == null) { return(new FetchTogglesResult { HasChanged = false }); } // Success return(new FetchTogglesResult { HasChanged = true, Etag = newEtag, ToggleCollection = toggleCollection }); } } }