diff options
Diffstat (limited to 'Emby.Server.Implementations/Services')
4 files changed, 57 insertions, 26 deletions
diff --git a/Emby.Server.Implementations/Services/RequestHelper.cs b/Emby.Server.Implementations/Services/RequestHelper.cs index 8cfc3d089..7538d3102 100644 --- a/Emby.Server.Implementations/Services/RequestHelper.cs +++ b/Emby.Server.Implementations/Services/RequestHelper.cs @@ -1,40 +1,40 @@ using System; using System.IO; -using ServiceStack; +using Emby.Server.Implementations.HttpServer; namespace Emby.Server.Implementations.Services { public class RequestHelper { - public static Func<Type, Stream, object> GetRequestReader(string contentType) + public static Func<Type, Stream, object> GetRequestReader(HttpListenerHost host, string contentType) { switch (GetContentTypeWithoutEncoding(contentType)) { case "application/xml": case "text/xml": case "text/xml; charset=utf-8": //"text/xml; charset=utf-8" also matches xml - return ServiceStackHost.Instance.DeserializeXml; + return host.DeserializeXml; case "application/json": case "text/json": - return ServiceStackHost.Instance.DeserializeJson; + return host.DeserializeJson; } return null; } - public static Action<object, Stream> GetResponseWriter(string contentType) + public static Action<object, Stream> GetResponseWriter(HttpListenerHost host, string contentType) { switch (GetContentTypeWithoutEncoding(contentType)) { case "application/xml": case "text/xml": case "text/xml; charset=utf-8": //"text/xml; charset=utf-8" also matches xml - return (o, s) => ServiceStackHost.Instance.SerializeToXml(o, s); + return host.SerializeToXml; case "application/json": case "text/json": - return (o, s) => ServiceStackHost.Instance.SerializeToJson(o, s); + return host.SerializeToJson; } return null; diff --git a/Emby.Server.Implementations/Services/ResponseHelper.cs b/Emby.Server.Implementations/Services/ResponseHelper.cs index 1af70ad7f..d4ce1cabf 100644 --- a/Emby.Server.Implementations/Services/ResponseHelper.cs +++ b/Emby.Server.Implementations/Services/ResponseHelper.cs @@ -5,6 +5,7 @@ using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; +using Emby.Server.Implementations.HttpServer; using MediaBrowser.Model.Services; namespace Emby.Server.Implementations.Services @@ -161,7 +162,7 @@ namespace Emby.Server.Implementations.Services public static async Task WriteObject(IRequest request, object result, IResponse response) { var contentType = request.ResponseContentType; - var serializer = RequestHelper.GetResponseWriter(contentType); + var serializer = RequestHelper.GetResponseWriter(HttpListenerHost.Instance, contentType); using (var ms = new MemoryStream()) { diff --git a/Emby.Server.Implementations/Services/ServiceController.cs b/Emby.Server.Implementations/Services/ServiceController.cs index 714a16df5..da8af89c8 100644 --- a/Emby.Server.Implementations/Services/ServiceController.cs +++ b/Emby.Server.Implementations/Services/ServiceController.cs @@ -53,28 +53,58 @@ namespace Emby.Server.Implementations.Services ServiceExecGeneral.CreateServiceRunnersFor(requestType, actions); - var returnMarker = requestType.GetTypeWithGenericTypeDefinitionOf(typeof(IReturn<>)); + var returnMarker = GetTypeWithGenericTypeDefinitionOf(requestType, typeof(IReturn<>)); var responseType = returnMarker != null ? GetGenericArguments(returnMarker)[0] : mi.ReturnType != typeof(object) && mi.ReturnType != typeof(void) ? mi.ReturnType : Type.GetType(requestType.FullName + "Response"); - RegisterRestPaths(requestType); + RegisterRestPaths(appHost, requestType); appHost.AddServiceInfo(serviceType, requestType, responseType); } } + private static Type GetTypeWithGenericTypeDefinitionOf(Type type, Type genericTypeDefinition) + { + foreach (var t in type.GetTypeInfo().ImplementedInterfaces) + { + if (t.GetTypeInfo().IsGenericType && t.GetGenericTypeDefinition() == genericTypeDefinition) + { + return t; + } + } + + var genericType = FirstGenericType(type); + if (genericType != null && genericType.GetGenericTypeDefinition() == genericTypeDefinition) + { + return genericType; + } + + return null; + } + + public static Type FirstGenericType(Type type) + { + while (type != null) + { + if (type.GetTypeInfo().IsGenericType) + return type; + + type = type.GetTypeInfo().BaseType; + } + return null; + } + public readonly Dictionary<string, List<RestPath>> RestPathMap = new Dictionary<string, List<RestPath>>(StringComparer.OrdinalIgnoreCase); - public void RegisterRestPaths(Type requestType) + public void RegisterRestPaths(HttpListenerHost appHost, Type requestType) { - var appHost = ServiceStackHost.Instance; var attrs = appHost.GetRouteAttributes(requestType); - foreach (MediaBrowser.Model.Services.RouteAttribute attr in attrs) + foreach (RouteAttribute attr in attrs) { - var restPath = new RestPath(requestType, attr.Path, attr.Verbs, attr.Summary, attr.Notes); + 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( diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs index 003776f9c..93126426c 100644 --- a/Emby.Server.Implementations/Services/ServiceHandler.cs +++ b/Emby.Server.Implementations/Services/ServiceHandler.cs @@ -59,17 +59,17 @@ namespace Emby.Server.Implementations.Services } } - protected static object CreateContentTypeRequest(IRequest httpReq, Type requestType, string contentType) + protected static object CreateContentTypeRequest(HttpListenerHost host, IRequest httpReq, Type requestType, string contentType) { if (!string.IsNullOrEmpty(contentType) && httpReq.ContentLength > 0) { - var deserializer = RequestHelper.GetRequestReader(contentType); + var deserializer = RequestHelper.GetRequestReader(host, contentType); if (deserializer != null) { return deserializer(requestType, httpReq.InputStream); } } - return ServiceStackHost.Instance.CreateInstance(requestType); //Return an empty DTO, even for empty request bodies + return host.CreateInstance(requestType); } public static RestPath FindMatchingRestPath(string httpMethod, string pathInfo, ILogger logger, out string contentType) @@ -137,7 +137,7 @@ namespace Emby.Server.Implementations.Services if (ResponseContentType != null) httpReq.ResponseContentType = ResponseContentType; - var request = httpReq.Dto = CreateRequest(httpReq, restPath, logger); + var request = httpReq.Dto = CreateRequest(appHost, httpReq, restPath, logger); appHost.ApplyRequestFilters(httpReq, httpRes, request); @@ -146,7 +146,7 @@ namespace Emby.Server.Implementations.Services var response = await HandleResponseAsync(rawResponse).ConfigureAwait(false); // Apply response filters - foreach (var responseFilter in appHost.GlobalResponseFilters) + foreach (var responseFilter in appHost.ResponseFilters) { responseFilter(httpReq, httpRes, response); } @@ -154,18 +154,18 @@ namespace Emby.Server.Implementations.Services await ResponseHelper.WriteToResponse(httpRes, httpReq, response).ConfigureAwait(false); } - public static object CreateRequest(IRequest httpReq, RestPath restPath, ILogger logger) + public static object CreateRequest(HttpListenerHost host, IRequest httpReq, RestPath restPath, ILogger logger) { var requestType = restPath.RequestType; if (RequireqRequestStream(requestType)) { // Used by IRequiresRequestStream - return CreateRequiresRequestStreamRequest(httpReq, requestType); + return CreateRequiresRequestStreamRequest(host, httpReq, requestType); } var requestParams = GetFlattenedRequestParams(httpReq); - return CreateRequest(httpReq, restPath, requestParams); + return CreateRequest(host, httpReq, restPath, requestParams); } private static bool RequireqRequestStream(Type requestType) @@ -175,19 +175,19 @@ namespace Emby.Server.Implementations.Services return requiresRequestStreamTypeInfo.IsAssignableFrom(requestType.GetTypeInfo()); } - private static IRequiresRequestStream CreateRequiresRequestStreamRequest(IRequest req, Type requestType) + private static IRequiresRequestStream CreateRequiresRequestStreamRequest(HttpListenerHost host, IRequest req, Type requestType) { var restPath = GetRoute(req); - var request = ServiceHandler.CreateRequest(req, restPath, GetRequestParams(req), ServiceStackHost.Instance.CreateInstance(requestType)); + var request = ServiceHandler.CreateRequest(req, restPath, GetRequestParams(req), host.CreateInstance(requestType)); var rawReq = (IRequiresRequestStream)request; rawReq.RequestStream = req.InputStream; return rawReq; } - public static object CreateRequest(IRequest httpReq, RestPath restPath, Dictionary<string, string> requestParams) + public static object CreateRequest(HttpListenerHost host, IRequest httpReq, RestPath restPath, Dictionary<string, string> requestParams) { - var requestDto = CreateContentTypeRequest(httpReq, restPath.RequestType, httpReq.ContentType); + var requestDto = CreateContentTypeRequest(host, httpReq, restPath.RequestType, httpReq.ContentType); return CreateRequest(httpReq, restPath, requestParams, requestDto); } |
