diff options
Diffstat (limited to 'MediaBrowser.Controller/Net')
| -rw-r--r-- | MediaBrowser.Controller/Net/AuthenticatedAttribute.cs | 69 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/AuthorizationInfo.cs | 52 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs | 322 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IAuthService.cs | 9 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IAuthorizationContext.cs | 21 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IHasResultFactory.cs | 17 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IHttpResultFactory.cs | 80 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IHttpServer.cs | 39 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/ISessionContext.cs | 16 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IWebSocketConnection.cs | 85 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/IWebSocketListener.cs | 17 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/SecurityException.cs | 21 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/StaticResultOptions.cs | 41 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs | 41 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Net/WebSocketMessageInfo.cs | 16 |
15 files changed, 846 insertions, 0 deletions
diff --git a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs new file mode 100644 index 000000000..2f31b8e66 --- /dev/null +++ b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs @@ -0,0 +1,69 @@ +using System; +using MediaBrowser.Model.Services; + +namespace MediaBrowser.Controller.Net +{ + public class AuthenticatedAttribute : Attribute, IHasRequestFilter, IAuthenticationAttributes + { + public static IAuthService AuthService { get; set; } + + /// <summary> + /// Gets or sets the roles. + /// </summary> + /// <value>The roles.</value> + public string Roles { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether [escape parental control]. + /// </summary> + /// <value><c>true</c> if [escape parental control]; otherwise, <c>false</c>.</value> + public bool EscapeParentalControl { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether [allow before startup wizard]. + /// </summary> + /// <value><c>true</c> if [allow before startup wizard]; otherwise, <c>false</c>.</value> + public bool AllowBeforeStartupWizard { get; set; } + + public bool AllowLocal { get; set; } + + /// <summary> + /// The request filter is executed before the service. + /// </summary> + /// <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) + { + AuthService.Authenticate(request, 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; } + } + + public string[] GetRoles() + { + return (Roles ?? string.Empty).Split(new []{ ',' }, StringSplitOptions.RemoveEmptyEntries); + } + + public bool AllowLocalOnly { get; set; } + } + + public interface IAuthenticationAttributes + { + bool EscapeParentalControl { get; } + bool AllowBeforeStartupWizard { get; } + bool AllowLocal { get; } + bool AllowLocalOnly { get; } + + string[] GetRoles(); + } +} diff --git a/MediaBrowser.Controller/Net/AuthorizationInfo.cs b/MediaBrowser.Controller/Net/AuthorizationInfo.cs new file mode 100644 index 000000000..a68060db5 --- /dev/null +++ b/MediaBrowser.Controller/Net/AuthorizationInfo.cs @@ -0,0 +1,52 @@ +using MediaBrowser.Controller.Entities; +using System; + + +namespace MediaBrowser.Controller.Net +{ + public class AuthorizationInfo + { + /// <summary> + /// Gets or sets the user identifier. + /// </summary> + /// <value>The user identifier.</value> + public Guid UserId { + get { + if (User == null) { + return Guid.Empty; + } + else { + return User.Id; + } + } + } + + /// <summary> + /// Gets or sets the device identifier. + /// </summary> + /// <value>The device identifier.</value> + public string DeviceId { get; set; } + /// <summary> + /// Gets or sets the device. + /// </summary> + /// <value>The device.</value> + public string Device { get; set; } + /// <summary> + /// Gets or sets the client. + /// </summary> + /// <value>The client.</value> + public string Client { get; set; } + /// <summary> + /// Gets or sets the version. + /// </summary> + /// <value>The version.</value> + public string Version { get; set; } + /// <summary> + /// Gets or sets the token. + /// </summary> + /// <value>The token.</value> + public string Token { get; set; } + + public User User { get; set; } + } +} diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs new file mode 100644 index 000000000..7df96b777 --- /dev/null +++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs @@ -0,0 +1,322 @@ +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; +using MediaBrowser.Model.Threading; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net.WebSockets; +using System.Threading.Tasks; +using System.Threading; +using System; + +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, ITimer, TStateType>> ActiveConnections = + new List<Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType>>(); + + /// <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, CancellationToken cancellationToken); + + /// <summary> + /// The logger + /// </summary> + protected ILogger Logger; + + protected ITimerFactory TimerFactory { get; private set; } + + protected BasePeriodicWebSocketListener(ILogger logger) + { + if (logger == null) + { + throw new ArgumentNullException("logger"); + } + + Logger = logger; + } + + /// <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 Task.FromResult(true); + } + + protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); + + protected virtual bool SendOnTimer + { + get + { + return false; + } + } + + 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 ? + TimerFactory.Create(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) : + null; + + var state = new TStateType + { + IntervalMs = periodMs, + InitialDelayMs = dueTimeMs + }; + + lock (ActiveConnections) + { + ActiveConnections.Add(new Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType>(message.Connection, cancellationTokenSource, timer, state)); + } + + 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, ITimer, TStateType> 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) + { + Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType>[] 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; + }) + .ToArray(); + } + + foreach (var tuple in tuples) + { + SendData(tuple); + } + } + + private async void SendData(Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType> tuple) + { + var connection = tuple.Item1; + + try + { + var state = tuple.Item4; + + var cancellationToken = tuple.Item2.Token; + + var data = await GetDataToSend(state, cancellationToken).ConfigureAwait(false); + + if (data != null) + { + await connection.SendAsync(new WebSocketMessage<TReturnDataType> + { + MessageType = Name, + Data = data + + }, cancellationToken).ConfigureAwait(false); + + state.DateLastSendUtc = DateTime.UtcNow; + } + } + 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, ITimer, TStateType> 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) + { + + } + + 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.ToArray()) + { + 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/IAuthService.cs b/MediaBrowser.Controller/Net/IAuthService.cs new file mode 100644 index 000000000..361320250 --- /dev/null +++ b/MediaBrowser.Controller/Net/IAuthService.cs @@ -0,0 +1,9 @@ +using MediaBrowser.Model.Services; + +namespace MediaBrowser.Controller.Net +{ + public interface IAuthService + { + void Authenticate(IRequest request, IAuthenticationAttributes authAttribtues); + } +} diff --git a/MediaBrowser.Controller/Net/IAuthorizationContext.cs b/MediaBrowser.Controller/Net/IAuthorizationContext.cs new file mode 100644 index 000000000..5a9d0aa30 --- /dev/null +++ b/MediaBrowser.Controller/Net/IAuthorizationContext.cs @@ -0,0 +1,21 @@ +using MediaBrowser.Model.Services; + +namespace MediaBrowser.Controller.Net +{ + public interface IAuthorizationContext + { + /// <summary> + /// Gets the authorization information. + /// </summary> + /// <param name="requestContext">The request context.</param> + /// <returns>AuthorizationInfo.</returns> + AuthorizationInfo GetAuthorizationInfo(object requestContext); + + /// <summary> + /// Gets the authorization information. + /// </summary> + /// <param name="requestContext">The request context.</param> + /// <returns>AuthorizationInfo.</returns> + AuthorizationInfo GetAuthorizationInfo(IRequest requestContext); + } +} diff --git a/MediaBrowser.Controller/Net/IHasResultFactory.cs b/MediaBrowser.Controller/Net/IHasResultFactory.cs new file mode 100644 index 000000000..03144e4b8 --- /dev/null +++ b/MediaBrowser.Controller/Net/IHasResultFactory.cs @@ -0,0 +1,17 @@ +using MediaBrowser.Model.Services; + +namespace MediaBrowser.Controller.Net +{ + /// <summary> + /// Interface IHasResultFactory + /// Services that require a ResultFactory should implement this + /// </summary> + public interface IHasResultFactory : IRequiresRequest + { + /// <summary> + /// Gets or sets the result factory. + /// </summary> + /// <value>The result factory.</value> + IHttpResultFactory ResultFactory { get; set; } + } +} diff --git a/MediaBrowser.Controller/Net/IHttpResultFactory.cs b/MediaBrowser.Controller/Net/IHttpResultFactory.cs new file mode 100644 index 000000000..f8e631de3 --- /dev/null +++ b/MediaBrowser.Controller/Net/IHttpResultFactory.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Services; + +namespace MediaBrowser.Controller.Net +{ + /// <summary> + /// Interface IHttpResultFactory + /// </summary> + public interface IHttpResultFactory + { + /// <summary> + /// Gets the result. + /// </summary> + /// <param name="content">The content.</param> + /// <param name="contentType">Type of the content.</param> + /// <param name="responseHeaders">The response headers.</param> + /// <returns>System.Object.</returns> + object GetResult(string content, string contentType, IDictionary<string, string> responseHeaders = null); + + object GetResult(IRequest requestContext, byte[] content, string contentType, IDictionary<string, string> responseHeaders = null); + object GetResult(IRequest requestContext, Stream content, string contentType, IDictionary<string, string> responseHeaders = null); + object GetResult(IRequest requestContext, string content, string contentType, IDictionary<string, string> responseHeaders = null); + + object GetRedirectResult(string url); + + object GetResult<T>(IRequest requestContext, T result, IDictionary<string, string> responseHeaders = null) + where T : class; + + /// <summary> + /// Gets the static result. + /// </summary> + /// <param name="requestContext">The request context.</param> + /// <param name="cacheKey">The cache key.</param> + /// <param name="lastDateModified">The last date modified.</param> + /// <param name="cacheDuration">Duration of the cache.</param> + /// <param name="contentType">Type of the content.</param> + /// <param name="factoryFn">The factory fn.</param> + /// <param name="responseHeaders">The response headers.</param> + /// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param> + /// <returns>System.Object.</returns> + Task<object> GetStaticResult(IRequest requestContext, + Guid cacheKey, + DateTime? lastDateModified, + TimeSpan? cacheDuration, + string contentType, Func<Task<Stream>> factoryFn, + IDictionary<string, string> responseHeaders = null, + bool isHeadRequest = false); + + /// <summary> + /// Gets the static result. + /// </summary> + /// <param name="requestContext">The request context.</param> + /// <param name="options">The options.</param> + /// <returns>System.Object.</returns> + Task<object> GetStaticResult(IRequest requestContext, StaticResultOptions options); + + /// <summary> + /// Gets the static file result. + /// </summary> + /// <param name="requestContext">The request context.</param> + /// <param name="path">The path.</param> + /// <param name="fileShare">The file share.</param> + /// <returns>System.Object.</returns> + Task<object> GetStaticFileResult(IRequest requestContext, string path, FileShareMode fileShare = FileShareMode.Read); + + /// <summary> + /// Gets the static file result. + /// </summary> + /// <param name="requestContext">The request context.</param> + /// <param name="options">The options.</param> + /// <returns>System.Object.</returns> + Task<object> GetStaticFileResult(IRequest requestContext, + StaticFileResultOptions options); + } +} diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs new file mode 100644 index 000000000..d2ebadcfa --- /dev/null +++ b/MediaBrowser.Controller/Net/IHttpServer.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using MediaBrowser.Model.Services; +using MediaBrowser.Model.Events; + +namespace MediaBrowser.Controller.Net +{ + /// <summary> + /// Interface IHttpServer + /// </summary> + public interface IHttpServer : IDisposable + { + /// <summary> + /// Gets the URL prefix. + /// </summary> + /// <value>The URL prefix.</value> + string[] UrlPrefixes { get; } + + /// <summary> + /// Stops this instance. + /// </summary> + void Stop(); + + /// <summary> + /// Occurs when [web socket connected]. + /// </summary> + event EventHandler<GenericEventArgs<IWebSocketConnection>> WebSocketConnected; + + /// <summary> + /// Inits this instance. + /// </summary> + void Init(IEnumerable<IService> services, IEnumerable<IWebSocketListener> listener); + + /// <summary> + /// If set, all requests will respond with this message + /// </summary> + string GlobalResponse { get; set; } + } +} diff --git a/MediaBrowser.Controller/Net/ISessionContext.cs b/MediaBrowser.Controller/Net/ISessionContext.cs new file mode 100644 index 000000000..37ddbc2b3 --- /dev/null +++ b/MediaBrowser.Controller/Net/ISessionContext.cs @@ -0,0 +1,16 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Session; +using System.Threading.Tasks; +using MediaBrowser.Model.Services; + +namespace MediaBrowser.Controller.Net +{ + public interface ISessionContext + { + SessionInfo GetSession(object requestContext); + User GetUser(object requestContext); + + SessionInfo GetSession(IRequest requestContext); + User GetUser(IRequest requestContext); + } +} diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs new file mode 100644 index 000000000..816e9afca --- /dev/null +++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs @@ -0,0 +1,85 @@ +using MediaBrowser.Model.Net; +using MediaBrowser.Model.Services; +using System.Net.WebSockets; +using System.Threading.Tasks; +using System.Threading; +using System; + +namespace MediaBrowser.Controller.Net +{ + public interface IWebSocketConnection : IDisposable + { + /// <summary> + /// Occurs when [closed]. + /// </summary> + event EventHandler<EventArgs> Closed; + + /// <summary> + /// Gets the id. + /// </summary> + /// <value>The id.</value> + Guid Id { get; } + + /// <summary> + /// Gets the last activity date. + /// </summary> + /// <value>The last activity date.</value> + DateTime LastActivityDate { get; } + + /// <summary> + /// Gets or sets the URL. + /// </summary> + /// <value>The URL.</value> + string Url { get; set; } + /// <summary> + /// Gets or sets the query string. + /// </summary> + /// <value>The query string.</value> + QueryParamCollection QueryString { get; set; } + + /// <summary> + /// Gets or sets the receive action. + /// </summary> + /// <value>The receive action.</value> + Func<WebSocketMessageInfo, Task> OnReceive { get; set; } + + /// <summary> + /// Gets the state. + /// </summary> + /// <value>The state.</value> + WebSocketState State { get; } + + /// <summary> + /// Gets the remote end point. + /// </summary> + /// <value>The remote end point.</value> + string RemoteEndPoint { get; } + + /// <summary> + /// Sends a message asynchronously. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="message">The message.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + /// <exception cref="System.ArgumentNullException">message</exception> + Task SendAsync<T>(WebSocketMessage<T> message, CancellationToken cancellationToken); + + /// <summary> + /// Sends a message asynchronously. + /// </summary> + /// <param name="buffer">The buffer.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task SendAsync(byte[] buffer, CancellationToken cancellationToken); + + /// <summary> + /// Sends a message asynchronously. + /// </summary> + /// <param name="text">The text.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + /// <exception cref="System.ArgumentNullException">buffer</exception> + Task SendAsync(string text, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Controller/Net/IWebSocketListener.cs b/MediaBrowser.Controller/Net/IWebSocketListener.cs new file mode 100644 index 000000000..29698c1a4 --- /dev/null +++ b/MediaBrowser.Controller/Net/IWebSocketListener.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Net +{ + /// <summary> + ///This is an interface for listening to messages coming through a web socket connection + /// </summary> + public interface IWebSocketListener + { + /// <summary> + /// Processes the message. + /// </summary> + /// <param name="message">The message.</param> + /// <returns>Task.</returns> + Task ProcessMessage(WebSocketMessageInfo message); + } +} diff --git a/MediaBrowser.Controller/Net/SecurityException.cs b/MediaBrowser.Controller/Net/SecurityException.cs new file mode 100644 index 000000000..b251ab9a9 --- /dev/null +++ b/MediaBrowser.Controller/Net/SecurityException.cs @@ -0,0 +1,21 @@ +using System; + +namespace MediaBrowser.Controller.Net +{ + public class SecurityException : Exception + { + public SecurityException(string message) + : base(message) + { + + } + + public SecurityExceptionType SecurityExceptionType { get; set; } + } + + public enum SecurityExceptionType + { + Unauthenticated = 0, + ParentalControl = 1 + } +} diff --git a/MediaBrowser.Controller/Net/StaticResultOptions.cs b/MediaBrowser.Controller/Net/StaticResultOptions.cs new file mode 100644 index 000000000..1c9b2586d --- /dev/null +++ b/MediaBrowser.Controller/Net/StaticResultOptions.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +using MediaBrowser.Model.IO; + +namespace MediaBrowser.Controller.Net +{ + public class StaticResultOptions + { + public string ContentType { get; set; } + public TimeSpan? CacheDuration { get; set; } + public DateTime? DateLastModified { get; set; } + public Guid CacheKey { get; set; } + + public Func<Task<Stream>> ContentFactory { get; set; } + + public bool IsHeadRequest { get; set; } + + public IDictionary<string, string> ResponseHeaders { get; set; } + + public Action OnComplete { get; set; } + public Action OnError { get; set; } + + public string Path { get; set; } + public long? ContentLength { get; set; } + + public FileShareMode FileShare { get; set; } + + public StaticResultOptions() + { + ResponseHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + FileShare = FileShareMode.Read; + } + } + + public class StaticFileResultOptions : StaticResultOptions + { + } +} diff --git a/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs b/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs new file mode 100644 index 000000000..b200f883a --- /dev/null +++ b/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Specialized; +using MediaBrowser.Model.Services; + +namespace MediaBrowser.Controller.Net +{ + /// <summary> + /// Class WebSocketConnectEventArgs + /// </summary> + + public class WebSocketConnectingEventArgs : EventArgs + { + /// <summary> + /// Gets or sets the URL. + /// </summary> + /// <value>The URL.</value> + public string Url { get; set; } + /// <summary> + /// Gets or sets the endpoint. + /// </summary> + /// <value>The endpoint.</value> + public string Endpoint { get; set; } + /// <summary> + /// Gets or sets the query string. + /// </summary> + /// <value>The query string.</value> + public QueryParamCollection QueryString { get; set; } + /// <summary> + /// Gets or sets a value indicating whether [allow connection]. + /// </summary> + /// <value><c>true</c> if [allow connection]; otherwise, <c>false</c>.</value> + public bool AllowConnection { get; set; } + + public WebSocketConnectingEventArgs() + { + QueryString = new QueryParamCollection(); + AllowConnection = true; + } + } + +} diff --git a/MediaBrowser.Controller/Net/WebSocketMessageInfo.cs b/MediaBrowser.Controller/Net/WebSocketMessageInfo.cs new file mode 100644 index 000000000..332f16420 --- /dev/null +++ b/MediaBrowser.Controller/Net/WebSocketMessageInfo.cs @@ -0,0 +1,16 @@ +using MediaBrowser.Model.Net; + +namespace MediaBrowser.Controller.Net +{ + /// <summary> + /// Class WebSocketMessageInfo + /// </summary> + public class WebSocketMessageInfo : WebSocketMessage<string> + { + /// <summary> + /// Gets or sets the connection. + /// </summary> + /// <value>The connection.</value> + public IWebSocketConnection Connection { get; set; } + } +}
\ No newline at end of file |
