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

This commit is contained in:
Claus Vium 2019-03-05 19:20:28 +01:00
parent 318e0d4a24
commit 78742b8e4c
15 changed files with 82 additions and 119 deletions

View File

@ -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;

View File

@ -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); var rangeString = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}";
Headers["Content-Range"] = rangeString; 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);
} }

View File

@ -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[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate";
responseHeaders["pragma"] = "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);
}
} }

View File

@ -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[HeaderNames.ContentType] = contentType;
Headers["Accept-Ranges"] = "bytes"; 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)
{ {

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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;
} }

View File

@ -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; }

View File

@ -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
{ {

View File

@ -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

View File

@ -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); var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType(path); [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); var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file." + request.Container); [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)
{ {

View File

@ -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"; responseHeaders[HeaderNames.AcceptRanges] = "none";
}
// Seeing cases of -1 here
if (response.ContentLength.HasValue && response.ContentLength.Value >= 0)
{
// TODO
//responseHeaders["Content-Length"] = response.ContentLength.Value.ToString(UsCulture);
} }
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); return 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;
} }
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;
}
} }
} }

View File

@ -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"); get => GetHeaderValue(HeaderNames.Accept);
set => RequestHeaders["Accept"] = value; 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"); get => GetHeaderValue(HeaderNames.UserAgent);
set => RequestHeaders["User-Agent"] = value; set => RequestHeaders[HeaderNames.UserAgent] = value;
} }
/// <summary> /// <summary>