diff options
Diffstat (limited to 'Emby.Server.Implementations')
4 files changed, 65 insertions, 91 deletions
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 9297362f9..a9ce51324 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -710,13 +710,6 @@ namespace Emby.Server.Implementations.HttpServer Summary = route.Summary }); - routes.Add(new RouteAttribute(NormalizeRoutePath(route.Path), route.Verbs) - { - Notes = route.Notes, - Priority = route.Priority, - Summary = route.Summary - }); - routes.Add(new RouteAttribute(DoubleNormalizeEmbyRoutePath(route.Path), route.Verbs) { Notes = route.Notes, @@ -773,16 +766,6 @@ namespace Emby.Server.Implementations.HttpServer return "emby/emby/" + path; } - private string NormalizeRoutePath(string path) - { - if (path.StartsWith("/", StringComparison.OrdinalIgnoreCase)) - { - return "/mediabrowser" + path; - } - - return "mediabrowser/" + path; - } - private bool _disposed; private readonly object _disposeLock = new object(); protected virtual void Dispose(bool disposing) diff --git a/Emby.Server.Implementations/Services/ServiceController.cs b/Emby.Server.Implementations/Services/ServiceController.cs index c3970b22f..4dc14a193 100644 --- a/Emby.Server.Implementations/Services/ServiceController.cs +++ b/Emby.Server.Implementations/Services/ServiceController.cs @@ -75,11 +75,7 @@ namespace Emby.Server.Implementations.Services var attrs = appHost.GetRouteAttributes(requestType); foreach (RouteAttribute attr in attrs) { - var restPath = new RestPath(appHost.CreateInstance, appHost.GetParseFn, requestType, attr.Path, attr.Verbs, attr.Summary, attr.Notes); - - if (!restPath.IsValid) - throw new NotSupportedException(string.Format( - "RestPath '{0}' on Type '{1}' is not Valid", attr.Path, requestType.GetMethodName())); + var restPath = new RestPath(appHost.CreateInstance, appHost.GetParseFn, requestType, attr.Path, attr.Verbs, attr.Summary); RegisterRestPath(restPath); } @@ -92,8 +88,7 @@ namespace Emby.Server.Implementations.Services if (!restPath.Path.StartsWith("/")) throw new ArgumentException(string.Format("Route '{0}' on '{1}' must start with a '/'", restPath.Path, restPath.RequestType.GetMethodName())); if (restPath.Path.IndexOfAny(InvalidRouteChars) != -1) - throw new ArgumentException(string.Format("Route '{0}' on '{1}' contains invalid chars. " + - "See https://github.com/ServiceStack/ServiceStack/wiki/Routing for info on valid routes.", restPath.Path, restPath.RequestType.GetMethodName())); + throw new ArgumentException(string.Format("Route '{0}' on '{1}' contains invalid chars. ", restPath.Path, restPath.RequestType.GetMethodName())); List<RestPath> pathsAtFirstMatch; if (!RestPathMap.TryGetValue(restPath.FirstMatchHashKey, out pathsAtFirstMatch)) diff --git a/Emby.Server.Implementations/Services/ServiceExec.cs b/Emby.Server.Implementations/Services/ServiceExec.cs index fa9e26f28..7971c6781 100644 --- a/Emby.Server.Implementations/Services/ServiceExec.cs +++ b/Emby.Server.Implementations/Services/ServiceExec.cs @@ -11,7 +11,7 @@ namespace Emby.Server.Implementations.Services { public static class ServiceExecExtensions { - public static HashSet<string> AllVerbs = new HashSet<string>(new[] { + public static string[] AllVerbs = new[] { "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT", // RFC 2616 "PROPFIND", "PROPPATCH", "MKCOL", "COPY", "MOVE", "LOCK", "UNLOCK", // RFC 2518 "VERSION-CONTROL", "REPORT", "CHECKOUT", "CHECKIN", "UNCHECKOUT", @@ -22,7 +22,9 @@ namespace Emby.Server.Implementations.Services "SEARCH", // https://datatracker.ietf.org/doc/draft-reschke-webdav-search/ "BCOPY", "BDELETE", "BMOVE", "BPROPFIND", "BPROPPATCH", "NOTIFY", "POLL", "SUBSCRIBE", "UNSUBSCRIBE" - }); + }; + + public static HashSet<string> AllVerbsSet = new HashSet<string>(AllVerbs); public static List<MethodInfo> GetActions(this Type serviceType) { diff --git a/Emby.Server.Implementations/Services/ServicePath.cs b/Emby.Server.Implementations/Services/ServicePath.cs index da5e74f1f..df5d71374 100644 --- a/Emby.Server.Implementations/Services/ServicePath.cs +++ b/Emby.Server.Implementations/Services/ServicePath.cs @@ -21,8 +21,6 @@ namespace Emby.Server.Implementations.Services readonly bool[] componentsWithSeparators; private readonly string restPath; - private readonly string allowedVerbs; - private readonly bool allowsAllVerbs; public bool IsWildCardPath { get; private set; } private readonly string[] literalsToMatch; @@ -46,15 +44,7 @@ namespace Emby.Server.Implementations.Services /// </summary> public int TotalComponentsCount { get; set; } - public string[] Verbs - { - get - { - return allowsAllVerbs - ? new[] { "ANY" } - : AllowedVerbs.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); - } - } + public string[] Verbs { get; private set; } public Type RequestType { get; private set; } @@ -62,19 +52,11 @@ namespace Emby.Server.Implementations.Services public string Summary { get; private set; } - public string Notes { get; private set; } - - public bool AllowsAllVerbs { get { return this.allowsAllVerbs; } } - - public string AllowedVerbs { get { return this.allowedVerbs; } } - public int Priority { get; set; } //passed back to RouteAttribute public static string[] GetPathPartsForMatching(string pathInfo) { - var parts = pathInfo.ToLower().Split(PathSeperatorChar) - .Where(x => !String.IsNullOrEmpty(x)).ToArray(); - return parts; + return pathInfo.ToLower().Split(new[] { PathSeperatorChar }, StringSplitOptions.RemoveEmptyEntries); } public static List<string> GetFirstMatchHashKeys(string[] pathPartsForMatching) @@ -109,18 +91,13 @@ namespace Emby.Server.Implementations.Services return list; } - public RestPath(Func<Type, object> createInstanceFn, Func<Type, Func<string, object>> getParseFn, Type requestType, string path, string verbs, string summary = null, string notes = null) + public RestPath(Func<Type, object> createInstanceFn, Func<Type, Func<string, object>> getParseFn, Type requestType, string path, string verbs, string summary = null) { this.RequestType = requestType; this.Summary = summary; - this.Notes = notes; this.restPath = path; - this.allowsAllVerbs = verbs == null || String.Equals(verbs, WildCard, StringComparison.OrdinalIgnoreCase); - if (!this.allowsAllVerbs) - { - this.allowedVerbs = verbs.ToUpper(); - } + this.Verbs = string.IsNullOrWhiteSpace(verbs) ? ServiceExecExtensions.AllVerbs : verbs.ToUpper().Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries); var componentsList = new List<string>(); @@ -153,7 +130,6 @@ namespace Emby.Server.Implementations.Services this.PathComponentsCount = this.componentsWithSeparators.Length; string firstLiteralMatch = null; - var sbHashKey = new StringBuilder(); for (var i = 0; i < components.Length; i++) { var component = components[i]; @@ -172,7 +148,6 @@ namespace Emby.Server.Implementations.Services else { this.literalsToMatch[i] = component.ToLower(); - sbHashKey.Append(i + PathSeperatorChar.ToString() + this.literalsToMatch); if (firstLiteralMatch == null) { @@ -198,9 +173,6 @@ namespace Emby.Server.Implementations.Services ? this.PathComponentsCount + PathSeperator + firstLiteralMatch : WildCardChar + PathSeperator + firstLiteralMatch; - this.IsValid = sbHashKey.Length > 0; - this.UniqueMatchHashKey = sbHashKey.ToString(); - this.typeDeserializer = new StringMapTypeDeserializer(createInstanceFn, getParseFn, this.RequestType); RegisterCaseInsenstivePropertyNameMappings(); } @@ -220,26 +192,46 @@ namespace Emby.Server.Implementations.Services }; - private static List<Type> _excludeTypes = new List<Type> { typeof(Stream) }; + private static Type excludeType = typeof(Stream); - internal static PropertyInfo[] GetSerializableProperties(Type type) + internal static List<PropertyInfo> GetSerializableProperties(Type type) { - var properties = GetPublicProperties(type); - var readableProperties = properties.Where(x => x.GetMethod != null); + var list = new List<PropertyInfo>(); + var props = GetPublicProperties(type); - // else return those properties that are not decorated with IgnoreDataMember - return readableProperties - .Where(prop => prop.GetCustomAttributes(true) - .All(attr => + foreach (var prop in props) + { + if (prop.GetMethod == null) + { + continue; + } + + if (excludeType == prop.PropertyType) + { + continue; + } + + var ignored = false; + foreach (var attr in prop.GetCustomAttributes(true)) + { + if (IgnoreAttributesNamed.Contains(attr.GetType().Name)) { - var name = attr.GetType().Name; - return !IgnoreAttributesNamed.Contains(name); - })) - .Where(prop => !_excludeTypes.Contains(prop.PropertyType)) - .ToArray(); + ignored = true; + break; + } + } + + if (!ignored) + { + list.Add(prop); + } + } + + // else return those properties that are not decorated with IgnoreDataMember + return list; } - private static PropertyInfo[] GetPublicProperties(Type type) + private static List<PropertyInfo> GetPublicProperties(Type type) { if (type.GetTypeInfo().IsInterface) { @@ -269,12 +261,19 @@ namespace Emby.Server.Implementations.Services propertyInfos.InsertRange(0, newPropertyInfos); } - return propertyInfos.ToArray(propertyInfos.Count); + return propertyInfos; } - return GetTypesPublicProperties(type) - .Where(t => t.GetIndexParameters().Length == 0) // ignore indexed properties - .ToArray(); + var list = new List<PropertyInfo>(); + + foreach (var t in GetTypesPublicProperties(type)) + { + if (t.GetIndexParameters().Length == 0) + { + list.Add(t); + } + } + return list; } private static PropertyInfo[] GetTypesPublicProperties(Type subType) @@ -289,16 +288,11 @@ namespace Emby.Server.Implementations.Services return pis.ToArray(pis.Count); } - - public bool IsValid { get; set; } - /// <summary> /// Provide for quick lookups based on hashes that can be determined from a request url /// </summary> public string FirstMatchHashKey { get; private set; } - public string UniqueMatchHashKey { get; private set; } - private readonly StringMapTypeDeserializer typeDeserializer; private readonly Dictionary<string, string> propertyNamesMap = new Dictionary<string, string>(); @@ -321,8 +315,14 @@ namespace Emby.Server.Implementations.Services score += Math.Max((10 - VariableArgsCount), 1) * 100; //Exact verb match is better than ANY - var exactVerb = String.Equals(httpMethod, AllowedVerbs, StringComparison.OrdinalIgnoreCase); - score += exactVerb ? 10 : 1; + if (Verbs.Length == 1 && string.Equals(httpMethod, Verbs[0], StringComparison.OrdinalIgnoreCase)) + { + score += 10; + } + else + { + score += 1; + } return score; } @@ -346,7 +346,7 @@ namespace Emby.Server.Implementations.Services return false; } - if (!this.allowsAllVerbs && !StringContains(this.allowedVerbs, httpMethod)) + if (!Verbs.Contains(httpMethod, StringComparer.OrdinalIgnoreCase)) { //logger.Info("allowsAllVerbs mismatch for {0} for {1} allowedverbs {2}", httpMethod, string.Join("/", withPathInfoParts), this.allowedVerbs); return false; @@ -457,8 +457,7 @@ namespace Emby.Server.Implementations.Services public object CreateRequest(string pathInfo, Dictionary<string, string> queryStringAndFormData, object fromInstance) { - var requestComponents = pathInfo.Split(PathSeperatorChar) - .Where(x => !String.IsNullOrEmpty(x)).ToArray(); + var requestComponents = pathInfo.Split(new[] { PathSeperatorChar }, StringSplitOptions.RemoveEmptyEntries); ExplodeComponents(ref requestComponents); @@ -555,10 +554,5 @@ namespace Emby.Server.Implementations.Services return this.typeDeserializer.PopulateFromMap(fromInstance, requestKeyValuesMap); } - - public override int GetHashCode() - { - return UniqueMatchHashKey.GetHashCode(); - } } }
\ No newline at end of file |
