aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs38
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpResultFactory.cs100
-rw-r--r--MediaBrowser.Controller/Net/StaticResultOptions.cs2
-rw-r--r--deployment/debian-package-x64/pkg-src/changelog12
-rw-r--r--deployment/debian-package-x64/pkg-src/control7
-rw-r--r--deployment/fedora-package-x64/pkg-src/jellyfin.spec12
6 files changed, 56 insertions, 115 deletions
diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs
index 6ea1bd08e..2232b3eeb 100644
--- a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs
@@ -66,11 +66,6 @@ namespace Emby.Server.Implementations.HttpClientManager
// http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c
ServicePointManager.Expect100Continue = false;
-
-#if NET46
-// Trakt requests sometimes fail without this
- ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;
-#endif
}
/// <summary>
@@ -106,23 +101,6 @@ namespace Emby.Server.Implementations.HttpClientManager
return client;
}
- private static WebRequest CreateWebRequest(string url)
- {
- try
- {
- return WebRequest.Create(url);
- }
- catch (NotSupportedException)
- {
- //Webrequest creation does fail on MONO randomly when using WebRequest.Create
- //the issue occurs in the GetCreator method here: http://www.oschina.net/code/explore/mono-2.8.1/mcs/class/System/System.Net/WebRequest.cs
-
- var type = Type.GetType("System.Net.HttpRequestCreator, System, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089");
- var creator = Activator.CreateInstance(type, nonPublic: true) as IWebRequestCreate;
- return creator.Create(new Uri(url)) as HttpWebRequest;
- }
- }
-
private WebRequest GetRequest(HttpRequestOptions options, string method)
{
string url = options.Url;
@@ -135,7 +113,7 @@ namespace Emby.Server.Implementations.HttpClientManager
url = url.Replace(userInfo + "@", string.Empty);
}
- var request = CreateWebRequest(url);
+ var request = WebRequest.Create(url);
if (request is HttpWebRequest httpWebRequest)
{
@@ -627,14 +605,16 @@ namespace Emby.Server.Implementations.HttpClientManager
var exception = new HttpException(webException.Message, webException);
- var response = webException.Response as HttpWebResponse;
- if (response != null)
+ using (var response = webException.Response as HttpWebResponse)
{
- exception.StatusCode = response.StatusCode;
-
- if ((int)response.StatusCode == 429)
+ if (response != null)
{
- client.LastTimeout = DateTime.UtcNow;
+ exception.StatusCode = response.StatusCode;
+
+ if ((int)response.StatusCode == 429)
+ {
+ client.LastTimeout = DateTime.UtcNow;
+ }
}
}
diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
index 7445fd3c2..75ca57ebb 100644
--- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -422,18 +422,20 @@ namespace Emby.Server.Implementations.HttpServer
/// <summary>
/// Pres the process optimized result.
/// </summary>
- private object GetCachedResult(IRequest requestContext, IDictionary<string, string> responseHeaders, Guid cacheKey, string cacheKeyString, DateTime? lastDateModified, TimeSpan? cacheDuration, string contentType)
+ private object GetCachedResult(IRequest requestContext, IDictionary<string, string> responseHeaders, StaticResultOptions options)
{
bool noCache = (requestContext.Headers.Get("Cache-Control") ?? string.Empty).IndexOf("no-cache", StringComparison.OrdinalIgnoreCase) != -1;
+ AddCachingHeaders(responseHeaders, options.CacheDuration, noCache, options.DateLastModified);
if (!noCache)
{
- if (IsNotModified(requestContext, cacheKey))
+ DateTime.TryParse(requestContext.Headers.Get("If-Modified-Since"), out var ifModifiedSinceHeader);
+
+ if (IsNotModified(ifModifiedSinceHeader, options.CacheDuration, options.DateLastModified))
{
- AddAgeHeader(responseHeaders, lastDateModified);
- AddExpiresHeader(responseHeaders, cacheKeyString, cacheDuration);
+ AddAgeHeader(responseHeaders, options.DateLastModified);
- var result = new HttpResult(Array.Empty<byte>(), contentType ?? "text/html", HttpStatusCode.NotModified);
+ var result = new HttpResult(Array.Empty<byte>(), options.ContentType ?? "text/html", HttpStatusCode.NotModified);
AddResponseHeaders(result, responseHeaders);
@@ -441,8 +443,6 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- AddCachingHeaders(responseHeaders, cacheKeyString, cacheDuration);
-
return null;
}
@@ -487,9 +487,6 @@ namespace Emby.Server.Implementations.HttpServer
options.DateLastModified = _fileSystem.GetLastWriteTimeUtc(path);
}
- var cacheKey = path + options.DateLastModified.Value.Ticks;
-
- options.CacheKey = cacheKey.GetMD5();
options.ContentFactory = () => Task.FromResult(GetFileStream(path, fileShare));
options.ResponseHeaders = options.ResponseHeaders ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
@@ -520,7 +517,6 @@ namespace Emby.Server.Implementations.HttpServer
return GetStaticResult(requestContext, new StaticResultOptions
{
CacheDuration = cacheDuration,
- CacheKey = cacheKey,
ContentFactory = factoryFn,
ContentType = contentType,
DateLastModified = lastDateModified,
@@ -534,14 +530,10 @@ namespace Emby.Server.Implementations.HttpServer
options.ResponseHeaders = options.ResponseHeaders ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var contentType = options.ContentType;
- var etag = requestContext.Headers.Get("If-None-Match");
- var cacheKey = etag != null ? new Guid(etag.Trim('\"')) : Guid.Empty;
- if (!cacheKey.Equals(Guid.Empty))
+ if (!string.IsNullOrEmpty(requestContext.Headers.Get("If-Modified-Since")))
{
- var key = cacheKey.ToString("N");
-
// See if the result is already cached in the browser
- var result = GetCachedResult(requestContext, options.ResponseHeaders, cacheKey, key, options.DateLastModified, options.CacheDuration, contentType);
+ var result = GetCachedResult(requestContext, options.ResponseHeaders, options);
if (result != null)
{
@@ -553,6 +545,8 @@ namespace Emby.Server.Implementations.HttpServer
var isHeadRequest = options.IsHeadRequest || string.Equals(requestContext.Verb, "HEAD", StringComparison.OrdinalIgnoreCase);
var factoryFn = options.ContentFactory;
var responseHeaders = options.ResponseHeaders;
+ AddCachingHeaders(responseHeaders, options.CacheDuration, false, options.DateLastModified);
+ AddAgeHeader(responseHeaders, options.DateLastModified);
var rangeHeader = requestContext.Headers.Get("Range");
@@ -566,21 +560,10 @@ namespace Emby.Server.Implementations.HttpServer
};
AddResponseHeaders(hasHeaders, options.ResponseHeaders);
- // Generate an ETag based on identifying information - TODO read contents from filesystem instead?
- var responseId = $"{hasHeaders.ContentType}{options.Path}{hasHeaders.TotalContentLength}";
- var hashedId = MD5.Create().ComputeHash(Encoding.Default.GetBytes(responseId));
- hasHeaders.Headers["ETag"] = new Guid(hashedId).ToString("N");
-
return hasHeaders;
}
var stream = await factoryFn().ConfigureAwait(false);
- // Generate an etag based on stream content
- var streamHash = MD5.Create().ComputeHash(stream);
- var newEtag = new Guid(streamHash).ToString("N");
-
- // reset position so the response can re-use it -- TODO is this ok?
- stream.Position = 0;
var totalContentLength = options.ContentLength;
if (!totalContentLength.HasValue)
@@ -603,7 +586,6 @@ namespace Emby.Server.Implementations.HttpServer
};
AddResponseHeaders(hasHeaders, options.ResponseHeaders);
- hasHeaders.Headers["ETag"] = newEtag;
return hasHeaders;
}
else
@@ -628,7 +610,6 @@ namespace Emby.Server.Implementations.HttpServer
};
AddResponseHeaders(hasHeaders, options.ResponseHeaders);
- hasHeaders.Headers["ETag"] = newEtag;
return hasHeaders;
}
}
@@ -641,37 +622,28 @@ namespace Emby.Server.Implementations.HttpServer
/// <summary>
/// Adds the caching responseHeaders.
/// </summary>
- private void AddCachingHeaders(IDictionary<string, string> responseHeaders, string cacheKey, TimeSpan? cacheDuration)
+ private void AddCachingHeaders(IDictionary<string, string> responseHeaders, TimeSpan? cacheDuration,
+ bool noCache, DateTime? lastModifiedDate)
{
- if (cacheDuration.HasValue)
- {
- responseHeaders["Cache-Control"] = "public, max-age=" + Convert.ToInt32(cacheDuration.Value.TotalSeconds);
- }
- else if (!string.IsNullOrEmpty(cacheKey))
- {
- responseHeaders["Cache-Control"] = "public";
- }
- else
+ if (noCache)
{
responseHeaders["Cache-Control"] = "no-cache, no-store, must-revalidate";
responseHeaders["pragma"] = "no-cache, no-store, must-revalidate";
+ return;
}
- AddExpiresHeader(responseHeaders, cacheKey, cacheDuration);
- }
-
- /// <summary>
- /// Adds the expires header.
- /// </summary>
- private static void AddExpiresHeader(IDictionary<string, string> responseHeaders, string cacheKey, TimeSpan? cacheDuration)
- {
if (cacheDuration.HasValue)
{
- responseHeaders["Expires"] = DateTime.UtcNow.Add(cacheDuration.Value).ToString("r");
+ responseHeaders["Cache-Control"] = "public, max-age=" + cacheDuration.Value.TotalSeconds;
}
- else if (string.IsNullOrEmpty(cacheKey))
+ else
{
- responseHeaders["Expires"] = "-1";
+ responseHeaders["Cache-Control"] = "public";
+ }
+
+ if (lastModifiedDate.HasValue)
+ {
+ responseHeaders["Last-Modified"] = lastModifiedDate.ToString();
}
}
@@ -687,32 +659,6 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders["Age"] = Convert.ToInt64((DateTime.UtcNow - lastDateModified.Value).TotalSeconds).ToString(CultureInfo.InvariantCulture);
}
}
- /// <summary>
- /// Determines whether [is not modified] [the specified cache key].
- /// </summary>
- /// <param name="requestContext">The request context.</param>
- /// <param name="cacheKey">The cache key.</param>
- /// <param name="lastDateModified">The last date modified.</param>
- /// <param name="cacheDuration">Duration of the cache.</param>
- /// <returns><c>true</c> if [is not modified] [the specified cache key]; otherwise, <c>false</c>.</returns>
- private bool IsNotModified(IRequest requestContext, Guid cacheKey)
- {
- var ifNoneMatchHeader = requestContext.Headers.Get("If-None-Match");
-
- bool hasCacheKey = !cacheKey.Equals(Guid.Empty);
-
- // Validate If-None-Match
- if (hasCacheKey && !string.IsNullOrEmpty(ifNoneMatchHeader))
- {
- if (Guid.TryParse(ifNoneMatchHeader, out var ifNoneMatch)
- && cacheKey.Equals(ifNoneMatch))
- {
- return true;
- }
- }
-
- return false;
- }
/// <summary>
/// Determines whether [is not modified] [the specified if modified since].
diff --git a/MediaBrowser.Controller/Net/StaticResultOptions.cs b/MediaBrowser.Controller/Net/StaticResultOptions.cs
index a54de12be..7a179913a 100644
--- a/MediaBrowser.Controller/Net/StaticResultOptions.cs
+++ b/MediaBrowser.Controller/Net/StaticResultOptions.cs
@@ -12,8 +12,6 @@ namespace MediaBrowser.Controller.Net
public string ContentType { get; set; }
public TimeSpan? CacheDuration { get; set; }
public DateTime? DateLastModified { get; set; }
- public Guid CacheKey { get; set; }
-
public Func<Task<Stream>> ContentFactory { get; set; }
public bool IsHeadRequest { get; set; }
diff --git a/deployment/debian-package-x64/pkg-src/changelog b/deployment/debian-package-x64/pkg-src/changelog
index d5872e4a7..a4b55a4ec 100644
--- a/deployment/debian-package-x64/pkg-src/changelog
+++ b/deployment/debian-package-x64/pkg-src/changelog
@@ -1,4 +1,4 @@
-jellyfin (10.2.0~rc1) unstable; urgency=medium
+jellyfin (10.2.0~rc2) unstable; urgency=medium
* jellyfin:
* PR452 Use EF Core for Activity database
@@ -70,7 +70,11 @@ jellyfin (10.2.0~rc1) unstable; urgency=medium
* PR842 Use VAAPI-enabled ffmpeg
* PR852 Use SQLitePCL.pretty.netstandard on NuGet
* PR853 Fix poor handling of cache directories
- * PR8 rebase to latest master
+ * PR864: Add support for ZIP plugin archives
+ * PR868: Fix audio streaming via BaseProgressiveStreamingService
+ * PR869: Remove DLL support and require all packages/plugins to be zip archives
+ * PR872: Fix potential NullReferenceException
+ * PR890: Drop ETag and use Last-Modified header
* jellyfin-web:
* PR24 Add Master codeowners
* PR34 Revert "Add Master codeowners"
@@ -91,12 +95,14 @@ jellyfin (10.2.0~rc1) unstable; urgency=medium
* PR95 add display language option back
* PR112 Removed seasonal theme support
* PR116 Consolidate all strings into a single file per language
+ * PR117 Fix volume slider behavior
* PR118 Enable and fix PiP for Safari
* PR119 Make the toggle track visible on all themes
* PR121 Fix syntax error in site.js
* PR127 Change sharedcomponents module to core
+ * PR135 Make sure fallback culture is always available
- -- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 10 Feb 2019 01:18:23 -0500
+ -- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 13 Feb 2019 01:03:20 -0500
jellyfin (10.1.0-1) unstable; urgency=medium
diff --git a/deployment/debian-package-x64/pkg-src/control b/deployment/debian-package-x64/pkg-src/control
index 74bebeaf1..88d10438b 100644
--- a/deployment/debian-package-x64/pkg-src/control
+++ b/deployment/debian-package-x64/pkg-src/control
@@ -18,6 +18,11 @@ Replaces: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server
Breaks: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server
Conflicts: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server
Architecture: any
-Depends: at, libsqlite3-0, ffmpeg, libfontconfig1, libfreetype6, libssl1.0.0 | libssl1.0.2
+Depends: at,
+ libsqlite3-0,
+ ffmpeg (<7:4.1) | jellyfin-ffmpeg,
+ libfontconfig1,
+ libfreetype6,
+ libssl1.0.0 | libssl1.0.2
Description: Jellyfin is a home media server.
It is built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono. It features a REST-based api with built-in documentation to facilitate client development. We also have client libraries for our api to enable rapid development.
diff --git a/deployment/fedora-package-x64/pkg-src/jellyfin.spec b/deployment/fedora-package-x64/pkg-src/jellyfin.spec
index 343d23e91..03fc0b6ff 100644
--- a/deployment/fedora-package-x64/pkg-src/jellyfin.spec
+++ b/deployment/fedora-package-x64/pkg-src/jellyfin.spec
@@ -8,7 +8,7 @@
Name: jellyfin
Version: 10.2.0
-Release: rc1%{?dist}
+Release: rc2%{?dist}
Summary: The Free Software Media Browser
License: GPLv2
URL: https://jellyfin.media
@@ -140,7 +140,7 @@ fi
%systemd_postun_with_restart jellyfin.service
%changelog
-* Sun Feb 10 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
+* Wed Feb 13 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
- jellyfin:
- PR452 Use EF Core for Activity database
- PR535 Clean up streambuilder
@@ -211,7 +211,11 @@ fi
- PR842 Use VAAPI-enabled ffmpeg
- PR852 Use SQLitePCL.pretty.netstandard on NuGet
- PR853 Fix poor handling of cache directories
-- PR8 rebase to latest master
+- PR864 Add support for ZIP plugin archives
+- PR868 Fix audio streaming via BaseProgressiveStreamingService
+- PR869 Remove DLL support and require all packages/plugins to be zip archives
+- PR872 Fix potential NullReferenceException
+- PR890 Drop ETag and use Last-Modified header
- jellyfin-web:
- PR24 Add Master codeowners
- PR34 Revert "Add Master codeowners"
@@ -232,10 +236,12 @@ fi
- PR95 add display language option back
- PR112 Removed seasonal theme support
- PR116 Consolidate all strings into a single file per language
+- PR117 Fix volume slider behavior
- PR118 Enable and fix PiP for Safari
- PR119 Make the toggle track visible on all themes
- PR121 Fix syntax error in site.js
- PR127 Change sharedcomponents module to core
+- PR135 Make sure fallback culture is always available
* Sun Jan 20 2019 Jellyfin Packaging Team <packaging@jellyfin.org>
- jellyfin:
- PR335 Build scripts and build system consolidation.