diff options
Diffstat (limited to 'MediaBrowser.Model/Net')
| -rw-r--r-- | MediaBrowser.Model/Net/EndPointInfo.cs | 8 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/HttpException.cs | 43 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/HttpResponse.cs | 64 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/IAcceptSocket.cs | 15 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/ISocket.cs | 28 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/ISocketFactory.cs | 49 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/IpAddressInfo.cs | 37 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/IpEndPointInfo.cs | 30 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/MimeTypes.cs | 346 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/NetworkShare.cs | 31 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/NetworkShareType.cs | 30 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/SocketReceiveResult.cs | 25 | ||||
| -rw-r--r-- | MediaBrowser.Model/Net/WebSocketMessage.cs | 24 |
13 files changed, 730 insertions, 0 deletions
diff --git a/MediaBrowser.Model/Net/EndPointInfo.cs b/MediaBrowser.Model/Net/EndPointInfo.cs new file mode 100644 index 000000000..5a158e785 --- /dev/null +++ b/MediaBrowser.Model/Net/EndPointInfo.cs @@ -0,0 +1,8 @@ +namespace MediaBrowser.Model.Net +{ + public class EndPointInfo + { + public bool IsLocal { get; set; } + public bool IsInNetwork { get; set; } + } +} diff --git a/MediaBrowser.Model/Net/HttpException.cs b/MediaBrowser.Model/Net/HttpException.cs new file mode 100644 index 000000000..698b1bc7e --- /dev/null +++ b/MediaBrowser.Model/Net/HttpException.cs @@ -0,0 +1,43 @@ +using System; +using System.Net; + +namespace MediaBrowser.Model.Net +{ + /// <summary> + /// Class HttpException + /// </summary> + public class HttpException : Exception + { + /// <summary> + /// Gets or sets the status code. + /// </summary> + /// <value>The status code.</value> + public HttpStatusCode? StatusCode { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is timed out. + /// </summary> + /// <value><c>true</c> if this instance is timed out; otherwise, <c>false</c>.</value> + public bool IsTimedOut { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="HttpException" /> class. + /// </summary> + /// <param name="message">The message.</param> + /// <param name="innerException">The inner exception.</param> + public HttpException(string message, Exception innerException) + : base(message, innerException) + { + + } + + /// <summary> + /// Initializes a new instance of the <see cref="HttpException" /> class. + /// </summary> + /// <param name="message">The message.</param> + public HttpException(string message) + : base(message) + { + } + } +} diff --git a/MediaBrowser.Model/Net/HttpResponse.cs b/MediaBrowser.Model/Net/HttpResponse.cs new file mode 100644 index 000000000..f4bd8e681 --- /dev/null +++ b/MediaBrowser.Model/Net/HttpResponse.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; + +namespace MediaBrowser.Model.Net +{ + public class HttpResponse : IDisposable + { + /// <summary> + /// Gets or sets the type of the content. + /// </summary> + /// <value>The type of the content.</value> + public string ContentType { get; set; } + + /// <summary> + /// Gets or sets the response URL. + /// </summary> + /// <value>The response URL.</value> + public string ResponseUrl { get; set; } + + /// <summary> + /// Gets or sets the content. + /// </summary> + /// <value>The content.</value> + public Stream Content { get; set; } + + /// <summary> + /// Gets or sets the status code. + /// </summary> + /// <value>The status code.</value> + public HttpStatusCode StatusCode { get; set; } + + /// <summary> + /// Gets or sets the length of the content. + /// </summary> + /// <value>The length of the content.</value> + public long? ContentLength { get; set; } + + /// <summary> + /// Gets or sets the headers. + /// </summary> + /// <value>The headers.</value> + public Dictionary<string, string> Headers { get; set; } + + private readonly IDisposable _disposable; + + public HttpResponse(IDisposable disposable) + { + _disposable = disposable; + } + public HttpResponse() + { + } + + public void Dispose() + { + if (_disposable != null) + { + _disposable.Dispose(); + } + } + } +} diff --git a/MediaBrowser.Model/Net/IAcceptSocket.cs b/MediaBrowser.Model/Net/IAcceptSocket.cs new file mode 100644 index 000000000..af5a1fcfb --- /dev/null +++ b/MediaBrowser.Model/Net/IAcceptSocket.cs @@ -0,0 +1,15 @@ +using System; + +namespace MediaBrowser.Model.Net +{ + public class SocketCreateException : Exception + { + public SocketCreateException(string errorCode, Exception originalException) + : base(errorCode, originalException) + { + ErrorCode = errorCode; + } + + public string ErrorCode { get; private set; } + } +} diff --git a/MediaBrowser.Model/Net/ISocket.cs b/MediaBrowser.Model/Net/ISocket.cs new file mode 100644 index 000000000..6a6781026 --- /dev/null +++ b/MediaBrowser.Model/Net/ISocket.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Model.Net +{ + /// <summary> + /// Provides a common interface across platforms for UDP sockets used by this SSDP implementation. + /// </summary> + public interface ISocket : IDisposable + { + IpAddressInfo LocalIPAddress { get; } + + Task<SocketReceiveResult> ReceiveAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken); + + int Receive(byte[] buffer, int offset, int count); + + IAsyncResult BeginReceive(byte[] buffer, int offset, int count, AsyncCallback callback); + SocketReceiveResult EndReceive(IAsyncResult result); + + /// <summary> + /// Sends a UDP message to a particular end point (uni or multicast). + /// </summary> + Task SendToAsync(byte[] buffer, int offset, int bytes, IpEndPointInfo endPoint, CancellationToken cancellationToken); + } +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs new file mode 100644 index 000000000..6a4b99600 --- /dev/null +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -0,0 +1,49 @@ + +using System.IO; + +namespace MediaBrowser.Model.Net +{ + /// <summary> + /// Implemented by components that can create a platform specific UDP socket implementation, and wrap it in the cross platform <see cref="ISocket"/> interface. + /// </summary> + public interface ISocketFactory + { + + /// <summary> + /// Createa a new unicast socket using the specified local port number. + /// </summary> + /// <param name="localPort">The local port to bind to.</param> + /// <returns>A <see cref="ISocket"/> implementation.</returns> + ISocket CreateUdpSocket(int localPort); + + ISocket CreateUdpBroadcastSocket(int localPort); + + ISocket CreateTcpSocket(IpAddressInfo remoteAddress, int remotePort); + + /// <summary> + /// Createa a new unicast socket using the specified local port number. + /// </summary> + ISocket CreateSsdpUdpSocket(IpAddressInfo localIp, int localPort); + + /// <summary> + /// Createa a new multicast socket using the specified multicast IP address, multicast time to live and local port. + /// </summary> + /// <param name="ipAddress">The multicast IP address to bind to.</param> + /// <param name="multicastTimeToLive">The multicast time to live value. Actually a maximum number of network hops for UDP packets.</param> + /// <param name="localPort">The local port to bind to.</param> + /// <returns>A <see cref="ISocket"/> implementation.</returns> + ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); + + Stream CreateNetworkStream(ISocket socket, bool ownsSocket); + } + + public enum SocketType + { + Stream + } + + public enum ProtocolType + { + Tcp + } +} diff --git a/MediaBrowser.Model/Net/IpAddressInfo.cs b/MediaBrowser.Model/Net/IpAddressInfo.cs new file mode 100644 index 000000000..520f8fb54 --- /dev/null +++ b/MediaBrowser.Model/Net/IpAddressInfo.cs @@ -0,0 +1,37 @@ +using System; + +namespace MediaBrowser.Model.Net +{ + public class IpAddressInfo + { + public static IpAddressInfo Any = new IpAddressInfo("0.0.0.0", IpAddressFamily.InterNetwork); + public static IpAddressInfo IPv6Any = new IpAddressInfo("00000000000000000000", IpAddressFamily.InterNetworkV6); + public static IpAddressInfo Loopback = new IpAddressInfo("127.0.0.1", IpAddressFamily.InterNetwork); + public static IpAddressInfo IPv6Loopback = new IpAddressInfo("::1", IpAddressFamily.InterNetworkV6); + + public string Address { get; set; } + public IpAddressFamily AddressFamily { get; set; } + + public IpAddressInfo(string address, IpAddressFamily addressFamily) + { + Address = address; + AddressFamily = addressFamily; + } + + public bool Equals(IpAddressInfo address) + { + return string.Equals(address.Address, Address, StringComparison.OrdinalIgnoreCase); + } + + public override String ToString() + { + return Address; + } + } + + public enum IpAddressFamily + { + InterNetwork, + InterNetworkV6 + } +} diff --git a/MediaBrowser.Model/Net/IpEndPointInfo.cs b/MediaBrowser.Model/Net/IpEndPointInfo.cs new file mode 100644 index 000000000..b5cadc429 --- /dev/null +++ b/MediaBrowser.Model/Net/IpEndPointInfo.cs @@ -0,0 +1,30 @@ +using System; +using System.Globalization; + +namespace MediaBrowser.Model.Net +{ + public class IpEndPointInfo + { + public IpAddressInfo IpAddress { get; set; } + + public int Port { get; set; } + + public IpEndPointInfo() + { + + } + + public IpEndPointInfo(IpAddressInfo address, int port) + { + IpAddress = address; + Port = port; + } + + public override string ToString() + { + var ipAddresString = IpAddress == null ? string.Empty : IpAddress.ToString(); + + return ipAddresString + ":" + Port.ToString(CultureInfo.InvariantCulture); + } + } +} diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs new file mode 100644 index 000000000..d66d62fea --- /dev/null +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -0,0 +1,346 @@ +using MediaBrowser.Model.Extensions; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace MediaBrowser.Model.Net +{ + /// <summary> + /// Class MimeTypes + /// </summary> + public static class MimeTypes + { + /// <summary> + /// Any extension in this list is considered a video file - can be added to at runtime for extensibility + /// </summary> + private static readonly string[] VideoFileExtensions = new string[] + { + ".mkv", + ".m2t", + ".m2ts", + ".img", + ".iso", + ".mk3d", + ".ts", + ".rmvb", + ".mov", + ".avi", + ".mpg", + ".mpeg", + ".wmv", + ".mp4", + ".divx", + ".dvr-ms", + ".wtv", + ".ogm", + ".ogv", + ".asf", + ".m4v", + ".flv", + ".f4v", + ".3gp", + ".webm", + ".mts", + ".m2v", + ".rec" + }; + + private static Dictionary<string, string> GetVideoFileExtensionsDictionary() + { + Dictionary<string, string> dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + + foreach (string ext in VideoFileExtensions) + { + dict[ext] = ext; + } + + return dict; + } + + private static readonly Dictionary<string, string> VideoFileExtensionsDictionary = GetVideoFileExtensionsDictionary(); + + // http://en.wikipedia.org/wiki/Internet_media_type + // Add more as needed + + private static Dictionary<string, string> GetMimeTypeLookup() + { + Dictionary<string, string> dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + + dict.Add(".jpg", "image/jpeg"); + dict.Add(".jpeg", "image/jpeg"); + dict.Add(".tbn", "image/jpeg"); + dict.Add(".png", "image/png"); + dict.Add(".gif", "image/gif"); + dict.Add(".tiff", "image/tiff"); + dict.Add(".webp", "image/webp"); + dict.Add(".ico", "image/vnd.microsoft.icon"); + dict.Add(".mpg", "video/mpeg"); + dict.Add(".mpeg", "video/mpeg"); + dict.Add(".ogv", "video/ogg"); + dict.Add(".mov", "video/quicktime"); + dict.Add(".webm", "video/webm"); + dict.Add(".mkv", "video/x-matroska"); + dict.Add(".wmv", "video/x-ms-wmv"); + dict.Add(".flv", "video/x-flv"); + dict.Add(".avi", "video/x-msvideo"); + dict.Add(".asf", "video/x-ms-asf"); + dict.Add(".m4v", "video/x-m4v"); + dict.Add(".m4s", "video/mp4"); + dict.Add(".cbz", "application/x-cbz"); + dict.Add(".cbr", "application/epub+zip"); + dict.Add(".epub", "application/epub+zip"); + dict.Add(".pdf", "application/pdf"); + dict.Add(".mobi", "application/x-mobipocket-ebook"); + + dict.Add(".ass", "text/x-ssa"); + dict.Add(".ssa", "text/x-ssa"); + + return dict; + } + + private static readonly Dictionary<string, string> MimeTypeLookup = GetMimeTypeLookup(); + + private static readonly Dictionary<string, string> ExtensionLookup = CreateExtensionLookup(); + + private static Dictionary<string, string> CreateExtensionLookup() + { + var dict = MimeTypeLookup + .GroupBy(i => i.Value) + .ToDictionary(x => x.Key, x => x.First().Key, StringComparer.OrdinalIgnoreCase); + + dict["image/jpg"] = ".jpg"; + dict["image/x-png"] = ".png"; + + return dict; + } + + public static string GetMimeType(string path) + { + return GetMimeType(path, true); + } + + /// <summary> + /// Gets the type of the MIME. + /// </summary> + public static string GetMimeType(string path, bool enableStreamDefault) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + var ext = Path.GetExtension(path) ?? string.Empty; + + string result; + if (MimeTypeLookup.TryGetValue(ext, out result)) + { + return result; + } + + // Type video + if (StringHelper.EqualsIgnoreCase(ext, ".3gp")) + { + return "video/3gpp"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".3g2")) + { + return "video/3gpp2"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".ts")) + { + return "video/mp2t"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".mpd")) + { + return "video/vnd.mpeg.dash.mpd"; + } + + // Catch-all for all video types that don't require specific mime types + if (VideoFileExtensionsDictionary.ContainsKey(ext)) + { + return "video/" + ext.TrimStart('.').ToLower(); + } + + // Type text + if (StringHelper.EqualsIgnoreCase(ext, ".css")) + { + return "text/css"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".csv")) + { + return "text/csv"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".html")) + { + return "text/html; charset=UTF-8"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".htm")) + { + return "text/html; charset=UTF-8"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".txt")) + { + return "text/plain"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".xml")) + { + return "application/xml"; + } + + // Type audio + if (StringHelper.EqualsIgnoreCase(ext, ".mp3")) + { + return "audio/mpeg"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".m4a")) + { + return "audio/mp4"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".aac")) + { + return "audio/mp4"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".webma")) + { + return "audio/webm"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".wav")) + { + return "audio/wav"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".wma")) + { + return "audio/x-ms-wma"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".flac")) + { + return "audio/flac"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".aac")) + { + return "audio/x-aac"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".ogg")) + { + return "audio/ogg"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".oga")) + { + return "audio/ogg"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".opus")) + { + return "audio/ogg"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".ac3")) + { + return "audio/ac3"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".dsf")) + { + return "audio/dsf"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".m4b")) + { + return "audio/m4b"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".xsp")) + { + return "audio/xsp"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".dsp")) + { + return "audio/dsp"; + } + + // Playlists + if (StringHelper.EqualsIgnoreCase(ext, ".m3u8")) + { + return "application/x-mpegURL"; + } + + // Misc + if (StringHelper.EqualsIgnoreCase(ext, ".dll")) + { + return "application/octet-stream"; + } + + // Web + if (StringHelper.EqualsIgnoreCase(ext, ".js")) + { + return "application/x-javascript"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".json")) + { + return "application/json"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".map")) + { + return "application/x-javascript"; + } + + if (StringHelper.EqualsIgnoreCase(ext, ".woff")) + { + return "font/woff"; + } + + if (StringHelper.EqualsIgnoreCase(ext, ".ttf")) + { + return "font/ttf"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".eot")) + { + return "application/vnd.ms-fontobject"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".svg")) + { + return "image/svg+xml"; + } + if (StringHelper.EqualsIgnoreCase(ext, ".svgz")) + { + return "image/svg+xml"; + } + + if (StringHelper.EqualsIgnoreCase(ext, ".srt")) + { + return "text/plain"; + } + + if (StringHelper.EqualsIgnoreCase(ext, ".vtt")) + { + return "text/vtt"; + } + + if (StringHelper.EqualsIgnoreCase(ext, ".ttml")) + { + return "application/ttml+xml"; + } + + if (enableStreamDefault) + { + return "application/octet-stream"; + } + + return null; + } + + public static string ToExtension(string mimeType) + { + if (string.IsNullOrEmpty(mimeType)) + { + throw new ArgumentNullException("mimeType"); + } + + // handle text/html; charset=UTF-8 + mimeType = mimeType.Split(';')[0]; + + string result; + if (ExtensionLookup.TryGetValue(mimeType, out result)) + { + return result; + } + return null; + } + } +} diff --git a/MediaBrowser.Model/Net/NetworkShare.cs b/MediaBrowser.Model/Net/NetworkShare.cs new file mode 100644 index 000000000..5ce84eeed --- /dev/null +++ b/MediaBrowser.Model/Net/NetworkShare.cs @@ -0,0 +1,31 @@ + +namespace MediaBrowser.Model.Net +{ + public class NetworkShare + { + /// <summary> + /// The name of the computer that this share belongs to + /// </summary> + public string Server { get; set; } + + /// <summary> + /// Share name + /// </summary> + public string Name { get; set; } + + /// <summary> + /// Local path + /// </summary> + public string Path { get; set; } + + /// <summary> + /// Share type + /// </summary> + public NetworkShareType ShareType { get; set; } + + /// <summary> + /// Comment + /// </summary> + public string Remark { get; set; } + } +} diff --git a/MediaBrowser.Model/Net/NetworkShareType.cs b/MediaBrowser.Model/Net/NetworkShareType.cs new file mode 100644 index 000000000..41dc9003e --- /dev/null +++ b/MediaBrowser.Model/Net/NetworkShareType.cs @@ -0,0 +1,30 @@ + +namespace MediaBrowser.Model.Net +{ + /// <summary> + /// Enum NetworkShareType + /// </summary> + public enum NetworkShareType + { + /// <summary> + /// Disk share + /// </summary> + Disk, + /// <summary> + /// Printer share + /// </summary> + Printer, + /// <summary> + /// Device share + /// </summary> + Device, + /// <summary> + /// IPC share + /// </summary> + Ipc, + /// <summary> + /// Special share + /// </summary> + Special + } +} diff --git a/MediaBrowser.Model/Net/SocketReceiveResult.cs b/MediaBrowser.Model/Net/SocketReceiveResult.cs new file mode 100644 index 000000000..483e2297b --- /dev/null +++ b/MediaBrowser.Model/Net/SocketReceiveResult.cs @@ -0,0 +1,25 @@ + +namespace MediaBrowser.Model.Net +{ + /// <summary> + /// Used by the sockets wrapper to hold raw data received from a UDP socket. + /// </summary> + public sealed class SocketReceiveResult + { + /// <summary> + /// The buffer to place received data into. + /// </summary> + public byte[] Buffer { get; set; } + + /// <summary> + /// The number of bytes received. + /// </summary> + public int ReceivedBytes { get; set; } + + /// <summary> + /// The <see cref="IpEndPointInfo"/> the data was received from. + /// </summary> + public IpEndPointInfo RemoteEndPoint { get; set; } + public IpAddressInfo LocalIPAddress { get; set; } + } +} diff --git a/MediaBrowser.Model/Net/WebSocketMessage.cs b/MediaBrowser.Model/Net/WebSocketMessage.cs new file mode 100644 index 000000000..c049a96ef --- /dev/null +++ b/MediaBrowser.Model/Net/WebSocketMessage.cs @@ -0,0 +1,24 @@ + +namespace MediaBrowser.Model.Net +{ + /// <summary> + /// Class WebSocketMessage + /// </summary> + /// <typeparam name="T"></typeparam> + public class WebSocketMessage<T> + { + /// <summary> + /// Gets or sets the type of the message. + /// </summary> + /// <value>The type of the message.</value> + public string MessageType { get; set; } + public string MessageId { get; set; } + public string ServerId { get; set; } + /// <summary> + /// Gets or sets the data. + /// </summary> + /// <value>The data.</value> + public T Data { get; set; } + } + +} |
