|
|
@ -192,6 +192,13 @@ namespace MediaBrowser.Common.Net.Handlers
|
|
|
|
|
|
|
|
|
|
|
|
ctx.Response.ContentType = await GetContentType().ConfigureAwait(false);
|
|
|
|
ctx.Response.ContentType = await GetContentType().ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string etag = await GetETag().ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(etag))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ctx.Response.Headers["ETag"] = etag;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TimeSpan cacheDuration = CacheDuration;
|
|
|
|
TimeSpan cacheDuration = CacheDuration;
|
|
|
|
|
|
|
|
|
|
|
|
DateTime? lastDateModified = await GetLastDateModified().ConfigureAwait(false);
|
|
|
|
DateTime? lastDateModified = await GetLastDateModified().ConfigureAwait(false);
|
|
|
@ -205,7 +212,11 @@ namespace MediaBrowser.Common.Net.Handlers
|
|
|
|
// If the cache hasn't expired yet just return a 304
|
|
|
|
// If the cache hasn't expired yet just return a 304
|
|
|
|
if (IsCacheValid(ifModifiedSince.ToUniversalTime(), cacheDuration, lastDateModified))
|
|
|
|
if (IsCacheValid(ifModifiedSince.ToUniversalTime(), cacheDuration, lastDateModified))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
StatusCode = 304;
|
|
|
|
// ETag must also match (if supplied)
|
|
|
|
|
|
|
|
if ((etag ?? string.Empty).Equals(ctx.Request.Headers["If-None-Match"] ?? string.Empty))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
StatusCode = 304;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -311,6 +322,11 @@ namespace MediaBrowser.Common.Net.Handlers
|
|
|
|
response.Headers[HttpResponseHeader.LastModified] = lastModified.ToString("r");
|
|
|
|
response.Headers[HttpResponseHeader.LastModified] = lastModified.ToString("r");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected virtual Task<string> GetETag()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return Task.FromResult<string>(string.Empty);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Gives subclasses a chance to do any prep work, and also to validate data and set an error status code, if needed
|
|
|
|
/// Gives subclasses a chance to do any prep work, and also to validate data and set an error status code, if needed
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|