public static Task <EndPointSettings> GetEndPointSettingsAsync(string clientIp, string profileId) { EndPointSettings settings = new EndPointSettings(); try { if (Profiles.ContainsKey(profileId) == true) { settings.Profile = Profiles[profileId]; } else if (profileId == NO_PROFILE) { settings.Profile = null; } else if (Profiles.ContainsKey(DLNA_DEFAULT_PROFILE_ID) == true) { settings.Profile = Profiles[DLNA_DEFAULT_PROFILE_ID]; } } catch (Exception e) { Logger.Info("DlnaMediaServer: Exception reading profile links (Text: '{0}')", e.Message); } return(Task.FromResult(settings)); }
public static Task LoadProfileLinksAsync() { try { IUserProfileDataManagement userManager = ServiceRegistration.Get <IUserProfileDataManagement>(); ISettingsManager settingsManager = ServiceRegistration.Get <ISettingsManager>(); ProfileLinkSettings profileLinks = settingsManager.Load <ProfileLinkSettings>(); //Remove deleted profiles var deletedProfiles = ProfileLinks.Where(p => !profileLinks.Links.Any(lp => lp.ClientName == p.Key)).Select(p => p.Key).ToList(); foreach (var profile in deletedProfiles) { ProfileLinks.TryRemove(profile, out _); } //Add and update profiles foreach (ProfileLink link in profileLinks.Links) { EndPointSettings settings = null; if (!ProfileLinks.TryGetValue(link.ClientName, out settings)) { settings = new EndPointSettings(); ProfileLinks.TryAdd(link.ClientName, settings); } settings.AutoProfile = false; if (Profiles.ContainsKey(link.Profile) == true) { settings.Profile = Profiles[link.Profile]; } else if (link.Profile == NO_PROFILE) { settings.Profile = null; } else if (link.Profile == AUTO_PROFILE) { //settings.Profile = null; settings.AutoProfile = true; } else if (Profiles.ContainsKey(DLNA_DEFAULT_PROFILE_ID) == true) { settings.Profile = Profiles[DLNA_DEFAULT_PROFILE_ID]; } //settings.ClientId = await userManager.CreateProfileAsync($"DLNA ({ip.ToString()})", UserProfileType.ClientProfile, ""); settings.UserId = Guid.TryParse(link.DefaultUserProfile, out Guid g) ? g : (Guid?)null; if (settings.Profile == null) { Logger.Info("DlnaMediaServer: Client: {0}, using profile: {1}", link.ClientName, NO_PROFILE); } else { Logger.Info("DlnaMediaServer: Client: {0}, using profile: {1}", link.ClientName, settings.Profile.ID); } } } catch (Exception e) { Logger.Info("DlnaMediaServer: Exception reading profile links (Text: '{0}')", e.Message); } return(Task.CompletedTask); }
public static async Task <EndPointSettings> DetectProfileAsync(IOwinRequest request) { //Lazy load profiles. Needed because of localized strings in profiles if (Profiles.Count == 0) { Logger.Info("DetectProfile: Loading profiles and links"); await LoadProfilesAsync(false); await LoadProfilesAsync(true); await LoadProfileLinksAsync(); } if (Guid.TryParse(request.Query["id"], out var clientId)) { var idLink = ProfileLinks.FirstOrDefault(l => l.Value.ClientId == clientId); if (idLink.Value != null) { return(idLink.Value); } } if (request?.RemoteIpAddress == null) { Logger.Error("DetectProfile: Couldn't find remote address!"); return(null); } IPAddress ip = ResolveIpAddress(request.RemoteIpAddress); string clientName = EndPointSettings.GetClientName(ip); // Check links if (ProfileLinks.TryGetValue(clientName, out var link)) { if (link.Profile != null) { #if DEBUG Logger.Debug("DetectProfile: IP: {0}, using: {1}", ip, link.Profile.ID); #endif return(link); } else if (link.AutoProfile == false) { #if DEBUG Logger.Debug("DetectProfile: IP: {0}, using: None", ip); #endif return(null); } } foreach (KeyValuePair <string, EndPointProfile> profile in Profiles) { var match = false; foreach (Detection detection in profile.Value.Detections) { //Check if HTTP header matches if (detection.HttpHeaders.Count > 0) { match = true; foreach (KeyValuePair <string, string> header in detection.HttpHeaders) { if (header.Value != null && (request.Headers[header.Key] == null || !Regex.IsMatch(request.Headers[header.Key], header.Value, RegexOptions.IgnoreCase))) { match = false; break; } } } // If there are Http Header conditions, but match = false, we can't fulfill the requirements anymore if (detection.HttpHeaders.Count > 0 && !match) { break; } //Check UPnP Fields if (detection.UPnPSearch.Count() > 0) { List <TrackedDevice> trackedDevices = MediaServerPlugin.Tracker.GeTrackedDevicesByIp(ip); if (trackedDevices == null || trackedDevices.Count == 0) { #if DEBUG Logger.Warn("DetectProfile: No matching Devices"); #endif break; } match = true; foreach (TrackedDevice trackedDevice in trackedDevices) { if (detection.UPnPSearch.FriendlyName != null && (trackedDevice.FriendlyName == null || !Regex.IsMatch(trackedDevice.FriendlyName, detection.UPnPSearch.FriendlyName, RegexOptions.IgnoreCase))) { match = false; #if DEBUG Logger.Debug("DetectProfile: No FriendlyName Tracked: {0}, Search: {1}", trackedDevice.FriendlyName, detection.UPnPSearch.FriendlyName); #endif break; } if (detection.UPnPSearch.ModelName != null && (trackedDevice.ModelName == null || !Regex.IsMatch(trackedDevice.ModelName, detection.UPnPSearch.ModelName, RegexOptions.IgnoreCase))) { match = false; #if DEBUG Logger.Debug("DetectProfile: No ModelName Tracked: {0}, Search: {1}", trackedDevice.ModelName, detection.UPnPSearch.ModelName); #endif break; } if (detection.UPnPSearch.ModelNumber != null && (trackedDevice.ModelNumber == null || !Regex.IsMatch(trackedDevice.ModelNumber, detection.UPnPSearch.ModelNumber, RegexOptions.IgnoreCase))) { match = false; #if DEBUG Logger.Debug("DetectProfile: No ModelNumber Tracked: {0}, Search: {1}", trackedDevice.ModelNumber, detection.UPnPSearch.ModelNumber); #endif break; } if (detection.UPnPSearch.ProductNumber != null && (trackedDevice.ProductNumber == null || !Regex.IsMatch(trackedDevice.ProductNumber, detection.UPnPSearch.ProductNumber, RegexOptions.IgnoreCase))) { match = false; #if DEBUG Logger.Debug("DetectProfile: No ProductNumber Tracked: {0}, Search: {1}", trackedDevice.ProductNumber, detection.UPnPSearch.ProductNumber); #endif break; } if (detection.UPnPSearch.Server != null && (trackedDevice.Server == null || !Regex.IsMatch(trackedDevice.Server, detection.UPnPSearch.Server, RegexOptions.IgnoreCase))) { match = false; #if DEBUG Logger.Debug("DetectProfile: No Server Tracked: {0}, Search: {1}", trackedDevice.Server, detection.UPnPSearch.Server); #endif break; } if (detection.UPnPSearch.Manufacturer != null && (trackedDevice.Manufacturer == null || !Regex.IsMatch(trackedDevice.Manufacturer, detection.UPnPSearch.Manufacturer, RegexOptions.IgnoreCase))) { match = false; #if DEBUG Logger.Debug("DetectProfile: No Manufacturer Tracked: {0}, Search: {1}", trackedDevice.Manufacturer, detection.UPnPSearch.Manufacturer); #endif break; } } } if (match) { Logger.Info("DetectProfile: Profile found => using {0}, headers={1}", profile.Value.ID, string.Join(", ", request.Headers.Select(h => h.Key + ": " + string.Join(";", h.Value)).ToArray())); var eps = await GetEndPointSettingsAsync(ip.ToString(), profile.Value.ID); if (ProfileLinks.TryAdd(clientName, eps) == false) { ProfileLinks[clientName] = eps; } else { SaveProfileLinks(); } return(eps); } } } // no match => return Default Profile Logger.Info("DetectProfile: No profile found => using {0}, headers={1}", DLNA_DEFAULT_PROFILE_ID, string.Join(", ", request.Headers.Select(h => h.Key + ": " + string.Join(";", h.Value)).ToArray())); var def = await GetEndPointSettingsAsync(ip.ToString(), DLNA_DEFAULT_PROFILE_ID); if (ProfileLinks.TryAdd(clientName, def) == false) { ProfileLinks[clientName] = def; } else { SaveProfileLinks(); } return(def); }