diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs index 0dd4d4ca5..0e6083773 100644 --- a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs +++ b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs @@ -83,7 +83,16 @@ namespace Emby.Server.Implementations.HttpClientManager var request = new HttpRequestMessage(method, url); - AddRequestHeaders(request, options); + foreach (var header in options.RequestHeaders) + { + request.Headers.TryAddWithoutValidation(header.Key, header.Value); + } + + if (options.EnableDefaultUserAgent + && !request.Headers.TryGetValues(HeaderNames.UserAgent, out _)) + { + request.Headers.Add(HeaderNames.UserAgent, _defaultUserAgentFn()); + } switch (options.DecompressionMethod) { @@ -121,26 +130,6 @@ namespace Emby.Server.Implementations.HttpClientManager return request; } - private void AddRequestHeaders(HttpRequestMessage request, HttpRequestOptions options) - { - var hasUserAgent = false; - - foreach (var header in options.RequestHeaders) - { - if (string.Equals(header.Key, HeaderNames.UserAgent, StringComparison.OrdinalIgnoreCase)) - { - hasUserAgent = true; - } - - request.Headers.Add(header.Key, header.Value); - } - - if (!hasUserAgent && options.EnableDefaultUserAgent) - { - request.Headers.Add(HeaderNames.UserAgent, _defaultUserAgentFn()); - } - } - /// /// Gets the response internal. /// diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 17aa6b23a..8c4ccfa22 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -956,7 +956,10 @@ namespace MediaBrowser.Api.Playback if (string.Equals(GetHeader("getMediaInfo.sec"), "1", StringComparison.OrdinalIgnoreCase)) { var ms = TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalMilliseconds; - responseHeaders["MediaInfo.sec"] = string.Format("SEC_Duration={0};", Convert.ToInt32(ms).ToString(CultureInfo.InvariantCulture)); + responseHeaders["MediaInfo.sec"] = string.Format( + CultureInfo.InvariantCulture, + "SEC_Duration={0};", + Convert.ToInt32(ms)); } if (!isStaticallyStreamed && profile != null) @@ -974,8 +977,7 @@ namespace MediaBrowser.Api.Playback if (state.VideoRequest == null) { - responseHeaders["contentFeatures.dlna.org"] = new ContentFeatureBuilder(profile) - .BuildAudioHeader( + responseHeaders["contentFeatures.dlna.org"] = new ContentFeatureBuilder(profile).BuildAudioHeader( state.OutputContainer, audioCodec, state.OutputAudioBitrate, @@ -984,15 +986,13 @@ namespace MediaBrowser.Api.Playback state.OutputAudioBitDepth, isStaticallyStreamed, state.RunTimeTicks, - state.TranscodeSeekInfo - ); + state.TranscodeSeekInfo); } else { var videoCodec = state.ActualOutputVideoCodec; - responseHeaders["contentFeatures.dlna.org"] = new ContentFeatureBuilder(profile) - .BuildVideoHeader( + responseHeaders["contentFeatures.dlna.org"] = new ContentFeatureBuilder(profile).BuildVideoHeader( state.OutputContainer, videoCodec, audioCodec, @@ -1014,9 +1014,7 @@ namespace MediaBrowser.Api.Playback state.TargetVideoStreamCount, state.TargetAudioStreamCount, state.TargetVideoCodecTag, - state.IsTargetAVC - - ).FirstOrDefault() ?? string.Empty; + state.IsTargetAVC).FirstOrDefault() ?? string.Empty; } } @@ -1025,8 +1023,16 @@ namespace MediaBrowser.Api.Playback var runtimeSeconds = TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalSeconds.ToString(CultureInfo.InvariantCulture); var startSeconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds.ToString(CultureInfo.InvariantCulture); - responseHeaders["TimeSeekRange.dlna.org"] = string.Format("npt={0}-{1}/{1}", startSeconds, runtimeSeconds); - responseHeaders["X-AvailableSeekRange"] = string.Format("1 npt={0}-{1}", startSeconds, runtimeSeconds); + responseHeaders["TimeSeekRange.dlna.org"] = string.Format( + CultureInfo.InvariantCulture, + "npt={0}-{1}/{1}", + startSeconds, + runtimeSeconds); + responseHeaders["X-AvailableSeekRange"] = string.Format( + CultureInfo.InvariantCulture, + "1 npt={0}-{1}", + startSeconds, + runtimeSeconds); } } } diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index c15681654..97c1a7a49 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -280,18 +280,24 @@ namespace MediaBrowser.Api.Playback.Progressive /// if set to true [is head request]. /// The cancellation token source. /// Task{System.Object}. - private async Task GetStaticRemoteStreamResult(StreamState state, Dictionary responseHeaders, bool isHeadRequest, CancellationTokenSource cancellationTokenSource) + private async Task GetStaticRemoteStreamResult( + StreamState state, + Dictionary responseHeaders, + bool isHeadRequest, + CancellationTokenSource cancellationTokenSource) { - state.RemoteHttpHeaders.TryGetValue(HeaderNames.UserAgent, out var useragent); - var options = new HttpRequestOptions { Url = state.MediaPath, - UserAgent = useragent, BufferContent = false, CancellationToken = cancellationTokenSource.Token }; + if (state.RemoteHttpHeaders.TryGetValue(HeaderNames.UserAgent, out var useragent)) + { + options.UserAgent = useragent; + } + var response = await HttpClient.GetResponse(options).ConfigureAwait(false); responseHeaders[HeaderNames.AcceptRanges] = "none"; @@ -306,7 +312,7 @@ namespace MediaBrowser.Api.Playback.Progressive { using (response) { - return ResultFactory.GetResult(null, new byte[] { }, response.ContentType, responseHeaders); + return ResultFactory.GetResult(null, Array.Empty(), response.ContentType, responseHeaders); } } diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 963091673..841205d0c 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -168,9 +168,7 @@ namespace MediaBrowser.Controller.MediaEncoding /// System.String. public string GetUserAgentParam(EncodingJobInfo state) { - state.RemoteHttpHeaders.TryGetValue("User-Agent", out string useragent); - - if (!string.IsNullOrEmpty(useragent)) + if (state.RemoteHttpHeaders.TryGetValue("User-Agent", out string useragent)) { return "-user_agent \"" + useragent + "\""; } diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs index e52951dd0..2333fa7a0 100644 --- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs +++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Model.Dlna @@ -81,17 +82,20 @@ namespace MediaBrowser.Model.Dlna // flagValue = flagValue | DlnaFlags.TimeBasedSeek; //} - string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", - DlnaMaps.FlagsToString(flagValue)); + string dlnaflags = string.Format( + CultureInfo.InvariantCulture, + ";DLNA.ORG_FLAGS={0}", + DlnaMaps.FlagsToString(flagValue)); - ResponseProfile mediaProfile = _profile.GetAudioMediaProfile(container, + ResponseProfile mediaProfile = _profile.GetAudioMediaProfile( + container, audioCodec, audioChannels, audioBitrate, audioSampleRate, audioBitDepth); - string orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; + string orgPn = mediaProfile?.OrgPn; if (string.IsNullOrEmpty(orgPn)) {