-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
151 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using UpnpSharp.Utils; | ||
|
||
namespace UpnpSharp.Ssdp | ||
{ | ||
public class SsdpService | ||
{ | ||
string baseUrl, scpdUrl; | ||
protected SsdpDeviceService serviceXml; | ||
|
||
public string Type => this.serviceXml.ServiceType; | ||
public string Id => this.serviceXml.ServiceId; | ||
public string ScpdUrl => scpdUrl; | ||
public string ControlUrl => this.serviceXml.ControlUrl; | ||
public string EventSubUrl => this.serviceXml.EventSubUrl; | ||
public string BaseUrl => baseUrl; | ||
public string? Description { get; protected set; } | ||
public Dictionary<string, string> Actions { get; protected set; } = new(); | ||
|
||
public SsdpService(string baseUrl, SsdpDeviceService service) | ||
{ | ||
this.serviceXml = service; | ||
|
||
this.baseUrl = baseUrl; | ||
this.scpdUrl = service.ScpdUrl; | ||
|
||
UrlParser baseUri = new UrlParser(baseUrl); | ||
UrlParser scpdUri = new UrlParser(scpdUrl); | ||
if (baseUri.Scheme != Uri.UriSchemeHttp) | ||
{ | ||
throw new Exception($"Unsupported url scheme: {baseUri.Scheme}"); | ||
} | ||
|
||
if (scpdUri.Scheme == Uri.UriSchemeHttp) | ||
{ | ||
if (scpdUri.Host != baseUri.Host) throw new Exception($"Host doesn't match: \"{scpdUri.Host}\" and \"{baseUri.Host}\""); | ||
} | ||
else if (string.IsNullOrWhiteSpace(scpdUri.Scheme)) | ||
{ | ||
if (scpdUrl.StartsWith('/')) this.scpdUrl = $"{baseUri.Scheme}://{baseUri.Host}:{baseUri.Port}{scpdUrl}"; | ||
else this.scpdUrl = $"{baseUri.Scheme}://{baseUri.Host}:{baseUri.Port}/{scpdUri.ToString()}"; | ||
} | ||
else throw new Exception($"Unsupported url scheme: {scpdUri.Scheme}"); | ||
|
||
RequestDescription().Wait(); | ||
RequestStateVariables(); | ||
RequestActions(); | ||
} | ||
|
||
private void RequestActions() | ||
{ | ||
Console.WriteLine(this.Description); | ||
} | ||
|
||
private void RequestStateVariables() | ||
{ | ||
return; | ||
} | ||
|
||
public async Task RequestDescription() | ||
{ | ||
HttpClient client = new HttpClient(); | ||
var response = await client.GetAsync(this.ScpdUrl); | ||
if (!response.IsSuccessStatusCode) | ||
{ | ||
this.Description = null; | ||
throw new Exception($"Unsuccessful request: 2xx or 3xx status code expected, got {response.StatusCode}."); | ||
} | ||
this.Description = await response.Content.ReadAsStringAsync(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
using System; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace UpnpSharp.Utils | ||
{ | ||
public class UrlParser | ||
{ | ||
public string Scheme { get; protected set; } = string.Empty; | ||
public string Host { get; protected set; } = string.Empty; | ||
public ushort Port { get; protected set; } = 0; | ||
public string Path { get; protected set; } = string.Empty; | ||
|
||
public UrlParser(string uri) | ||
{ | ||
if (string.IsNullOrEmpty(uri)) | ||
throw new ArgumentNullException(nameof(uri), "The URI cannot be null or empty."); | ||
|
||
ParseUri(uri); | ||
} | ||
|
||
private void ParseUri(string uri) | ||
{ | ||
var schemeMatch = Regex.Match(uri, @"^(?<scheme>[a-zA-Z][a-zA-Z0-9+.-]*):"); | ||
if (schemeMatch.Success) | ||
{ | ||
Scheme = schemeMatch.Groups["scheme"].Value; | ||
uri = uri.Substring(Scheme.Length + 1); // Remove scheme from uri | ||
} | ||
|
||
var authorityMatch = Regex.Match(uri, @"^//(?<authority>[^/]+)"); | ||
if (authorityMatch.Success) | ||
{ | ||
var authority = authorityMatch.Groups["authority"].Value; | ||
uri = uri.Substring(authority.Length + 2); // Remove authority from uri | ||
|
||
var hostPortMatch = Regex.Match(authority, @"^(?<host>[^:]+)(:(?<port>\d+))?$"); | ||
if (hostPortMatch.Success) | ||
{ | ||
Host = hostPortMatch.Groups["host"].Value; | ||
Port = hostPortMatch.Groups["port"].Success ? ushort.Parse(hostPortMatch.Groups["port"].Value) : GetDefaultPort(Scheme); | ||
} | ||
} | ||
|
||
Path = uri; | ||
} | ||
|
||
private ushort GetDefaultPort(string scheme) | ||
{ | ||
switch (scheme?.ToLower()) | ||
{ | ||
case "http": | ||
return 80; | ||
case "https": | ||
return 443; | ||
case "ftp": | ||
return 21; | ||
default: | ||
return 0; | ||
} | ||
} | ||
} | ||
} |