瀏覽代碼

Switch to HeaderNames instead of hardcoded strings (and other header related fixes)

Claus Vium 6 年之前
父節點
當前提交
78742b8e4c

+ 3 - 2
Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs

@@ -15,6 +15,7 @@ using MediaBrowser.Common.Net;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Net;
 using MediaBrowser.Model.Net;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
 
 
 namespace Emby.Server.Implementations.HttpClientManager
 namespace Emby.Server.Implementations.HttpClientManager
 {
 {
@@ -179,11 +180,11 @@ namespace Emby.Server.Implementations.HttpClientManager
 
 
             foreach (var header in options.RequestHeaders)
             foreach (var header in options.RequestHeaders)
             {
             {
-                if (string.Equals(header.Key, "Accept", StringComparison.OrdinalIgnoreCase))
+                if (string.Equals(header.Key, HeaderNames.Accept, StringComparison.OrdinalIgnoreCase))
                 {
                 {
                     request.Accept = header.Value;
                     request.Accept = header.Value;
                 }
                 }
-                else if (string.Equals(header.Key, "User-Agent", StringComparison.OrdinalIgnoreCase))
+                else if (string.Equals(header.Key, HeaderNames.UserAgent, StringComparison.OrdinalIgnoreCase))
                 {
                 {
                     SetUserAgent(request, header.Value);
                     SetUserAgent(request, header.Value);
                     hasUserAgent = true;
                     hasUserAgent = true;

+ 5 - 4
Emby.Server.Implementations/HttpServer/FileWriter.cs

@@ -9,6 +9,7 @@ using Emby.Server.Implementations.IO;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
 
 
 namespace Emby.Server.Implementations.HttpServer
 namespace Emby.Server.Implementations.HttpServer
 {
 {
@@ -56,10 +57,10 @@ namespace Emby.Server.Implementations.HttpServer
             FileSystem = fileSystem;
             FileSystem = fileSystem;
             RangeHeader = rangeHeader;
             RangeHeader = rangeHeader;
 
 
-            Headers["Content-Type"] = contentType;
+            Headers[HeaderNames.ContentType] = contentType;
 
 
             TotalContentLength = fileSystem.GetFileInfo(path).Length;
             TotalContentLength = fileSystem.GetFileInfo(path).Length;
-            Headers["Accept-Ranges"] = "bytes";
+            Headers[HeaderNames.AcceptRanges] = "bytes";
 
 
             if (string.IsNullOrWhiteSpace(rangeHeader))
             if (string.IsNullOrWhiteSpace(rangeHeader))
             {
             {
@@ -97,8 +98,8 @@ namespace Emby.Server.Implementations.HttpServer
 
 
             // Content-Length is the length of what we're serving, not the original content
             // Content-Length is the length of what we're serving, not the original content
             var lengthString = RangeLength.ToString(UsCulture);
             var lengthString = RangeLength.ToString(UsCulture);
-            var rangeString = string.Format("bytes {0}-{1}/{2}", RangeStart, RangeEnd, TotalContentLength);
-            Headers["Content-Range"] = rangeString;
+            var rangeString = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}";
+            Headers[HeaderNames.ContentRange] = rangeString;
 
 
             Logger.LogInformation("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString);
             Logger.LogInformation("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString);
         }
         }

+ 18 - 23
Emby.Server.Implementations/HttpServer/HttpResultFactory.cs

@@ -75,7 +75,7 @@ namespace Emby.Server.Implementations.HttpServer
         public object GetRedirectResult(string url)
         public object GetRedirectResult(string url)
         {
         {
             var responseHeaders = new Dictionary<string, string>();
             var responseHeaders = new Dictionary<string, string>();
-            responseHeaders["Location"] = url;
+            responseHeaders[HeaderNames.Location] = url;
 
 
             var result = new HttpResult(Array.Empty<byte>(), "text/plain", HttpStatusCode.Redirect);
             var result = new HttpResult(Array.Empty<byte>(), "text/plain", HttpStatusCode.Redirect);
 
 
@@ -96,9 +96,9 @@ namespace Emby.Server.Implementations.HttpServer
                 responseHeaders = new Dictionary<string, string>();
                 responseHeaders = new Dictionary<string, string>();
             }
             }
 
 
-            if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string expires))
+            if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out string expires))
             {
             {
-                responseHeaders["Expires"] = "-1";
+                responseHeaders[HeaderNames.Expires] = "-1";
             }
             }
 
 
             AddResponseHeaders(result, responseHeaders);
             AddResponseHeaders(result, responseHeaders);
@@ -142,9 +142,9 @@ namespace Emby.Server.Implementations.HttpServer
                 responseHeaders = new Dictionary<string, string>();
                 responseHeaders = new Dictionary<string, string>();
             }
             }
 
 
-            if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string _))
+            if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out string _))
             {
             {
-                responseHeaders["Expires"] = "-1";
+                responseHeaders[HeaderNames.Expires] = "-1";
             }
             }
 
 
             AddResponseHeaders(result, responseHeaders);
             AddResponseHeaders(result, responseHeaders);
