aboutsummaryrefslogtreecommitdiff
path: root/Emby.Dlna/PlayTo/SsdpHttpClient.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Dlna/PlayTo/SsdpHttpClient.cs')
-rw-r--r--Emby.Dlna/PlayTo/SsdpHttpClient.cs165
1 files changed, 71 insertions, 94 deletions
diff --git a/Emby.Dlna/PlayTo/SsdpHttpClient.cs b/Emby.Dlna/PlayTo/SsdpHttpClient.cs
index 1ad99fac5..cade7b4c2 100644
--- a/Emby.Dlna/PlayTo/SsdpHttpClient.cs
+++ b/Emby.Dlna/PlayTo/SsdpHttpClient.cs
@@ -1,13 +1,17 @@
+#nullable disable
+
+#pragma warning disable CS1591
+
using System;
using System.Globalization;
-using System.IO;
+using System.Net.Http;
+using System.Net.Mime;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Emby.Dlna.Common;
using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Configuration;
namespace Emby.Dlna.PlayTo
{
@@ -16,35 +20,36 @@ namespace Emby.Dlna.PlayTo
private const string USERAGENT = "Microsoft-Windows/6.2 UPnP/1.0 Microsoft-DLNA DLNADOC/1.50";
private const string FriendlyName = "Jellyfin";
- private readonly IHttpClient _httpClient;
- private readonly IServerConfigurationManager _config;
+ private readonly IHttpClientFactory _httpClientFactory;
- public SsdpHttpClient(IHttpClient httpClient, IServerConfigurationManager config)
+ public SsdpHttpClient(IHttpClientFactory httpClientFactory)
{
- _httpClient = httpClient;
- _config = config;
+ _httpClientFactory = httpClientFactory;
}
- public async Task<XDocument> SendCommandAsync(string baseUrl,
+ public async Task<XDocument> SendCommandAsync(
+ string baseUrl,
DeviceService service,
string command,
string postData,
- bool logRequest = true,
- string header = null)
+ string header = null,
+ CancellationToken cancellationToken = default)
{
- var cancellationToken = CancellationToken.None;
-
- using (var response = await PostSoapDataAsync(NormalizeServiceUrl(baseUrl, service.ControlUrl), "\"" + service.ServiceType + "#" + command + "\"", postData, header, logRequest, cancellationToken)
- .ConfigureAwait(false))
- {
- using (var stream = response.Content)
- {
- using (var reader = new StreamReader(stream, Encoding.UTF8))
- {
- return XDocument.Parse(reader.ReadToEnd(), LoadOptions.PreserveWhitespace);
- }
- }
- }
+ var url = NormalizeServiceUrl(baseUrl, service.ControlUrl);
+ using var response = await PostSoapDataAsync(
+ url,
+ $"\"{service.ServiceType}#{command}\"",
+ postData,
+ header,
+ cancellationToken)
+ .ConfigureAwait(false);
+ response.EnsureSuccessStatusCode();
+
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
+ return await XDocument.LoadAsync(
+ stream,
+ LoadOptions.None,
+ cancellationToken).ConfigureAwait(false);
}
private static string NormalizeServiceUrl(string baseUrl, string serviceUrl)
@@ -55,110 +60,82 @@ namespace Emby.Dlna.PlayTo
return serviceUrl;
}
- if (!serviceUrl.StartsWith("/"))
+ if (!serviceUrl.StartsWith('/'))
+ {
serviceUrl = "/" + serviceUrl;
+ }
return baseUrl + serviceUrl;
}
- private readonly CultureInfo _usCulture = new CultureInfo("en-US");
-
- public async Task SubscribeAsync(string url,
+ public async Task SubscribeAsync(
+ string url,
string ip,
int port,
string localIp,
int eventport,
int timeOut = 3600)
{
- var options = new HttpRequestOptions
- {
- Url = url,
- UserAgent = USERAGENT,
- LogErrorResponseBody = true,
- BufferContent = false,
-
- // The periodic requests may keep some devices awake
- LogRequestAsDebug = true
- };
-
- options.RequestHeaders["HOST"] = ip + ":" + port.ToString(_usCulture);
- options.RequestHeaders["CALLBACK"] = "<" + localIp + ":" + eventport.ToString(_usCulture) + ">";
- options.RequestHeaders["NT"] = "upnp:event";
- options.RequestHeaders["TIMEOUT"] = "Second-" + timeOut.ToString(_usCulture);
-
- using (await _httpClient.SendAsync(options, "SUBSCRIBE").ConfigureAwait(false))
- {
-
- }
+ using var options = new HttpRequestMessage(new HttpMethod("SUBSCRIBE"), url);
+ options.Headers.UserAgent.ParseAdd(USERAGENT);
+ options.Headers.TryAddWithoutValidation("HOST", ip + ":" + port.ToString(CultureInfo.InvariantCulture));
+ options.Headers.TryAddWithoutValidation("CALLBACK", "<" + localIp + ":" + eventport.ToString(CultureInfo.InvariantCulture) + ">");
+ options.Headers.TryAddWithoutValidation("NT", "upnp:event");
+ options.Headers.TryAddWithoutValidation("TIMEOUT", "Second-" + timeOut.ToString(CultureInfo.InvariantCulture));
+
+ using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
+ .SendAsync(options, HttpCompletionOption.ResponseHeadersRead)
+ .ConfigureAwait(false);
+ response.EnsureSuccessStatusCode();
}
public async Task<XDocument> GetDataAsync(string url, CancellationToken cancellationToken)
{
- var options = new HttpRequestOptions
+ using var options = new HttpRequestMessage(HttpMethod.Get, url);
+ options.Headers.UserAgent.ParseAdd(USERAGENT);
+ options.Headers.TryAddWithoutValidation("FriendlyName.DLNA.ORG", FriendlyName);
+ using var response = await _httpClientFactory.CreateClient(NamedClient.Default).SendAsync(options, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+ response.EnsureSuccessStatusCode();
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
+ try
{
- Url = url,
- UserAgent = USERAGENT,
- LogErrorResponseBody = true,
- BufferContent = false,
-
- // The periodic requests may keep some devices awake
- LogRequestAsDebug = true,
-
- CancellationToken = cancellationToken
- };
-
- options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName;
-
- using (var response = await _httpClient.SendAsync(options, "GET").ConfigureAwait(false))
+ return await XDocument.LoadAsync(
+ stream,
+ LoadOptions.None,
+ cancellationToken).ConfigureAwait(false);
+ }
+ catch
{
- using (var stream = response.Content)
- {
- using (var reader = new StreamReader(stream, Encoding.UTF8))
- {
- return XDocument.Parse(reader.ReadToEnd(), LoadOptions.PreserveWhitespace);
- }
- }
+ return null;
}
}
- private Task<HttpResponseInfo> PostSoapDataAsync(string url,
+ private async Task<HttpResponseMessage> PostSoapDataAsync(
+ string url,
string soapAction,
string postData,
string header,
- bool logRequest,
CancellationToken cancellationToken)
{
- if (!soapAction.StartsWith("\""))
- soapAction = "\"" + soapAction + "\"";
-
- var options = new HttpRequestOptions
+ if (soapAction[0] != '\"')
{
- Url = url,
- UserAgent = USERAGENT,
- LogRequest = logRequest || _config.GetDlnaConfiguration().EnableDebugLog,
- LogErrorResponseBody = true,
- BufferContent = false,
-
- // The periodic requests may keep some devices awake
- LogRequestAsDebug = true,
-
- CancellationToken = cancellationToken
- };
+ soapAction = $"\"{soapAction}\"";
+ }
- options.RequestHeaders["SOAPAction"] = soapAction;
- options.RequestHeaders["Pragma"] = "no-cache";
- options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName;
+ using var options = new HttpRequestMessage(HttpMethod.Post, url);
+ options.Headers.UserAgent.ParseAdd(USERAGENT);
+ options.Headers.TryAddWithoutValidation("SOAPACTION", soapAction);
+ options.Headers.TryAddWithoutValidation("Pragma", "no-cache");
+ options.Headers.TryAddWithoutValidation("FriendlyName.DLNA.ORG", FriendlyName);
if (!string.IsNullOrEmpty(header))
{
- options.RequestHeaders["contentFeatures.dlna.org"] = header;
+ options.Headers.TryAddWithoutValidation("contentFeatures.dlna.org", header);
}
- options.RequestContentType = "text/xml";
- options.AppendCharsetToMimeType = true;
- options.RequestContent = postData;
+ options.Content = new StringContent(postData, Encoding.UTF8, MediaTypeNames.Text.Xml);
- return _httpClient.Post(options);
+ return await _httpClientFactory.CreateClient(NamedClient.Default).SendAsync(options, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
}
}
}