diff options
Diffstat (limited to 'MediaBrowser.Controller/Net')
| -rw-r--r-- | MediaBrowser.Controller/Net/AuthenticatedAttribute.cs | 6 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs | 341 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IAsyncStreamSource.cs | 18 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IHasResultFactory.cs | 2 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IHttpResultFactory.cs | 10 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IHttpServer.cs | 3 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IRestfulService.cs | 12 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IServiceRequest.cs | 7 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IWebSocketConnection.cs | 4 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/LoggedAttribute.cs | 44 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/ServiceRequest.cs | 42 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/ServiceStackServiceRequest.cs | 62 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/StaticResultOptions.cs | 6 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs | 7 |
14 files changed, 82 insertions, 482 deletions
diff --git a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs index b1bab79c5..d45416f53 100644 --- a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs +++ b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs @@ -1,7 +1,7 @@ -using ServiceStack.Web; -using System; +using System; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { @@ -35,7 +35,7 @@ namespace MediaBrowser.Controller.Net /// <param name="requestDto">The request DTO</param> public void RequestFilter(IRequest request, IResponse response, object requestDto) { - var serviceRequest = new ServiceStackServiceRequest(request); + var serviceRequest = new ServiceRequest(request); AuthService.Authenticate(serviceRequest, this); } diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs deleted file mode 100644 index be177cb02..000000000 --- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs +++ /dev/null @@ -1,341 +0,0 @@ -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Net -{ - /// <summary> - /// Starts sending data over a web socket periodically when a message is received, and then stops when a corresponding stop message is received - /// </summary> - /// <typeparam name="TReturnDataType">The type of the T return data type.</typeparam> - /// <typeparam name="TStateType">The type of the T state type.</typeparam> - public abstract class BasePeriodicWebSocketListener<TReturnDataType, TStateType> : IWebSocketListener, IDisposable - where TStateType : WebSocketListenerState, new() - where TReturnDataType : class - { - /// <summary> - /// The _active connections - /// </summary> - protected readonly List<Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>> ActiveConnections = - new List<Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>>(); - - /// <summary> - /// Gets the name. - /// </summary> - /// <value>The name.</value> - protected abstract string Name { get; } - - /// <summary> - /// Gets the data to send. - /// </summary> - /// <param name="state">The state.</param> - /// <returns>Task{`1}.</returns> - protected abstract Task<TReturnDataType> GetDataToSend(TStateType state); - - /// <summary> - /// The logger - /// </summary> - protected ILogger Logger; - - /// <summary> - /// Initializes a new instance of the <see cref="BasePeriodicWebSocketListener{TStateType}" /> class. - /// </summary> - /// <param name="logger">The logger.</param> - /// <exception cref="System.ArgumentNullException">logger</exception> - protected BasePeriodicWebSocketListener(ILogger logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - - Logger = logger; - } - - /// <summary> - /// The null task result - /// </summary> - protected Task NullTaskResult = Task.FromResult(true); - - /// <summary> - /// Processes the message. - /// </summary> - /// <param name="message">The message.</param> - /// <returns>Task.</returns> - public Task ProcessMessage(WebSocketMessageInfo message) - { - if (message == null) - { - throw new ArgumentNullException("message"); - } - - if (string.Equals(message.MessageType, Name + "Start", StringComparison.OrdinalIgnoreCase)) - { - Start(message); - } - - if (string.Equals(message.MessageType, Name + "Stop", StringComparison.OrdinalIgnoreCase)) - { - Stop(message); - } - - return NullTaskResult; - } - - protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - protected virtual bool SendOnTimer - { - get - { - return true; - } - } - - protected virtual void ParseMessageParams(string[] values) - { - - } - - /// <summary> - /// Starts sending messages over a web socket - /// </summary> - /// <param name="message">The message.</param> - private void Start(WebSocketMessageInfo message) - { - var vals = message.Data.Split(','); - - var dueTimeMs = long.Parse(vals[0], UsCulture); - var periodMs = long.Parse(vals[1], UsCulture); - - if (vals.Length > 2) - { - ParseMessageParams(vals.Skip(2).ToArray()); - } - - var cancellationTokenSource = new CancellationTokenSource(); - - Logger.Debug("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name); - - var timer = SendOnTimer ? - new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) : - null; - - var state = new TStateType - { - IntervalMs = periodMs, - InitialDelayMs = dueTimeMs - }; - - var semaphore = new SemaphoreSlim(1, 1); - - lock (ActiveConnections) - { - ActiveConnections.Add(new Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>(message.Connection, cancellationTokenSource, timer, state, semaphore)); - } - - if (timer != null) - { - timer.Change(TimeSpan.FromMilliseconds(dueTimeMs), TimeSpan.FromMilliseconds(periodMs)); - } - } - - /// <summary> - /// Timers the callback. - /// </summary> - /// <param name="state">The state.</param> - private void TimerCallback(object state) - { - var connection = (IWebSocketConnection)state; - - Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim> tuple; - - lock (ActiveConnections) - { - tuple = ActiveConnections.FirstOrDefault(c => c.Item1 == connection); - } - - if (tuple == null) - { - return; - } - - if (connection.State != WebSocketState.Open || tuple.Item2.IsCancellationRequested) - { - DisposeConnection(tuple); - return; - } - - SendData(tuple); - } - - protected void SendData(bool force) - { - List<Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>> tuples; - - lock (ActiveConnections) - { - tuples = ActiveConnections - .Where(c => - { - if (c.Item1.State == WebSocketState.Open && !c.Item2.IsCancellationRequested) - { - var state = c.Item4; - - if (force || (DateTime.UtcNow - state.DateLastSendUtc).TotalMilliseconds >= state.IntervalMs) - { - return true; - } - } - - return false; - }) - .ToList(); - } - - foreach (var tuple in tuples) - { - SendData(tuple); - } - } - - private async void SendData(Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim> tuple) - { - var connection = tuple.Item1; - - try - { - await tuple.Item5.WaitAsync(tuple.Item2.Token).ConfigureAwait(false); - - var state = tuple.Item4; - - var data = await GetDataToSend(state).ConfigureAwait(false); - - if (data != null) - { - await connection.SendAsync(new WebSocketMessage<TReturnDataType> - { - MessageType = Name, - Data = data - - }, tuple.Item2.Token).ConfigureAwait(false); - - state.DateLastSendUtc = DateTime.UtcNow; - } - - tuple.Item5.Release(); - } - catch (OperationCanceledException) - { - if (tuple.Item2.IsCancellationRequested) - { - DisposeConnection(tuple); - } - } - catch (Exception ex) - { - Logger.ErrorException("Error sending web socket message {0}", ex, Name); - DisposeConnection(tuple); - } - } - - /// <summary> - /// Stops sending messages over a web socket - /// </summary> - /// <param name="message">The message.</param> - private void Stop(WebSocketMessageInfo message) - { - lock (ActiveConnections) - { - var connection = ActiveConnections.FirstOrDefault(c => c.Item1 == message.Connection); - - if (connection != null) - { - DisposeConnection(connection); - } - } - } - - /// <summary> - /// Disposes the connection. - /// </summary> - /// <param name="connection">The connection.</param> - private void DisposeConnection(Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim> connection) - { - Logger.Debug("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name); - - var timer = connection.Item3; - - if (timer != null) - { - try - { - timer.Dispose(); - } - catch (ObjectDisposedException) - { - - } - } - - try - { - connection.Item2.Cancel(); - connection.Item2.Dispose(); - } - catch (ObjectDisposedException) - { - - } - - try - { - connection.Item5.Dispose(); - } - catch (ObjectDisposedException) - { - - } - - ActiveConnections.Remove(connection); - } - - /// <summary> - /// Releases unmanaged and - optionally - managed resources. - /// </summary> - /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - lock (ActiveConnections) - { - foreach (var connection in ActiveConnections.ToList()) - { - DisposeConnection(connection); - } - } - } - } - - /// <summary> - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// </summary> - public void Dispose() - { - Dispose(true); - } - } - - public class WebSocketListenerState - { - public DateTime DateLastSendUtc { get; set; } - public long InitialDelayMs { get; set; } - public long IntervalMs { get; set; } - } -} diff --git a/MediaBrowser.Controller/Net/IAsyncStreamSource.cs b/MediaBrowser.Controller/Net/IAsyncStreamSource.cs deleted file mode 100644 index 0f41f60a5..000000000 --- a/MediaBrowser.Controller/Net/IAsyncStreamSource.cs +++ /dev/null @@ -1,18 +0,0 @@ -using ServiceStack.Web; -using System.IO; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Net -{ - /// <summary> - /// Interface IAsyncStreamSource - /// Enables asynchronous writing to http resonse streams - /// </summary> - public interface IAsyncStreamSource - { - /// <summary> - /// Asynchronously write to the response stream. - /// </summary> - Task WriteToAsync(Stream responseStream); - } -} diff --git a/MediaBrowser.Controller/Net/IHasResultFactory.cs b/MediaBrowser.Controller/Net/IHasResultFactory.cs index 3988b8d61..03144e4b8 100644 --- a/MediaBrowser.Controller/Net/IHasResultFactory.cs +++ b/MediaBrowser.Controller/Net/IHasResultFactory.cs @@ -1,4 +1,4 @@ -using ServiceStack.Web; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { diff --git a/MediaBrowser.Controller/Net/IHttpResultFactory.cs b/MediaBrowser.Controller/Net/IHttpResultFactory.cs index ca453840f..9f295c71d 100644 --- a/MediaBrowser.Controller/Net/IHttpResultFactory.cs +++ b/MediaBrowser.Controller/Net/IHttpResultFactory.cs @@ -1,8 +1,10 @@ -using ServiceStack.Web; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; +using MediaBrowser.Common.IO; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { @@ -20,8 +22,6 @@ namespace MediaBrowser.Controller.Net /// <returns>System.Object.</returns> object GetResult(object content, string contentType, IDictionary<string,string> responseHeaders = null); - object GetAsyncStreamWriter(IAsyncStreamSource streamSource); - /// <summary> /// Gets the optimized result. /// </summary> @@ -97,7 +97,7 @@ namespace MediaBrowser.Controller.Net /// <param name="path">The path.</param> /// <param name="fileShare">The file share.</param> /// <returns>System.Object.</returns> - Task<object> GetStaticFileResult(IRequest requestContext, string path, FileShare fileShare = FileShare.Read); + Task<object> GetStaticFileResult(IRequest requestContext, string path, FileShareMode fileShare = FileShareMode.Read); /// <summary> /// Gets the static file result. diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs index 97c5dd31b..8c503c199 100644 --- a/MediaBrowser.Controller/Net/IHttpServer.cs +++ b/MediaBrowser.Controller/Net/IHttpServer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { @@ -46,7 +47,7 @@ namespace MediaBrowser.Controller.Net /// <summary> /// Inits this instance. /// </summary> - void Init(IEnumerable<IRestfulService> services); + void Init(IEnumerable<IService> services); /// <summary> /// If set, all requests will respond with this message diff --git a/MediaBrowser.Controller/Net/IRestfulService.cs b/MediaBrowser.Controller/Net/IRestfulService.cs deleted file mode 100644 index 7d07bb094..000000000 --- a/MediaBrowser.Controller/Net/IRestfulService.cs +++ /dev/null @@ -1,12 +0,0 @@ -using ServiceStack; - -namespace MediaBrowser.Controller.Net -{ - /// <summary> - /// Interface IRestfulService - /// </summary> - [Logged] - public interface IRestfulService : IService - { - } -} diff --git a/MediaBrowser.Controller/Net/IServiceRequest.cs b/MediaBrowser.Controller/Net/IServiceRequest.cs index e48247362..ebc7e8d65 100644 --- a/MediaBrowser.Controller/Net/IServiceRequest.cs +++ b/MediaBrowser.Controller/Net/IServiceRequest.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; -using System.Collections.Specialized; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { public interface IServiceRequest { - object OriginalRequest { get; } string RemoteIp { get; } - NameValueCollection Headers { get; } - NameValueCollection QueryString { get; } + QueryParamCollection Headers { get; } + QueryParamCollection QueryString { get; } IDictionary<string,object> Items { get; } void AddResponseHeader(string name, string value); } diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs index e21df3c39..dad238891 100644 --- a/MediaBrowser.Controller/Net/IWebSocketConnection.cs +++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs @@ -1,8 +1,8 @@ using MediaBrowser.Model.Net; using System; -using System.Collections.Specialized; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { @@ -34,7 +34,7 @@ namespace MediaBrowser.Controller.Net /// Gets or sets the query string. /// </summary> /// <value>The query string.</value> - NameValueCollection QueryString { get; set; } + QueryParamCollection QueryString { get; set; } /// <summary> /// Gets or sets the receive action. diff --git a/MediaBrowser.Controller/Net/LoggedAttribute.cs b/MediaBrowser.Controller/Net/LoggedAttribute.cs index d56a015a8..6a2a5e2e3 100644 --- a/MediaBrowser.Controller/Net/LoggedAttribute.cs +++ b/MediaBrowser.Controller/Net/LoggedAttribute.cs @@ -2,17 +2,25 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; -using ServiceStack.Web; using System; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { - public class LoggedAttribute : Attribute, IHasRequestFilter + public class LoggedAttribute : IRequestFilter { - public ILogger Logger { get; set; } - public IUserManager UserManager { get; set; } - public ISessionManager SessionManager { get; set; } - public IAuthorizationContext AuthorizationContext { get; set; } + public LoggedAttribute(ILogger logger, IUserManager userManager, ISessionManager sessionManager, IAuthorizationContext authorizationContext) + { + Logger = logger; + UserManager = userManager; + SessionManager = sessionManager; + AuthorizationContext = authorizationContext; + } + + public ILogger Logger { get; private set; } + public IUserManager UserManager { get; private set; } + public ISessionManager SessionManager { get; private set; } + public IAuthorizationContext AuthorizationContext { get; private set; } /// <summary> /// The request filter is executed before the service. @@ -20,9 +28,9 @@ namespace MediaBrowser.Controller.Net /// <param name="request">The http request wrapper</param> /// <param name="response">The http response wrapper</param> /// <param name="requestDto">The request DTO</param> - public void RequestFilter(IRequest request, IResponse response, object requestDto) + public void Filter(IRequest request, IResponse response, object requestDto) { - var serviceRequest = new ServiceStackServiceRequest(request); + var serviceRequest = new ServiceRequest(request); //This code is executed before the service var auth = AuthorizationContext.GetAuthorizationInfo(serviceRequest); @@ -51,25 +59,5 @@ namespace MediaBrowser.Controller.Net } } } - - /// <summary> - /// A new shallow copy of this filter is used on every request. - /// </summary> - /// <returns>IHasRequestFilter.</returns> - public IHasRequestFilter Copy() - { - return this; - } - - /// <summary> - /// Order in which Request Filters are executed. - /// <0 Executed before global request filters - /// >0 Executed after global request filters - /// </summary> - /// <value>The priority.</value> - public int Priority - { - get { return 0; } - } } } diff --git a/MediaBrowser.Controller/Net/ServiceRequest.cs b/MediaBrowser.Controller/Net/ServiceRequest.cs new file mode 100644 index 000000000..1f72d0eb2 --- /dev/null +++ b/MediaBrowser.Controller/Net/ServiceRequest.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using MediaBrowser.Model.Services; + +namespace MediaBrowser.Controller.Net +{ + public class ServiceRequest : IServiceRequest + { + private readonly IRequest _request; + + public ServiceRequest(IRequest request) + { + _request = request; + } + + public string RemoteIp + { + get { return _request.RemoteIp; } + } + + public QueryParamCollection Headers + { + get { return _request.Headers; } + } + + public QueryParamCollection QueryString + { + get { return _request.QueryString; } + } + + public IDictionary<string, object> Items + { + get { return _request.Items; } + } + + public void AddResponseHeader(string name, string value) + { + _request.Response.AddHeader(name, value); + } + } +} diff --git a/MediaBrowser.Controller/Net/ServiceStackServiceRequest.cs b/MediaBrowser.Controller/Net/ServiceStackServiceRequest.cs deleted file mode 100644 index a33e9c1c6..000000000 --- a/MediaBrowser.Controller/Net/ServiceStackServiceRequest.cs +++ /dev/null @@ -1,62 +0,0 @@ -using ServiceStack.Web; -using System; -using System.Collections.Generic; -using System.Collections.Specialized; - -namespace MediaBrowser.Controller.Net -{ - public class ServiceStackServiceRequest : IServiceRequest - { - private readonly IRequest _request; - - public ServiceStackServiceRequest(IRequest request) - { - _request = request; - } - - public object OriginalRequest - { - get { return _request; } - } - - public string RemoteIp - { - get { return _request.RemoteIp; } - } - - private NameValueCollection _headers; - public NameValueCollection Headers - { - get { return _headers ?? (_headers = Get(_request.Headers)); } - } - - private NameValueCollection _query; - public NameValueCollection QueryString - { - get { return _query ?? (_query = Get(_request.QueryString)); } - } - - private NameValueCollection Get(INameValueCollection coll) - { - var nv = new NameValueCollection(StringComparer.OrdinalIgnoreCase); - - foreach (var key in coll.AllKeys) - { - nv[key] = coll[key]; - } - - return nv; - //return coll.ToNameValueCollection(); - } - - public IDictionary<string, object> Items - { - get { return _request.Items; } - } - - public void AddResponseHeader(string name, string value) - { - _request.Response.AddHeader(name, value); - } - } -} diff --git a/MediaBrowser.Controller/Net/StaticResultOptions.cs b/MediaBrowser.Controller/Net/StaticResultOptions.cs index b5efc1b8f..272fa8b3b 100644 --- a/MediaBrowser.Controller/Net/StaticResultOptions.cs +++ b/MediaBrowser.Controller/Net/StaticResultOptions.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; +using MediaBrowser.Common.IO; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.Net { @@ -31,11 +33,11 @@ namespace MediaBrowser.Controller.Net { public string Path { get; set; } - public FileShare FileShare { get; set; } + public FileShareMode FileShare { get; set; } public StaticFileResultOptions() { - FileShare = FileShare.Read; + FileShare = FileShareMode.Read; } } } diff --git a/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs b/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs index ffeaf286e..0ad80d374 100644 --- a/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs +++ b/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Specialized; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { @@ -17,7 +18,7 @@ namespace MediaBrowser.Controller.Net /// Gets or sets the query string. /// </summary> /// <value>The query string.</value> - public NameValueCollection QueryString { get; set; } + public QueryParamCollection QueryString { get; set; } /// <summary> /// Gets or sets the web socket. /// </summary> @@ -46,7 +47,7 @@ namespace MediaBrowser.Controller.Net /// Gets or sets the query string. /// </summary> /// <value>The query string.</value> - public NameValueCollection QueryString { get; set; } + public QueryParamCollection QueryString { get; set; } /// <summary> /// Gets or sets a value indicating whether [allow connection]. /// </summary> @@ -55,7 +56,7 @@ namespace MediaBrowser.Controller.Net public WebSocketConnectingEventArgs() { - QueryString = new NameValueCollection(); + QueryString = new QueryParamCollection(); AllowConnection = true; } } |