@@ -186,9 +186,9 @@ namespace Emby.Server.Implementations.HttpServer
                 responseHeaders = new Dictionary<string, string>();
                 responseHeaders = new Dictionary<string, string>();
             }
             }
 
 
-            if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string _))
+            if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out string _))
             {
             {
-                responseHeaders["Expires"] = "-1";
+                responseHeaders[HeaderNames.Expires] = "-1";
             }
             }
 
 
             AddResponseHeaders(result, responseHeaders);
             AddResponseHeaders(result, responseHeaders);
@@ -213,7 +213,7 @@ namespace Emby.Server.Implementations.HttpServer
                 responseHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
                 responseHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
             }
             }
 
 
-            responseHeaders["Expires"] = "-1";
+            responseHeaders[HeaderNames.Expires] = "-1";
 
 
             return ToOptimizedResultInternal(requestContext, result, responseHeaders);
             return ToOptimizedResultInternal(requestContext, result, responseHeaders);
         }
         }
@@ -245,7 +245,7 @@ namespace Emby.Server.Implementations.HttpServer
 
 
         private static string GetCompressionType(IRequest request)
         private static string GetCompressionType(IRequest request)
         {
         {
-            var acceptEncoding = request.Headers["Accept-Encoding"].ToString();
+            var acceptEncoding = request.Headers[HeaderNames.AcceptEncoding].ToString();
 
 
             if (string.IsNullOrEmpty(acceptEncoding))
             if (string.IsNullOrEmpty(acceptEncoding))
             {
             {
@@ -325,9 +325,9 @@ namespace Emby.Server.Implementations.HttpServer
             }
             }
 
 
             content = Compress(content, requestedCompressionType);
             content = Compress(content, requestedCompressionType);
-            responseHeaders["Content-Encoding"] = requestedCompressionType;
+            responseHeaders[HeaderNames.ContentEncoding] = requestedCompressionType;
 
 
-            responseHeaders["Vary"] = "Accept-Encoding";
+            responseHeaders[HeaderNames.Vary] = HeaderNames.AcceptEncoding;
 
 
             var contentLength = content.Length;
             var contentLength = content.Length;
 
 
@@ -537,7 +537,7 @@ namespace Emby.Server.Implementations.HttpServer
             AddCachingHeaders(responseHeaders, options.CacheDuration, false, options.DateLastModified);
             AddCachingHeaders(responseHeaders, options.CacheDuration, false, options.DateLastModified);
             AddAgeHeader(responseHeaders, options.DateLastModified);
             AddAgeHeader(responseHeaders, options.DateLastModified);
 
 
-            var rangeHeader = requestContext.Headers["Range"];
+            var rangeHeader = requestContext.Headers[HeaderNames.Range];
 
 
             if (!isHeadRequest && !string.IsNullOrEmpty(options.Path))
             if (!isHeadRequest && !string.IsNullOrEmpty(options.Path))
             {
             {
@@ -606,23 +606,23 @@ namespace Emby.Server.Implementations.HttpServer
         {
         {
             if (noCache)
             if (noCache)
             {
             {
-                responseHeaders["Cache-Control"] = "no-cache, no-store, must-revalidate";
-                responseHeaders["pragma"] = "no-cache, no-store, must-revalidate";
+                responseHeaders[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate";
+                responseHeaders[HeaderNames.Pragma] = "no-cache, no-store, must-revalidate";
                 return;
                 return;
             }
             }
 
 
             if (cacheDuration.HasValue)
             if (cacheDuration.HasValue)
             {
             {
-                responseHeaders["Cache-Control"] = "public, max-age=" + cacheDuration.Value.TotalSeconds;
+                responseHeaders[HeaderNames.CacheControl] = "public, max-age=" + cacheDuration.Value.TotalSeconds;
             }
             }
             else
             else
             {
             {
-                responseHeaders["Cache-Control"] = "public";
+                responseHeaders[HeaderNames.CacheControl] = "public";
             }
             }
 
 
             if (lastModifiedDate.HasValue)
             if (lastModifiedDate.HasValue)
             {
             {
-                responseHeaders["Last-Modified"] = lastModifiedDate.ToString();
+                responseHeaders[HeaderNames.LastModified] = lastModifiedDate.ToString();
             }
             }
         }
         }
 
 
@@ -635,7 +635,7 @@ namespace Emby.Server.Implementations.HttpServer
         {
         {
             if (lastDateModified.HasValue)
             if (lastDateModified.HasValue)
             {
             {
-                responseHeaders["Age"] = Convert.ToInt64((DateTime.UtcNow - lastDateModified.Value).TotalSeconds).ToString(CultureInfo.InvariantCulture);
+                responseHeaders[HeaderNames.Age] = Convert.ToInt64((DateTime.UtcNow - lastDateModified.Value).TotalSeconds).ToString(CultureInfo.InvariantCulture);
             }
             }
         }
         }
 
 
@@ -693,9 +693,4 @@ namespace Emby.Server.Implementations.HttpServer
             }
             }
         }
         }
     }
     }
-
-    public interface IBrotliCompressor
-    {
-        byte[] Compress(byte[] content);
-    }
 }
 }

+ 4 - 3
Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs

@@ -7,6 +7,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
 
 
 namespace Emby.Server.Implementations.HttpServer
 namespace Emby.Server.Implementations.HttpServer
 {
 {
@@ -66,8 +67,8 @@ namespace Emby.Server.Implementations.HttpServer
             this._logger = logger;
             this._logger = logger;
 
 
             ContentType = contentType;
             ContentType = contentType;
-            Headers["Content-Type"] = contentType;
-            Headers["Accept-Ranges"] = "bytes";
+            Headers[HeaderNames.ContentType] = contentType;
+            Headers[HeaderNames.AcceptRanges] = "bytes";
             StatusCode = HttpStatusCode.PartialContent;
             StatusCode = HttpStatusCode.PartialContent;
 
 
             SetRangeValues(contentLength);
             SetRangeValues(contentLength);
@@ -96,7 +97,7 @@ namespace Emby.Server.Implementations.HttpServer
             RangeLength = 1 + RangeEnd - RangeStart;
             RangeLength = 1 + RangeEnd - RangeStart;
 
 
             // Content-Length is the length of what we're serving, not the original content
             // Content-Length is the length of what we're serving, not the original content
-            Headers["Content-Range"] = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}";
+            Headers[HeaderNames.ContentRange] = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}";
 
 
             if (RangeStart > 0 && SourceStream.CanSeek)
             if (RangeStart > 0 && SourceStream.CanSeek)
             {
             {

+ 4 - 3
Emby.Server.Implementations/HttpServer/ResponseFilter.cs

@@ -3,6 +3,7 @@ using System.Globalization;
 using System.Text;
 using System.Text;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
 
 
 namespace Emby.Server.Implementations.HttpServer
 namespace Emby.Server.Implementations.HttpServer
 {
 {
@@ -44,13 +45,13 @@ namespace Emby.Server.Implementations.HttpServer
 
 
             if (dto is IHasHeaders hasHeaders)
             if (dto is IHasHeaders hasHeaders)
             {
             {
-                if (!hasHeaders.Headers.ContainsKey("Server"))
+                if (!hasHeaders.Headers.ContainsKey(HeaderNames.Server))
                 {
                 {
-                    hasHeaders.Headers["Server"] = "Microsoft-NetCore/2.0, UPnP/1.0 DLNADOC/1.50";
+                    hasHeaders.Headers[HeaderNames.Server] = "Microsoft-NetCore/2.0, UPnP/1.0 DLNADOC/1.50";
                 }
                 }
 
 
                 // Content length has to be explicitly set on on HttpListenerResponse or it won't be happy
                 // Content length has to be explicitly set on on HttpListenerResponse or it won't be happy
-                if (hasHeaders.Headers.TryGetValue("Content-Length", out string contentLength)
+                if (hasHeaders.Headers.TryGetValue(HeaderNames.ContentLength, out string contentLength)
                     && !string.IsNullOrEmpty(contentLength))
                     && !string.IsNullOrEmpty(contentLength))
                 {
                 {
                     var length = long.Parse(contentLength, UsCulture);
                     var length = long.Parse(contentLength, UsCulture);

+ 2 - 1
Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs

@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Security;
 using MediaBrowser.Controller.Security;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
+using Microsoft.Net.Http.Headers;
 
 
 namespace Emby.Server.Implementations.HttpServer.Security
 namespace Emby.Server.Implementations.HttpServer.Security
 {
 {
@@ -176,7 +177,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
 
 
             if (string.IsNullOrEmpty(auth))
             if (string.IsNullOrEmpty(auth))
             {
             {
-                auth = httpReq.Headers["Authorization"];
+                auth = httpReq.Headers[HeaderNames.Authorization];
             }
             }
 
 
             return GetAuthorization(auth);
             return GetAuthorization(auth);

+ 3 - 2
Emby.Server.Implementations/HttpServer/StreamWriter.cs

@@ -6,6 +6,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
 
 
 namespace Emby.Server.Implementations.HttpServer
 namespace Emby.Server.Implementations.HttpServer
 {
 {
@@ -52,7 +53,7 @@ namespace Emby.Server.Implementations.HttpServer
 
 
             SourceStream = source;
             SourceStream = source;
 
 
-            Headers["Content-Type"] = contentType;
+            Headers[HeaderNames.ContentType] = contentType;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -69,7 +70,7 @@ namespace Emby.Server.Implementations.HttpServer
 
 
             SourceBytes = source;
             SourceBytes = source;
 
 
-            Headers["Content-Type"] = contentType;
+            Headers[HeaderNames.ContentType] = contentType;
         }
         }
 
 
         public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken)
         public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken)

+ 3 - 2
Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs

@@ -17,6 +17,7 @@ using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.Net;
 using MediaBrowser.Model.Net;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Serialization;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
 
 
 namespace Emby.Server.Implementations.LiveTv.Listings
 namespace Emby.Server.Implementations.LiveTv.Listings
 {
 {
@@ -638,7 +639,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 #if NETSTANDARD2_0
 #if NETSTANDARD2_0
             if (Environment.OSVersion.Platform == PlatformID.Win32NT)
             if (Environment.OSVersion.Platform == PlatformID.Win32NT)
             {
             {
-                options.RequestHeaders["Accept-Encoding"] = "deflate";
+                options.RequestHeaders[HeaderNames.AcceptEncoding] = "deflate";
             }
             }
 #endif
 #endif
 
 
@@ -676,7 +677,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
 #if NETSTANDARD2_0
 #if NETSTANDARD2_0
             if (Environment.OSVersion.Platform == PlatformID.Win32NT)
             if (Environment.OSVersion.Platform == PlatformID.Win32NT)
             {
             {
-                options.RequestHeaders["Accept-Encoding"] = "deflate";
+                options.RequestHeaders[HeaderNames.AcceptEncoding] = "deflate";
             }
             }
 #endif
 #endif
 
 

+ 2 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs

@@ -19,6 +19,7 @@ using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.System;
 using MediaBrowser.Model.System;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
 
 
 namespace Emby.Server.Implementations.LiveTv.TunerHosts
 namespace Emby.Server.Implementations.LiveTv.TunerHosts
 {
 {
@@ -145,7 +146,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
             if (protocol == MediaProtocol.Http)
             if (protocol == MediaProtocol.Http)
             {
             {
                 // Use user-defined user-agent. If there isn't one, make it look like a browser.
                 // Use user-defined user-agent. If there isn't one, make it look like a browser.
-                httpHeaders["User-Agent"] = string.IsNullOrWhiteSpace(info.UserAgent) ?
+                httpHeaders[HeaderNames.UserAgent] = string.IsNullOrWhiteSpace(info.UserAgent) ?
                     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.85 Safari/537.36" :
                     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.85 Safari/537.36" :
                     info.UserAgent;
                     info.UserAgent;
             }
             }

+ 3 - 2
Emby.Server.Implementations/SocketSharp/RequestMono.cs

@@ -7,6 +7,7 @@ using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
 using Microsoft.Extensions.Primitives;
 using Microsoft.Extensions.Primitives;
+using Microsoft.Net.Http.Headers;
 
 
 namespace Emby.Server.Implementations.SocketSharp
 namespace Emby.Server.Implementations.SocketSharp
 {
 {
@@ -114,9 +115,9 @@ namespace Emby.Server.Implementations.SocketSharp
             return form;
             return form;
         }
         }
 
 
-        public string Accept => StringValues.IsNullOrEmpty(request.Headers["Accept"]) ? null : request.Headers["Accept"].ToString();
+        public string Accept => StringValues.IsNullOrEmpty(request.Headers[HeaderNames.Accept]) ? null : request.Headers[HeaderNames.Accept].ToString();
 
 
-        public string Authorization => StringValues.IsNullOrEmpty(request.Headers["Authorization"]) ? null : request.Headers["Authorization"].ToString();
+        public string Authorization => StringValues.IsNullOrEmpty(request.Headers[HeaderNames.Authorization]) ? null : request.Headers[HeaderNames.Authorization].ToString();
 
 
         protected bool validate_form { get; set; }
         protected bool validate_form { get; set; }
         protected bool checked_form { get; set; }
         protected bool checked_form { get; set; }

+ 2 - 1
MediaBrowser.Api/Images/ImageService.cs

@@ -18,6 +18,7 @@ using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
 
 
 namespace MediaBrowser.Api.Images
 namespace MediaBrowser.Api.Images
 {
 {
@@ -634,7 +635,7 @@ namespace MediaBrowser.Api.Images
 
 
             var imageResult = await _imageProcessor.ProcessImage(options).ConfigureAwait(false);
             var imageResult = await _imageProcessor.ProcessImage(options).ConfigureAwait(false);
 
 
-            headers["Vary"] = "Accept";
+            headers[HeaderNames.Vary] = HeaderNames.Accept;
 
 
             return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
             return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
             {
             {

+ 2 - 1
MediaBrowser.Api/Library/LibraryService.cs

@@ -29,6 +29,7 @@ using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Querying;
 using MediaBrowser.Model.Querying;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
 
 
 namespace MediaBrowser.Api.Library
 namespace MediaBrowser.Api.Library
 {
 {
@@ -827,7 +828,7 @@ namespace MediaBrowser.Api.Library
             var filename = (Path.GetFileName(path) ?? string.Empty).Replace("\"", string.Empty);
             var filename = (Path.GetFileName(path) ?? string.Empty).Replace("\"", string.Empty);
             if (!string.IsNullOrWhiteSpace(filename))
             if (!string.IsNullOrWhiteSpace(filename))
             {
             {
-                headers["Content-Disposition"] = "attachment; filename=\"" + filename + "\"";
+                headers[HeaderNames.ContentDisposition] = "attachment; filename=\"" + filename + "\"";
             }
             }
 
 
             return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
             return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions

+ 9 - 6
MediaBrowser.Api/LiveTv/LiveTvService.cs

@@ -24,6 +24,7 @@ using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.Querying;
 using MediaBrowser.Model.Querying;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.System;
 using MediaBrowser.Model.System;
+using Microsoft.Net.Http.Headers;
 
 
 namespace MediaBrowser.Api.LiveTv
 namespace MediaBrowser.Api.LiveTv
 {
 {
@@ -750,9 +751,10 @@ namespace MediaBrowser.Api.LiveTv
                 throw new FileNotFoundException();
                 throw new FileNotFoundException();
             }
             }
 
 
-            var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-
-            outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType(path);
+            var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
+            {
+                [HeaderNames.ContentType] = Model.Net.MimeTypes.GetMimeType(path)
+            };
 
 
             return new ProgressiveFileCopier(_fileSystem, _streamHelper, path, outputHeaders, Logger, _environment)
             return new ProgressiveFileCopier(_fileSystem, _streamHelper, path, outputHeaders, Logger, _environment)
             {
             {
@@ -772,9 +774,10 @@ namespace MediaBrowser.Api.LiveTv
 
 
             var directStreamProvider = liveStreamInfo;
             var directStreamProvider = liveStreamInfo;
 
 
-            var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-
-            outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file." + request.Container);
+            var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
+            {
+                [HeaderNames.ContentType] = Model.Net.MimeTypes.GetMimeType("file." + request.Container)
+            };
 
 
             return new ProgressiveFileCopier(directStreamProvider, _streamHelper, outputHeaders, Logger, _environment)
             return new ProgressiveFileCopier(directStreamProvider, _streamHelper, outputHeaders, Logger, _environment)
             {
             {

+ 17 - 64
MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs

@@ -17,6 +17,7 @@ using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.System;
 using MediaBrowser.Model.System;
+using Microsoft.Net.Http.Headers;
 
 
 namespace MediaBrowser.Api.Playback.Progressive
 namespace MediaBrowser.Api.Playback.Progressive
 {
 {
@@ -154,7 +155,7 @@ namespace MediaBrowser.Api.Playback.Progressive
                     var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
                     var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 
 
                     // TODO: Don't hardcode this
                     // TODO: Don't hardcode this
-                    outputHeaders["Content-Type"] = MediaBrowser.Model.Net.MimeTypes.GetMimeType("file.ts");
+                    outputHeaders[HeaderNames.ContentType] = Model.Net.MimeTypes.GetMimeType("file.ts");
 
 
                     return new ProgressiveFileCopier(state.DirectStreamProvider, outputHeaders, null, Logger, EnvironmentInfo, CancellationToken.None)
                     return new ProgressiveFileCopier(state.DirectStreamProvider, outputHeaders, null, Logger, EnvironmentInfo, CancellationToken.None)
                     {
                     {
@@ -196,9 +197,11 @@ namespace MediaBrowser.Api.Playback.Progressive
                 {
                 {
                     if (state.MediaSource.IsInfiniteStream)
                     if (state.MediaSource.IsInfiniteStream)
                     {
                     {
-                        var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+                        var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
+                        {
+                            [HeaderNames.ContentType] = contentType
+                        };
 
 
-                        outputHeaders["Content-Type"] = contentType;
 
 
                         return new ProgressiveFileCopier(FileSystem, state.MediaPath, outputHeaders, null, Logger, EnvironmentInfo, CancellationToken.None)
                         return new ProgressiveFileCopier(FileSystem, state.MediaPath, outputHeaders, null, Logger, EnvironmentInfo, CancellationToken.None)
                         {
                         {
@@ -298,16 +301,16 @@ namespace MediaBrowser.Api.Playback.Progressive
 
 
             if (trySupportSeek)
             if (trySupportSeek)
             {
             {
-                if (!string.IsNullOrWhiteSpace(Request.QueryString["Range"]))
+                if (!string.IsNullOrWhiteSpace(Request.QueryString[HeaderNames.Range]))
                 {
                 {
-                    options.RequestHeaders["Range"] = Request.QueryString["Range"];
+                    options.RequestHeaders[HeaderNames.Range] = Request.QueryString[HeaderNames.Range];
                 }
                 }
             }
             }
             var response = await HttpClient.GetResponse(options).ConfigureAwait(false);
             var response = await HttpClient.GetResponse(options).ConfigureAwait(false);
 
 
             if (trySupportSeek)
             if (trySupportSeek)
             {
             {
-                foreach (var name in new[] { "Content-Range", "Accept-Ranges" })
+                foreach (var name in new[] { HeaderNames.ContentRange, HeaderNames.AcceptRanges })
                 {
                 {
                     var val = response.Headers[name];
                     var val = response.Headers[name];
                     if (!string.IsNullOrWhiteSpace(val))
                     if (!string.IsNullOrWhiteSpace(val))
@@ -318,14 +321,7 @@ namespace MediaBrowser.Api.Playback.Progressive
             }
             }
             else
             else
             {
             {
-                responseHeaders["Accept-Ranges"] = "none";
-            }
-
-            // Seeing cases of -1 here
-            if (response.ContentLength.HasValue && response.ContentLength.Value >= 0)
-            {
-                // TODO
-                //responseHeaders["Content-Length"] = response.ContentLength.Value.ToString(UsCulture);
+                responseHeaders[HeaderNames.AcceptRanges] = "none";
             }
             }
 
 
             if (isHeadRequest)
             if (isHeadRequest)
@@ -338,7 +334,7 @@ namespace MediaBrowser.Api.Playback.Progressive
 
 
             var result = new StaticRemoteStreamWriter(response);
             var result = new StaticRemoteStreamWriter(response);
 
 
-            result.Headers["Content-Type"] = response.ContentType;
+            result.Headers[HeaderNames.ContentType] = response.ContentType;
 
 
             // Add the response headers to the result object
             // Add the response headers to the result object
             foreach (var header in responseHeaders)
             foreach (var header in responseHeaders)
@@ -362,42 +358,14 @@ namespace MediaBrowser.Api.Playback.Progressive
             // Use the command line args with a dummy playlist path
             // Use the command line args with a dummy playlist path
             var outputPath = state.OutputFilePath;
             var outputPath = state.OutputFilePath;
 
 
-            responseHeaders["Accept-Ranges"] = "none";
+            responseHeaders[HeaderNames.AcceptRanges] = "none";
 
 
             var contentType = state.GetMimeType(outputPath);
             var contentType = state.GetMimeType(outputPath);
 
 
-            // TODO: The isHeadRequest is only here because ServiceStack will add Content-Length=0 to the response
-            // What we really want to do is hunt that down and remove that
-            var contentLength = state.EstimateContentLength || isHeadRequest ? GetEstimatedContentLength(state) : null;
-
-            if (contentLength.HasValue)
-            {
-                responseHeaders["Content-Length"] = contentLength.Value.ToString(UsCulture);
-            }
-
             // Headers only
             // Headers only
             if (isHeadRequest)
             if (isHeadRequest)
             {
             {
-                var streamResult = ResultFactory.GetResult(null, new byte[] { }, contentType, responseHeaders);
-
-                var hasHeaders = streamResult as IHasHeaders;
-                if (hasHeaders != null)
-                {
-                    // TODO
-                    //if (contentLength.HasValue)
-                    //{
-                    //    hasHeaders.Headers["Content-Length"] = contentLength.Value.ToString(CultureInfo.InvariantCulture);
-                    //}
-                    //else
-                    //{
-                        if (hasHeaders.Headers.ContainsKey("Content-Length"))
-                        {
-                            hasHeaders.Headers.Remove("Content-Length");
-                        }
-                    //}
-                }
-
-                return streamResult;
+                return ResultFactory.GetResult(null, new byte[] { }, contentType, responseHeaders);
             }
             }
 
 
             var transcodingLock = ApiEntryPoint.Instance.GetTranscodingLock(outputPath);
             var transcodingLock = ApiEntryPoint.Instance.GetTranscodingLock(outputPath);
@@ -416,9 +384,11 @@ namespace MediaBrowser.Api.Playback.Progressive
                     state.Dispose();
                     state.Dispose();
                 }
                 }
 
 
-                var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+                var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
+                {
+                    [HeaderNames.ContentType] = contentType
+                };
 
 
-                outputHeaders["Content-Type"] = contentType;
 
 
                 // Add the response headers to the result object
                 // Add the response headers to the result object
                 foreach (var item in responseHeaders)
                 foreach (var item in responseHeaders)
@@ -433,22 +403,5 @@ namespace MediaBrowser.Api.Playback.Progressive
                 transcodingLock.Release();
                 transcodingLock.Release();
             }
             }
         }
         }
-
-        /// <summary>
-        /// Gets the length of the estimated content.
-        /// </summary>
-        /// <param name="state">The state.</param>
-        /// <returns>System.Nullable{System.Int64}.</returns>
-        private long? GetEstimatedContentLength(StreamState state)
-        {
-            var totalBitrate = state.TotalOutputBitrate ?? 0;
-
-            if (totalBitrate > 0 && state.RunTimeTicks.HasValue)
-            {
-                return Convert.ToInt64(totalBitrate * TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalSeconds / 8);
-            }
-
-            return null;
-        }
     }
     }
 }
 }

+ 5 - 4
MediaBrowser.Common/Net/HttpRequestOptions.cs

@@ -2,6 +2,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Threading;
 using System.Threading;
+using Microsoft.Net.Http.Headers;
 
 
 namespace MediaBrowser.Common.Net
 namespace MediaBrowser.Common.Net
 {
 {
@@ -24,8 +25,8 @@ namespace MediaBrowser.Common.Net
         /// <value>The accept header.</value>
         /// <value>The accept header.</value>
         public string AcceptHeader
         public string AcceptHeader
         {
         {
-            get => GetHeaderValue("Accept");
-            set => RequestHeaders["Accept"] = value;
+            get => GetHeaderValue(HeaderNames.Accept);
+            set => RequestHeaders[HeaderNames.Accept] = value;
         }
         }
         /// <summary>
         /// <summary>
         /// Gets or sets the cancellation token.
         /// Gets or sets the cancellation token.
@@ -45,8 +46,8 @@ namespace MediaBrowser.Common.Net
         /// <value>The user agent.</value>
         /// <value>The user agent.</value>
         public string UserAgent
         public string UserAgent
         {
         {
-            get => GetHeaderValue("User-Agent");
-            set => RequestHeaders["User-Agent"] = value;
+            get => GetHeaderValue(HeaderNames.UserAgent);
+            set => RequestHeaders[HeaderNames.UserAgent] = value;
         }
         }
 
 
         /// <summary>
         /// <summary>