aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emby.Common.Implementations/Archiving/ZipClient.cs (renamed from MediaBrowser.Server.Implementations/Archiving/ZipClient.cs)37
-rw-r--r--Emby.Common.Implementations/BaseApplicationHost.cs33
-rw-r--r--Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs29
-rw-r--r--Emby.Common.Implementations/IO/ManagedFileSystem.cs5
-rw-r--r--Emby.Common.Implementations/Net/NetSocket.cs6
-rw-r--r--Emby.Common.Implementations/Net/UdpSocket.cs2
-rw-r--r--Emby.Common.Implementations/Networking/NetworkManager.cs (renamed from Emby.Common.Implementations/Networking/BaseNetworkManager.cs)25
-rw-r--r--Emby.Common.Implementations/Serialization/JsonSerializer.cs (renamed from MediaBrowser.Server.Implementations/Serialization/JsonSerializer.cs)2
-rw-r--r--Emby.Common.Implementations/project.json47
-rw-r--r--Emby.Dlna/project.json (renamed from Emby.Server.Implementations/project.json)2
-rw-r--r--Emby.Drawing.ImageMagick/Emby.Drawing.ImageMagick.csproj83
-rw-r--r--Emby.Drawing.ImageMagick/ImageHelpers.cs43
-rw-r--r--Emby.Drawing.ImageMagick/ImageMagickEncoder.cs (renamed from Emby.Drawing/ImageMagick/ImageMagickEncoder.cs)13
-rw-r--r--Emby.Drawing.ImageMagick/PercentPlayedDrawer.cs (renamed from Emby.Drawing/ImageMagick/PercentPlayedDrawer.cs)0
-rw-r--r--Emby.Drawing.ImageMagick/PlayedIndicatorDrawer.cs (renamed from Emby.Drawing/ImageMagick/PlayedIndicatorDrawer.cs)0
-rw-r--r--Emby.Drawing.ImageMagick/Properties/AssemblyInfo.cs36
-rw-r--r--Emby.Drawing.ImageMagick/StripCollageBuilder.cs (renamed from Emby.Drawing/ImageMagick/StripCollageBuilder.cs)0
-rw-r--r--Emby.Drawing.ImageMagick/UnplayedCountIndicator.cs (renamed from Emby.Drawing/ImageMagick/UnplayedCountIndicator.cs)0
-rw-r--r--Emby.Drawing.ImageMagick/packages.config (renamed from Emby.Drawing/packages.config)2
-rw-r--r--Emby.Drawing.Net/DynamicImageHelpers.cs (renamed from Emby.Drawing/GDI/DynamicImageHelpers.cs)2
-rw-r--r--Emby.Drawing.Net/Emby.Drawing.Net.csproj78
-rw-r--r--Emby.Drawing.Net/GDIImageEncoder.cs (renamed from Emby.Drawing/GDI/GDIImageEncoder.cs)2
-rw-r--r--Emby.Drawing.Net/ImageExtensions.cs (renamed from Emby.Drawing/GDI/ImageExtensions.cs)2
-rw-r--r--Emby.Drawing.Net/ImageHelpers.cs (renamed from Emby.Drawing/ImageHelpers.cs)2
-rw-r--r--Emby.Drawing.Net/PercentPlayedDrawer.cs (renamed from Emby.Drawing/GDI/PercentPlayedDrawer.cs)2
-rw-r--r--Emby.Drawing.Net/PlayedIndicatorDrawer.cs (renamed from Emby.Drawing/GDI/PlayedIndicatorDrawer.cs)2
-rw-r--r--Emby.Drawing.Net/Properties/AssemblyInfo.cs36
-rw-r--r--Emby.Drawing.Net/UnplayedCountIndicator.cs (renamed from Emby.Drawing/GDI/UnplayedCountIndicator.cs)2
-rw-r--r--Emby.Drawing.Net/empty.png (renamed from Emby.Drawing/GDI/empty.png)bin158 -> 158 bytes
-rw-r--r--Emby.Drawing/Common/ImageHeader.cs2
-rw-r--r--Emby.Drawing/Emby.Drawing.csproj42
-rw-r--r--Emby.Drawing/ImageProcessor.cs14
-rw-r--r--Emby.Drawing/project.json17
-rw-r--r--Emby.Server.Core/Activity/ActivityRepository.cs (renamed from MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs)14
-rw-r--r--Emby.Server.Core/ApplicationHost.cs (renamed from MediaBrowser.Server.Startup.Common/ApplicationHost.cs)228
-rw-r--r--Emby.Server.Core/Browser/BrowserLauncher.cs (renamed from MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs)2
-rw-r--r--Emby.Server.Core/Configuration/ServerConfigurationManager.cs (renamed from MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs)16
-rw-r--r--Emby.Server.Core/Data/BaseSqliteRepository.cs (renamed from MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs)6
-rw-r--r--Emby.Server.Core/Data/DataExtensions.cs (renamed from MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs)13
-rw-r--r--Emby.Server.Core/Data/IDbConnector.cs (renamed from MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs)2
-rw-r--r--Emby.Server.Core/Data/MediaStreamColumns.cs (renamed from MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs)2
-rw-r--r--Emby.Server.Core/Data/SqliteDisplayPreferencesRepository.cs (renamed from MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs)17
-rw-r--r--Emby.Server.Core/Data/SqliteFileOrganizationRepository.cs (renamed from MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs)14
-rw-r--r--Emby.Server.Core/Data/SqliteItemRepository.cs (renamed from MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs)25
-rw-r--r--Emby.Server.Core/Data/SqliteUserDataRepository.cs (renamed from MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs)12
-rw-r--r--Emby.Server.Core/Data/SqliteUserRepository.cs (renamed from MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs)15
-rw-r--r--Emby.Server.Core/Data/TypeMapper.cs (renamed from MediaBrowser.Server.Implementations/Persistence/TypeMapper.cs)2
-rw-r--r--Emby.Server.Core/Devices/DeviceRepository.cs (renamed from MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs)18
-rw-r--r--Emby.Server.Core/Emby.Server.Core.xproj34
-rw-r--r--Emby.Server.Core/EntryPoints/ExternalPortForwarding.cs (renamed from MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs)15
-rw-r--r--Emby.Server.Core/EntryPoints/StartupWizard.cs (renamed from MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs)4
-rw-r--r--Emby.Server.Core/FFMpeg/FFMpegInfo.cs (renamed from MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInfo.cs)2
-rw-r--r--Emby.Server.Core/FFMpeg/FFMpegInstallInfo.cs (renamed from MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInstallInfo.cs)2
-rw-r--r--Emby.Server.Core/FFMpeg/FFMpegLoader.cs (renamed from MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs)22
-rw-r--r--Emby.Server.Core/HttpServerFactory.cs107
-rw-r--r--Emby.Server.Core/INativeApp.cs (renamed from MediaBrowser.Server.Startup.Common/INativeApp.cs)29
-rw-r--r--Emby.Server.Core/IO/LibraryMonitor.cs (renamed from MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs)22
-rw-r--r--Emby.Server.Core/Localization/TextLocalizer.cs (renamed from MediaBrowser.Server.Startup.Common/TextLocalizer.cs)2
-rw-r--r--Emby.Server.Core/Migrations/DbMigration.cs (renamed from MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs)4
-rw-r--r--Emby.Server.Core/Migrations/IVersionMigration.cs (renamed from MediaBrowser.Server.Startup.Common/Migrations/IVersionMigration.cs)2
-rw-r--r--Emby.Server.Core/Migrations/UpdateLevelMigration.cs (renamed from MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs)2
-rw-r--r--Emby.Server.Core/Notifications/SqliteNotificationsRepository.cs (renamed from MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs)14
-rw-r--r--Emby.Server.Core/Properties/AssemblyInfo.cs19
-rw-r--r--Emby.Server.Core/Security/AuthenticationRepository.cs (renamed from MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs)14
-rw-r--r--Emby.Server.Core/ServerApplicationPaths.cs (renamed from MediaBrowser.Server.Implementations/ServerApplicationPaths.cs)6
-rw-r--r--Emby.Server.Core/Social/SharingRepository.cs (renamed from MediaBrowser.Server.Implementations/Social/SharingRepository.cs)12
-rw-r--r--Emby.Server.Core/StartupOptions.cs (renamed from MediaBrowser.Server.Startup.Common/StartupOptions.cs)2
-rw-r--r--Emby.Server.Core/Sync/SyncRepository.cs (renamed from MediaBrowser.Server.Implementations/Sync/SyncRepository.cs)20
-rw-r--r--Emby.Server.Core/UnhandledExceptionWriter.cs (renamed from MediaBrowser.Server.Startup.Common/UnhandledExceptionWriter.cs)2
-rw-r--r--Emby.Server.Core/project.json131
-rw-r--r--Emby.Server.Implementations/Collections/CollectionsDynamicFolder.cs (renamed from MediaBrowser.Server.Implementations/Collections/CollectionsDynamicFolder.cs)2
-rw-r--r--Emby.Server.Implementations/Devices/CameraUploadsDynamicFolder.cs41
-rw-r--r--Emby.Server.Implementations/Emby.Server.Implementations.csproj146
-rw-r--r--Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs3
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpListenerHost.cs (renamed from MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs)172
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpResultFactory.cs (renamed from MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs)46
-rw-r--r--Emby.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs (renamed from MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs)101
-rw-r--r--Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs3
-rw-r--r--Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs (renamed from MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs)77
-rw-r--r--Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs (renamed from MediaBrowser.Server.Startup.Common/MbLinkShortcutHandler.cs)4
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs13
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs3
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs6
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs6
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs3
-rw-r--r--Emby.Server.Implementations/Library/Validators/PeopleValidator.cs18
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs8
-rw-r--r--Emby.Server.Implementations/Logging/PatternsLogger.cs63
-rw-r--r--Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs32
-rw-r--r--Emby.Server.Implementations/ServerManager/ServerManager.cs8
-rw-r--r--Emby.Server.Implementations/packages.config5
-rw-r--r--Emby.Server.sln130
-rw-r--r--MediaBrowser.Common/Net/INetworkManager.cs7
-rw-r--r--MediaBrowser.Controller/Drawing/IImageEncoder.cs (renamed from Emby.Drawing/IImageEncoder.cs)5
-rw-r--r--MediaBrowser.Controller/IServerApplicationHost.cs6
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj1
-rw-r--r--MediaBrowser.Controller/Net/IHttpServer.cs10
-rw-r--r--MediaBrowser.Controller/Net/IServerManager.cs4
-rw-r--r--MediaBrowser.LocalMetadata/Providers/PersonXmlProvider.cs42
-rw-r--r--MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs88
-rw-r--r--MediaBrowser.Model/IO/IFileSystem.cs2
-rw-r--r--MediaBrowser.Model/Services/IRequest.cs5
-rw-r--r--MediaBrowser.Model/System/Architecture.cs3
-rw-r--r--MediaBrowser.Model/System/IEnvironmentInfo.cs1
-rw-r--r--MediaBrowser.Mono.sln154
-rw-r--r--MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs27
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs39
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj294
-rw-r--r--MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs41
-rw-r--r--MediaBrowser.Server.Implementations/packages.config9
-rw-r--r--MediaBrowser.Server.Implementations/project.json17
-rw-r--r--MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj25
-rw-r--r--MediaBrowser.Server.Mono/Native/DbConnector.cs2
-rw-r--r--MediaBrowser.Server.Mono/Native/MonoApp.cs153
-rw-r--r--MediaBrowser.Server.Mono/Native/MonoFileSystem.cs21
-rw-r--r--MediaBrowser.Server.Mono/Program.cs127
-rw-r--r--MediaBrowser.Server.Mono/packages.config4
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/ASN1.cs (renamed from MediaBrowser.Server.Startup.Common/Security/ASN1.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/ASN1Convert.cs (renamed from MediaBrowser.Server.Startup.Common/Security/ASN1Convert.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/BitConverterLE.cs (renamed from MediaBrowser.Server.Startup.Common/Security/BitConverterLE.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/CertificateGenerator.cs (renamed from MediaBrowser.Server.Startup.Common/Security/CertificateGenerator.cs)4
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/CryptoConvert.cs (renamed from MediaBrowser.Server.Startup.Common/Security/CryptoConvert.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/PKCS1.cs (renamed from MediaBrowser.Server.Startup.Common/Security/PKCS1.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/PKCS12.cs (renamed from MediaBrowser.Server.Startup.Common/Security/PKCS12.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/PKCS7.cs (renamed from MediaBrowser.Server.Startup.Common/Security/PKCS7.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/PKCS8.cs (renamed from MediaBrowser.Server.Startup.Common/Security/PKCS8.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/PfxGenerator.cs (renamed from MediaBrowser.Server.Startup.Common/Security/PfxGenerator.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X501Name.cs (renamed from MediaBrowser.Server.Startup.Common/Security/X501Name.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509Builder.cs (renamed from MediaBrowser.Server.Startup.Common/Security/X509Builder.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509Certificate.cs (renamed from MediaBrowser.Server.Startup.Common/Security/X509Certificate.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateBuilder.cs (renamed from MediaBrowser.Server.Startup.Common/Security/X509CertificateBuilder.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateCollection.cs (renamed from MediaBrowser.Server.Startup.Common/Security/X509CertificateCollection.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509Extension.cs (renamed from MediaBrowser.Server.Startup.Common/Security/X509Extension.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509Extensions.cs (renamed from MediaBrowser.Server.Startup.Common/Security/X509Extensions.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X520Attributes.cs (renamed from MediaBrowser.Server.Startup.Common/Security/X520Attributes.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/IO/MemoryStreamProvider.cs (renamed from MediaBrowser.Server.Implementations/IO/MemoryStreamProvider.cs)2
-rw-r--r--MediaBrowser.Server.Startup.Common/ImageEncoderHelper.cs47
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ChannelScan.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ChannelScan.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/TransmissionMode.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/TransmissionMode.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Utils.cs (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Utils.cs)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0030.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0030.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0049.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0049.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0070.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0070.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0090.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0090.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0100.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0100.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0130.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0130.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0160.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0160.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0170.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0170.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0192.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0192.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0200.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0200.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0215.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0215.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0235.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0235.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0255.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0255.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0260.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0260.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0282.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0282.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0305.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0305.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0308.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0308.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0310.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0310.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0315.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0315.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0330.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0330.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0360.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0360.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0380.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0380.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0390.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0390.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0400.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0400.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0420.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0420.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0435.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0435.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0450.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0450.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0460.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0460.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0475.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0475.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0480.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0480.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0490.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0490.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0505.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0505.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0510.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0510.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0520.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0520.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0525.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0525.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0530.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0530.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0549.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0549.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0560.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0560.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0570.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0570.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0600.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0600.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0620.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0620.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0642.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0642.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0650.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0650.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0660.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0660.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0685.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0685.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0705.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0705.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0721.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0721.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0740.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0740.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0750.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0750.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0765.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0765.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0785.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0785.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0830.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0830.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0851.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0851.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0865.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0865.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0875.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0875.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0880.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0880.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0900.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0900.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0915.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0915.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0922.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0922.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0935.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0935.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0950.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0950.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0965.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0965.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1005.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1005.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1030.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1030.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1055.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1055.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1082.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1082.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1100.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1100.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1105.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1105.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1130.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1130.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1155.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1155.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1160.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1160.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1180.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1180.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1195.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1195.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1222.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1222.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1240.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1240.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1250.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1250.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1280.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1280.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1320.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1320.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1340.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1340.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1380.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1380.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1400.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1400.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1440.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1440.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1500.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1500.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1520.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1520.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1540.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1540.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1560.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1560.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1590.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1590.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600 OPTUS D1 FTA (160.0E).ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1600 OPTUS D1 FTA (160.0E).ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1600.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1620.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1620.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1640.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1640.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1660.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1660.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1690.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1690.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1720.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1720.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1800.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1800.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1830.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1830.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2210.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2210.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2230.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2230.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2250.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2250.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2270.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2270.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2290.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2290.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2310.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2310.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2330.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2330.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2350.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2350.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2370.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2370.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2390.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2390.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2410.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2410.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2432.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2432.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2451.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2451.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2470.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2470.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2489.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2489.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2500.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2500.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2527.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2527.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2550.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2550.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2570.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2570.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2590.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2590.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2608.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2608.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2630.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2630.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2650.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2650.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2669.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2669.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2690.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2690.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2710.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2710.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2728.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2728.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2730.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2730.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2750.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2750.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2760.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2760.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2770.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2770.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2780.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2780.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2812.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2812.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2820.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2820.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2830.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2830.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2850.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2850.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2873.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2873.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2880.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2880.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2881.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2881.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2882.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2882.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2900.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2900.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2930.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2930.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2950.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2950.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2970.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2970.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2985.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2985.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2990.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2990.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3020.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3020.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3045.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3045.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3070.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3070.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3100.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3100.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3125.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3125.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3150.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3150.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3169.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3169.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3195.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3195.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3225.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3225.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3255.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3255.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3285.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3285.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3300.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3300.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3325.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3325.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3355.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3355.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3380.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3380.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3400.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3400.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3420.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3420.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3450.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3450.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3460.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3460.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3475.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3475.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3490.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3490.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3520.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3520.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3527.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3527.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3550.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3550.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3560.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3560.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3592.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3592.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3594.ini (renamed from MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3594.ini)0
-rw-r--r--MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj322
-rw-r--r--MediaBrowser.Server.Startup.Common/NativeEnvironment.cs19
-rw-r--r--MediaBrowser.Server.Startup.Common/Networking/NetworkManager.cs50
-rw-r--r--MediaBrowser.Server.Startup.Common/Persistence/SqliteExtensions.cs (renamed from MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs)2
-rw-r--r--MediaBrowser.Server.Startup.Common/packages.config6
-rw-r--r--MediaBrowser.ServerApplication/MainStartup.cs30
-rw-r--r--MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj63
-rw-r--r--MediaBrowser.ServerApplication/Native/DbConnector.cs2
-rw-r--r--MediaBrowser.ServerApplication/Native/WindowsApp.cs20
-rw-r--r--MediaBrowser.ServerApplication/Networking/NetworkManager.cs2
-rw-r--r--MediaBrowser.ServerApplication/ServerNotifyIcon.cs2
-rw-r--r--MediaBrowser.ServerApplication/packages.config4
-rw-r--r--MediaBrowser.WebDashboard/packages.config2
-rw-r--r--MediaBrowser.sln455
-rw-r--r--RSSDP/project.json17
-rw-r--r--ServiceStack/FilterAttributeCache.cs27
-rw-r--r--ServiceStack/Host/ActionContext.cs27
-rw-r--r--ServiceStack/Host/ContentTypes.cs77
-rw-r--r--ServiceStack/Host/HttpResponseStreamWrapper.cs95
-rw-r--r--ServiceStack/Host/RestHandler.cs200
-rw-r--r--ServiceStack/Host/RestPath.cs443
-rw-r--r--ServiceStack/Host/ServiceController.cs220
-rw-r--r--ServiceStack/Host/ServiceExec.cs156
-rw-r--r--ServiceStack/Host/ServiceMetadata.cs27
-rw-r--r--ServiceStack/HttpHandlerFactory.cs27
-rw-r--r--ServiceStack/HttpRequestExtensions.cs127
-rw-r--r--ServiceStack/HttpResponseExtensionsInternal.cs237
-rw-r--r--ServiceStack/HttpResult.cs250
-rw-r--r--ServiceStack/HttpUtils.cs34
-rw-r--r--ServiceStack/Properties/AssemblyInfo.cs25
-rw-r--r--ServiceStack/ReflectionExtensions.cs270
-rw-r--r--ServiceStack/ServiceStack.csproj131
-rw-r--r--ServiceStack/ServiceStack.nuget.targets (renamed from Emby.Server.Implementations/Emby.Server.Implementations.nuget.targets)0
-rw-r--r--ServiceStack/ServiceStackHost.Runtime.cs74
-rw-r--r--ServiceStack/ServiceStackHost.cs104
-rw-r--r--ServiceStack/StringMapTypeDeserializer.cs126
-rw-r--r--ServiceStack/UrlExtensions.cs33
-rw-r--r--ServiceStack/packages.config3
-rw-r--r--ServiceStack/project.json17
-rw-r--r--SocketHttpListener.Portable/ByteOrder.cs17
-rw-r--r--SocketHttpListener.Portable/CloseEventArgs.cs90
-rw-r--r--SocketHttpListener.Portable/CloseStatusCode.cs94
-rw-r--r--SocketHttpListener.Portable/CompressionMethod.cs23
-rw-r--r--SocketHttpListener.Portable/ErrorEventArgs.cs46
-rw-r--r--SocketHttpListener.Portable/Ext.cs1089
-rw-r--r--SocketHttpListener.Portable/Fin.cs8
-rw-r--r--SocketHttpListener.Portable/HttpBase.cs104
-rw-r--r--SocketHttpListener.Portable/HttpResponse.cs161
-rw-r--r--SocketHttpListener.Portable/Mask.cs8
-rw-r--r--SocketHttpListener.Portable/MessageEventArgs.cs96
-rw-r--r--SocketHttpListener.Portable/Net/AuthenticationSchemeSelector.cs6
-rw-r--r--SocketHttpListener.Portable/Net/ChunkStream.cs371
-rw-r--r--SocketHttpListener.Portable/Net/ChunkedInputStream.cs160
-rw-r--r--SocketHttpListener.Portable/Net/CookieHelper.cs144
-rw-r--r--SocketHttpListener.Portable/Net/EndPointListener.cs368
-rw-r--r--SocketHttpListener.Portable/Net/EndPointManager.cs165
-rw-r--r--SocketHttpListener.Portable/Net/HttpConnection.cs550
-rw-r--r--SocketHttpListener.Portable/Net/HttpListener.cs299
-rw-r--r--SocketHttpListener.Portable/Net/HttpListenerBasicIdentity.cs70
-rw-r--r--SocketHttpListener.Portable/Net/HttpListenerContext.cs201
-rw-r--r--SocketHttpListener.Portable/Net/HttpListenerPrefixCollection.cs97
-rw-r--r--SocketHttpListener.Portable/Net/HttpListenerRequest.cs654
-rw-r--r--SocketHttpListener.Portable/Net/HttpListenerResponse.cs517
-rw-r--r--SocketHttpListener.Portable/Net/HttpStatusCode.cs321
-rw-r--r--SocketHttpListener.Portable/Net/HttpStreamAsyncResult.cs77
-rw-r--r--SocketHttpListener.Portable/Net/HttpVersion.cs16
-rw-r--r--SocketHttpListener.Portable/Net/ListenerPrefix.cs148
-rw-r--r--SocketHttpListener.Portable/Net/RequestStream.cs231
-rw-r--r--SocketHttpListener.Portable/Net/ResponseStream.cs316
-rw-r--r--SocketHttpListener.Portable/Net/WebHeaderCollection.cs391
-rw-r--r--SocketHttpListener.Portable/Net/WebSockets/HttpListenerWebSocketContext.cs347
-rw-r--r--SocketHttpListener.Portable/Net/WebSockets/WebSocketContext.cs183
-rw-r--r--SocketHttpListener.Portable/Opcode.cs43
-rw-r--r--SocketHttpListener.Portable/PayloadData.cs149
-rw-r--r--SocketHttpListener.Portable/Primitives/HttpListenerException.cs17
-rw-r--r--SocketHttpListener.Portable/Primitives/ICertificate.cs12
-rw-r--r--SocketHttpListener.Portable/Primitives/IStreamFactory.cs18
-rw-r--r--SocketHttpListener.Portable/Primitives/ITextEncoding.cs17
-rw-r--r--SocketHttpListener.Portable/Properties/AssemblyInfo.cs30
-rw-r--r--SocketHttpListener.Portable/Rsv.cs8
-rw-r--r--SocketHttpListener.Portable/SocketHttpListener.Portable.csproj109
-rw-r--r--SocketHttpListener.Portable/SocketHttpListener.Portable.nuget.targets6
-rw-r--r--SocketHttpListener.Portable/WebSocket.cs898
-rw-r--r--SocketHttpListener.Portable/WebSocketException.cs60
-rw-r--r--SocketHttpListener.Portable/WebSocketFrame.cs578
-rw-r--r--SocketHttpListener.Portable/WebSocketState.cs35
-rw-r--r--SocketHttpListener.Portable/packages.config5
-rw-r--r--SocketHttpListener.Portable/project.json17
-rw-r--r--src/Emby.Server/Emby.Server.xproj10
-rw-r--r--src/Emby.Server/project.json35
418 files changed, 14825 insertions, 1767 deletions
diff --git a/MediaBrowser.Server.Implementations/Archiving/ZipClient.cs b/Emby.Common.Implementations/Archiving/ZipClient.cs
index 29b922436c..791c6678cd 100644
--- a/MediaBrowser.Server.Implementations/Archiving/ZipClient.cs
+++ b/Emby.Common.Implementations/Archiving/ZipClient.cs
@@ -1,13 +1,13 @@
using System.IO;
using MediaBrowser.Model.IO;
-using SharpCompress.Archive.Rar;
-using SharpCompress.Archive.SevenZip;
-using SharpCompress.Archive.Tar;
+using SharpCompress.Archives.Rar;
+using SharpCompress.Archives.SevenZip;
+using SharpCompress.Archives.Tar;
using SharpCompress.Common;
-using SharpCompress.Reader;
-using SharpCompress.Reader.Zip;
+using SharpCompress.Readers;
+using SharpCompress.Readers.Zip;
-namespace MediaBrowser.Server.Implementations.Archiving
+namespace Emby.Common.Implementations.Archiving
{
/// <summary>
/// Class DotNetZipClient
@@ -45,11 +45,12 @@ namespace MediaBrowser.Server.Implementations.Archiving
{
using (var reader = ReaderFactory.Open(source))
{
- var options = ExtractOptions.ExtractFullPath;
+ var options = new ExtractionOptions();
+ options.ExtractFullPath = true;
if (overwriteExistingFiles)
{
- options = options | ExtractOptions.Overwrite;
+ options.Overwrite = true;
}
reader.WriteAllToDirectory(targetPath, options);
@@ -60,11 +61,12 @@ namespace MediaBrowser.Server.Implementations.Archiving
{
using (var reader = ZipReader.Open(source))
{
- var options = ExtractOptions.ExtractFullPath;
+ var options = new ExtractionOptions();
+ options.ExtractFullPath = true;
if (overwriteExistingFiles)
{
- options = options | ExtractOptions.Overwrite;
+ options.Overwrite = true;
}
reader.WriteAllToDirectory(targetPath, options);
@@ -97,11 +99,12 @@ namespace MediaBrowser.Server.Implementations.Archiving
{
using (var reader = archive.ExtractAllEntries())
{
- var options = ExtractOptions.ExtractFullPath;
+ var options = new ExtractionOptions();
+ options.ExtractFullPath = true;
if (overwriteExistingFiles)
{
- options = options | ExtractOptions.Overwrite;
+ options.Overwrite = true;
}
reader.WriteAllToDirectory(targetPath, options);
@@ -136,11 +139,12 @@ namespace MediaBrowser.Server.Implementations.Archiving
{
using (var reader = archive.ExtractAllEntries())
{
- var options = ExtractOptions.ExtractFullPath;
+ var options = new ExtractionOptions();
+ options.ExtractFullPath = true;
if (overwriteExistingFiles)
{
- options = options | ExtractOptions.Overwrite;
+ options.Overwrite = true;
}
reader.WriteAllToDirectory(targetPath, options);
@@ -174,11 +178,12 @@ namespace MediaBrowser.Server.Implementations.Archiving
{
using (var reader = archive.ExtractAllEntries())
{
- var options = ExtractOptions.ExtractFullPath;
+ var options = new ExtractionOptions();
+ options.ExtractFullPath = true;
if (overwriteExistingFiles)
{
- options = options | ExtractOptions.Overwrite;
+ options.Overwrite = true;
}
reader.WriteAllToDirectory(targetPath, options);
diff --git a/Emby.Common.Implementations/BaseApplicationHost.cs b/Emby.Common.Implementations/BaseApplicationHost.cs
index 0cf11e8255..f0309511e0 100644
--- a/Emby.Common.Implementations/BaseApplicationHost.cs
+++ b/Emby.Common.Implementations/BaseApplicationHost.cs
@@ -152,8 +152,6 @@ namespace Emby.Common.Implementations
protected IIsoManager IsoManager { get; private set; }
- protected ISystemEvents SystemEvents { get; private set; }
-
protected IProcessFactory ProcessFactory { get; private set; }
protected ITimerFactory TimerFactory { get; private set; }
protected ISocketFactory SocketFactory { get; private set; }
@@ -172,7 +170,7 @@ namespace Emby.Common.Implementations
protected ICryptoProvider CryptographyProvider = new CryptographyProvider();
- protected IEnvironmentInfo EnvironmentInfo = new Emby.Common.Implementations.EnvironmentInfo.EnvironmentInfo();
+ protected IEnvironmentInfo EnvironmentInfo { get; private set; }
private DeviceId _deviceId;
public string SystemId
@@ -193,20 +191,30 @@ namespace Emby.Common.Implementations
get { return EnvironmentInfo.OperatingSystemName; }
}
- public IMemoryStreamFactory MemoryStreamProvider { get; set; }
-
/// <summary>
/// The container
/// </summary>
protected readonly SimpleInjector.Container Container = new SimpleInjector.Container();
+ protected ISystemEvents SystemEvents { get; private set; }
+ protected IMemoryStreamFactory MemoryStreamFactory { get; private set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="BaseApplicationHost{TApplicationPathsType}"/> class.
/// </summary>
protected BaseApplicationHost(TApplicationPathsType applicationPaths,
ILogManager logManager,
- IFileSystem fileSystem)
+ IFileSystem fileSystem,
+ IEnvironmentInfo environmentInfo,
+ ISystemEvents systemEvents,
+ IMemoryStreamFactory memoryStreamFactory,
+ INetworkManager networkManager)
{
+ NetworkManager = networkManager;
+ EnvironmentInfo = environmentInfo;
+ SystemEvents = systemEvents;
+ MemoryStreamFactory = memoryStreamFactory;
+
// hack alert, until common can target .net core
BaseExtensions.CryptographyProvider = CryptographyProvider;
@@ -233,9 +241,6 @@ namespace Emby.Common.Implementations
JsonSerializer = CreateJsonSerializer();
- MemoryStreamProvider = CreateMemoryStreamProvider();
- SystemEvents = CreateSystemEvents();
-
OnLoggerLoaded(true);
LogManager.LoggerLoaded += (s, e) => OnLoggerLoaded(false);
@@ -267,9 +272,6 @@ namespace Emby.Common.Implementations
progress.Report(100);
}
- protected abstract IMemoryStreamFactory CreateMemoryStreamProvider();
- protected abstract ISystemEvents CreateSystemEvents();
-
protected virtual void OnLoggerLoaded(bool isFirstLoad)
{
Logger.Info("Application version: {0}", ApplicationVersion);
@@ -521,7 +523,7 @@ return null;
RegisterSingleInstance(JsonSerializer);
RegisterSingleInstance(XmlSerializer);
- RegisterSingleInstance(MemoryStreamProvider);
+ RegisterSingleInstance(MemoryStreamFactory);
RegisterSingleInstance(SystemEvents);
RegisterSingleInstance(LogManager);
@@ -532,10 +534,9 @@ return null;
RegisterSingleInstance(FileSystemManager);
- HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamProvider);
+ HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamFactory);
RegisterSingleInstance(HttpClient);
- NetworkManager = CreateNetworkManager(LogManager.GetLogger("NetworkManager"));
RegisterSingleInstance(NetworkManager);
IsoManager = new IsoManager();
@@ -588,8 +589,6 @@ return null;
}
}
- protected abstract INetworkManager CreateNetworkManager(ILogger logger);
-
/// <summary>
/// Creates an instance of type and resolves all constructor dependancies
/// </summary>
diff --git a/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs b/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs
index 8cea617eae..6a1b3ef74c 100644
--- a/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs
+++ b/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs
@@ -9,6 +9,8 @@ namespace Emby.Common.Implementations.EnvironmentInfo
{
public class EnvironmentInfo : IEnvironmentInfo
{
+ public MediaBrowser.Model.System.Architecture? CustomArchitecture { get; set; }
+
public MediaBrowser.Model.System.OperatingSystem OperatingSystem
{
get
@@ -66,5 +68,32 @@ namespace Emby.Common.Implementations.EnvironmentInfo
return "1.0";
}
}
+
+ public MediaBrowser.Model.System.Architecture SystemArchitecture
+ {
+ get
+ {
+ if (CustomArchitecture.HasValue)
+ {
+ return CustomArchitecture.Value;
+ }
+#if NET46
+ return Environment.Is64BitOperatingSystem ? MediaBrowser.Model.System.Architecture.X64 : MediaBrowser.Model.System.Architecture.X86;
+#elif NETSTANDARD1_6
+ switch(System.Runtime.InteropServices.RuntimeInformation.OSArchitecture)
+ {
+ case System.Runtime.InteropServices.Architecture.Arm:
+ return MediaBrowser.Model.System.Architecture.Arm;
+ case System.Runtime.InteropServices.Architecture.Arm64:
+ return MediaBrowser.Model.System.Architecture.Arm64;
+ case System.Runtime.InteropServices.Architecture.X64:
+ return MediaBrowser.Model.System.Architecture.X64;
+ case System.Runtime.InteropServices.Architecture.X86:
+ return MediaBrowser.Model.System.Architecture.X86;
+ }
+#endif
+ return MediaBrowser.Model.System.Architecture.X64;
+ }
+ }
}
}
diff --git a/Emby.Common.Implementations/IO/ManagedFileSystem.cs b/Emby.Common.Implementations/IO/ManagedFileSystem.cs
index 37b4575987..81ca8dcff2 100644
--- a/Emby.Common.Implementations/IO/ManagedFileSystem.cs
+++ b/Emby.Common.Implementations/IO/ManagedFileSystem.cs
@@ -761,5 +761,10 @@ namespace Emby.Common.Implementations.IO
var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
return Directory.EnumerateFileSystemEntries(path, "*", searchOption);
}
+
+ public virtual void SetExecutable(string path)
+ {
+
+ }
}
}
diff --git a/Emby.Common.Implementations/Net/NetSocket.cs b/Emby.Common.Implementations/Net/NetSocket.cs
index 72faa41a9a..faa1a81e2d 100644
--- a/Emby.Common.Implementations/Net/NetSocket.cs
+++ b/Emby.Common.Implementations/Net/NetSocket.cs
@@ -23,7 +23,7 @@ namespace Emby.Common.Implementations.Net
{
get
{
- return BaseNetworkManager.ToIpEndPointInfo((IPEndPoint)Socket.LocalEndPoint);
+ return NetworkManager.ToIpEndPointInfo((IPEndPoint)Socket.LocalEndPoint);
}
}
@@ -31,7 +31,7 @@ namespace Emby.Common.Implementations.Net
{
get
{
- return BaseNetworkManager.ToIpEndPointInfo((IPEndPoint)Socket.RemoteEndPoint);
+ return NetworkManager.ToIpEndPointInfo((IPEndPoint)Socket.RemoteEndPoint);
}
}
@@ -64,7 +64,7 @@ namespace Emby.Common.Implementations.Net
public void Bind(IpEndPointInfo endpoint)
{
- var nativeEndpoint = BaseNetworkManager.ToIPEndPoint(endpoint);
+ var nativeEndpoint = NetworkManager.ToIPEndPoint(endpoint);
Socket.Bind(nativeEndpoint);
}
diff --git a/Emby.Common.Implementations/Net/UdpSocket.cs b/Emby.Common.Implementations/Net/UdpSocket.cs
index 244b37bb41..eca82034b0 100644
--- a/Emby.Common.Implementations/Net/UdpSocket.cs
+++ b/Emby.Common.Implementations/Net/UdpSocket.cs
@@ -175,7 +175,7 @@ namespace Emby.Common.Implementations.Net
return null;
}
- return BaseNetworkManager.ToIpEndPointInfo(endpoint);
+ return NetworkManager.ToIpEndPointInfo(endpoint);
}
private void ProcessResponse(IAsyncResult asyncResult)
diff --git a/Emby.Common.Implementations/Networking/BaseNetworkManager.cs b/Emby.Common.Implementations/Networking/NetworkManager.cs
index f1ac8413be..e336973377 100644
--- a/Emby.Common.Implementations/Networking/BaseNetworkManager.cs
+++ b/Emby.Common.Implementations/Networking/NetworkManager.cs
@@ -9,15 +9,17 @@ using System.Net.Sockets;
using System.Threading.Tasks;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Net;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Common.Net;
namespace Emby.Common.Implementations.Networking
{
- public abstract class BaseNetworkManager
+ public class NetworkManager : INetworkManager
{
protected ILogger Logger { get; private set; }
private DateTime _lastRefresh;
- protected BaseNetworkManager(ILogger logger)
+ public NetworkManager(ILogger logger)
{
Logger = logger;
}
@@ -481,5 +483,24 @@ namespace Emby.Common.Implementations.Networking
var addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false);
return addresses.Select(ToIpAddressInfo).ToArray();
}
+
+ /// <summary>
+ /// Gets the network shares.
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <returns>IEnumerable{NetworkShare}.</returns>
+ public IEnumerable<NetworkShare> GetNetworkShares(string path)
+ {
+ return new List<NetworkShare>();
+ }
+
+ /// <summary>
+ /// Gets available devices within the domain
+ /// </summary>
+ /// <returns>PC's in the Domain</returns>
+ public IEnumerable<FileSystemEntryInfo> GetNetworkDevices()
+ {
+ return new List<FileSystemEntryInfo>();
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Serialization/JsonSerializer.cs b/Emby.Common.Implementations/Serialization/JsonSerializer.cs
index b9a03242c0..c9db336890 100644
--- a/MediaBrowser.Server.Implementations/Serialization/JsonSerializer.cs
+++ b/Emby.Common.Implementations/Serialization/JsonSerializer.cs
@@ -4,7 +4,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
-namespace MediaBrowser.Server.Implementations.Serialization
+namespace Emby.Common.Implementations.Serialization
{
/// <summary>
/// Provides a wrapper around third party json serialization.
diff --git a/Emby.Common.Implementations/project.json b/Emby.Common.Implementations/project.json
index 2b2357e383..b0a35bdf38 100644
--- a/Emby.Common.Implementations/project.json
+++ b/Emby.Common.Implementations/project.json
@@ -2,7 +2,7 @@
"version": "1.0.0-*",
"dependencies": {
-
+
},
"frameworks": {
@@ -19,46 +19,51 @@
"System.Text.Encoding": "4.0.0.0",
"System.Threading": "4.0.0.0",
"System.Threading.Tasks": "4.0.0.0",
- "System.Xml.ReaderWriter": "4.0.0"
+ "System.Xml.ReaderWriter": "4.0.0"
},
"dependencies": {
"SimpleInjector": "3.2.4",
+ "ServiceStack.Text": "4.5.4",
"NLog": "4.4.0-betaV15",
+ "sharpcompress": "0.14.0",
"MediaBrowser.Model": {
"target": "project"
},
"MediaBrowser.Common": {
"target": "project"
- }
- }
+ }
+ }
},
"netstandard1.6": {
"imports": "dnxcore50",
"dependencies": {
"NETStandard.Library": "1.6.0",
- "System.IO.FileSystem.DriveInfo": "4.0.0",
- "System.Diagnostics.Process": "4.1.0",
- "System.Threading.Timer": "4.0.1",
- "System.Net.Requests": "4.0.11",
- "System.Xml.ReaderWriter": "4.0.11",
- "System.Xml.XmlSerializer": "4.0.11",
- "System.Net.Http": "4.1.0",
- "System.Net.Primitives": "4.0.11",
- "System.Net.Sockets": "4.1.0",
- "System.Net.NetworkInformation": "4.1.0",
- "System.Net.NameResolution": "4.0.0",
- "System.Runtime.InteropServices.RuntimeInformation": "4.0.0",
- "System.Reflection": "4.1.0",
- "System.Reflection.Primitives": "4.0.1",
- "System.Runtime.Loader": "4.0.0",
- "SimpleInjector": "3.2.4",
+ "System.IO.FileSystem.DriveInfo": "4.0.0",
+ "System.Diagnostics.Process": "4.1.0",
+ "System.Threading.Timer": "4.0.1",
+ "System.Net.Requests": "4.0.11",
+ "System.Xml.ReaderWriter": "4.0.11",
+ "System.Xml.XmlSerializer": "4.0.11",
+ "System.Net.Http": "4.1.0",
+ "System.Net.Primitives": "4.0.11",
+ "System.Net.Sockets": "4.1.0",
+ "System.Net.NetworkInformation": "4.1.0",
+ "System.Net.NameResolution": "4.0.0",
+ "System.Runtime.InteropServices.RuntimeInformation": "4.0.0",
+ "System.Reflection": "4.1.0",
+ "System.Reflection.Primitives": "4.0.1",
+ "System.Runtime.Loader": "4.0.0",
+ "SimpleInjector": "3.2.4",
+ "ServiceStack.Text.Core": "1.0.27",
"NLog": "4.4.0-betaV15",
+ "sharpcompress": "0.14.0",
"MediaBrowser.Model": {
"target": "project"
},
"MediaBrowser.Common": {
"target": "project"
- } }
+ }
+ }
}
}
}
diff --git a/Emby.Server.Implementations/project.json b/Emby.Dlna/project.json
index 13bdedb418..fbbe9eaf32 100644
--- a/Emby.Server.Implementations/project.json
+++ b/Emby.Dlna/project.json
@@ -1,4 +1,4 @@
-{
+{
"frameworks":{
"netstandard1.6":{
"dependencies":{
diff --git a/Emby.Drawing.ImageMagick/Emby.Drawing.ImageMagick.csproj b/Emby.Drawing.ImageMagick/Emby.Drawing.ImageMagick.csproj
new file mode 100644
index 0000000000..98e99c92b1
--- /dev/null
+++ b/Emby.Drawing.ImageMagick/Emby.Drawing.ImageMagick.csproj
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{6CFEE013-6E7C-432B-AC37-CABF0880C69A}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Emby.Drawing.ImageMagick</RootNamespace>
+ <AssemblyName>Emby.Drawing.ImageMagick</AssemblyName>
+ <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\ImageMagickSharp.1.0.0.18\lib\net45\ImageMagickSharp.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ImageHelpers.cs" />
+ <Compile Include="ImageMagickEncoder.cs" />
+ <Compile Include="PercentPlayedDrawer.cs" />
+ <Compile Include="PlayedIndicatorDrawer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="StripCollageBuilder.cs" />
+ <Compile Include="UnplayedCountIndicator.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="fonts\robotoregular.ttf" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
+ <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
+ <Name>MediaBrowser.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
+ <Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
+ <Name>MediaBrowser.Controller</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
+ <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
+ <Name>MediaBrowser.Model</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/Emby.Drawing.ImageMagick/ImageHelpers.cs b/Emby.Drawing.ImageMagick/ImageHelpers.cs
new file mode 100644
index 0000000000..c623c21aa2
--- /dev/null
+++ b/Emby.Drawing.ImageMagick/ImageHelpers.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Emby.Drawing.ImageMagick
+{
+ internal static class ImageHelpers
+ {
+ internal static List<string> ProjectPaths(List<string> paths, int count)
+ {
+ if (count <= 0)
+ {
+ throw new ArgumentOutOfRangeException("count");
+ }
+ if (paths.Count == 0)
+ {
+ throw new ArgumentOutOfRangeException("paths");
+ }
+
+ var list = new List<string>();
+
+ AddToList(list, paths, count);
+
+ return list.Take(count).ToList();
+ }
+
+ private static void AddToList(List<string> list, List<string> paths, int count)
+ {
+ while (list.Count < count)
+ {
+ foreach (var path in paths)
+ {
+ list.Add(path);
+
+ if (list.Count >= count)
+ {
+ return;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs
index 3410ef003f..242898e332 100644
--- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs
+++ b/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs
@@ -8,9 +8,6 @@ using MediaBrowser.Model.Logging;
using System;
using System.IO;
using System.Linq;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
namespace Emby.Drawing.ImageMagick
@@ -19,17 +16,15 @@ namespace Emby.Drawing.ImageMagick
{
private readonly ILogger _logger;
private readonly IApplicationPaths _appPaths;
- private readonly IHttpClient _httpClient;
+ private readonly Func<IHttpClient> _httpClientFactory;
private readonly IFileSystem _fileSystem;
- private readonly IServerConfigurationManager _config;
- public ImageMagickEncoder(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config)
+ public ImageMagickEncoder(ILogger logger, IApplicationPaths appPaths, Func<IHttpClient> httpClientFactory, IFileSystem fileSystem)
{
_logger = logger;
_appPaths = appPaths;
- _httpClient = httpClient;
+ _httpClientFactory = httpClientFactory;
_fileSystem = fileSystem;
- _config = config;
LogVersion();
}
@@ -260,7 +255,7 @@ namespace Emby.Drawing.ImageMagick
{
var currentImageSize = new ImageSize(imageWidth, imageHeight);
- var task = new PlayedIndicatorDrawer(_appPaths, _httpClient, _fileSystem).DrawPlayedIndicator(wand, currentImageSize);
+ var task = new PlayedIndicatorDrawer(_appPaths, _httpClientFactory(), _fileSystem).DrawPlayedIndicator(wand, currentImageSize);
Task.WaitAll(task);
}
else if (options.UnplayedCount.HasValue)
diff --git a/Emby.Drawing/ImageMagick/PercentPlayedDrawer.cs b/Emby.Drawing.ImageMagick/PercentPlayedDrawer.cs
index 90f9d56095..90f9d56095 100644
--- a/Emby.Drawing/ImageMagick/PercentPlayedDrawer.cs
+++ b/Emby.Drawing.ImageMagick/PercentPlayedDrawer.cs
diff --git a/Emby.Drawing/ImageMagick/PlayedIndicatorDrawer.cs b/Emby.Drawing.ImageMagick/PlayedIndicatorDrawer.cs
index 14fb0ddf15..14fb0ddf15 100644
--- a/Emby.Drawing/ImageMagick/PlayedIndicatorDrawer.cs
+++ b/Emby.Drawing.ImageMagick/PlayedIndicatorDrawer.cs
diff --git a/Emby.Drawing.ImageMagick/Properties/AssemblyInfo.cs b/Emby.Drawing.ImageMagick/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..1089607d67
--- /dev/null
+++ b/Emby.Drawing.ImageMagick/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Emby.Drawing.ImageMagick")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Emby.Drawing.ImageMagick")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6cfee013-6e7c-432b-ac37-cabf0880c69a")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Emby.Drawing/ImageMagick/StripCollageBuilder.cs b/Emby.Drawing.ImageMagick/StripCollageBuilder.cs
index 715ab46800..715ab46800 100644
--- a/Emby.Drawing/ImageMagick/StripCollageBuilder.cs
+++ b/Emby.Drawing.ImageMagick/StripCollageBuilder.cs
diff --git a/Emby.Drawing/ImageMagick/UnplayedCountIndicator.cs b/Emby.Drawing.ImageMagick/UnplayedCountIndicator.cs
index c531400992..c531400992 100644
--- a/Emby.Drawing/ImageMagick/UnplayedCountIndicator.cs
+++ b/Emby.Drawing.ImageMagick/UnplayedCountIndicator.cs
diff --git a/Emby.Drawing/packages.config b/Emby.Drawing.ImageMagick/packages.config
index be2fb41879..619310d28e 100644
--- a/Emby.Drawing/packages.config
+++ b/Emby.Drawing.ImageMagick/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="ImageMagickSharp" version="1.0.0.18" targetFramework="net45" />
+ <package id="ImageMagickSharp" version="1.0.0.18" targetFramework="net452" />
</packages> \ No newline at end of file
diff --git a/Emby.Drawing/GDI/DynamicImageHelpers.cs b/Emby.Drawing.Net/DynamicImageHelpers.cs
index 9cbd6cbe3a..1910f7840d 100644
--- a/Emby.Drawing/GDI/DynamicImageHelpers.cs
+++ b/Emby.Drawing.Net/DynamicImageHelpers.cs
@@ -7,7 +7,7 @@ using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
-namespace Emby.Drawing.GDI
+namespace Emby.Drawing.Net
{
public static class DynamicImageHelpers
{
diff --git a/Emby.Drawing.Net/Emby.Drawing.Net.csproj b/Emby.Drawing.Net/Emby.Drawing.Net.csproj
new file mode 100644
index 0000000000..16e72a085b
--- /dev/null
+++ b/Emby.Drawing.Net/Emby.Drawing.Net.csproj
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{C97A239E-A96C-4D64-A844-CCF8CC30AECB}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Emby.Drawing.Net</RootNamespace>
+ <AssemblyName>Emby.Drawing.Net</AssemblyName>
+ <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="DynamicImageHelpers.cs" />
+ <Compile Include="GDIImageEncoder.cs" />
+ <Compile Include="ImageExtensions.cs" />
+ <Compile Include="ImageHelpers.cs" />
+ <Compile Include="PercentPlayedDrawer.cs" />
+ <Compile Include="PlayedIndicatorDrawer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="UnplayedCountIndicator.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
+ <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
+ <Name>MediaBrowser.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
+ <Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
+ <Name>MediaBrowser.Controller</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
+ <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
+ <Name>MediaBrowser.Model</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="empty.png" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/Emby.Drawing/GDI/GDIImageEncoder.cs b/Emby.Drawing.Net/GDIImageEncoder.cs
index 2fd2cac7e8..831a579792 100644
--- a/Emby.Drawing/GDI/GDIImageEncoder.cs
+++ b/Emby.Drawing.Net/GDIImageEncoder.cs
@@ -12,7 +12,7 @@ using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using ImageFormat = MediaBrowser.Model.Drawing.ImageFormat;
-namespace Emby.Drawing.GDI
+namespace Emby.Drawing.Net
{
public class GDIImageEncoder : IImageEncoder
{
diff --git a/Emby.Drawing/GDI/ImageExtensions.cs b/Emby.Drawing.Net/ImageExtensions.cs
index 6af5a8688f..dec2613d0f 100644
--- a/Emby.Drawing/GDI/ImageExtensions.cs
+++ b/Emby.Drawing.Net/ImageExtensions.cs
@@ -4,7 +4,7 @@ using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
-namespace Emby.Drawing.GDI
+namespace Emby.Drawing.Net
{
public static class ImageExtensions
{
diff --git a/Emby.Drawing/ImageHelpers.cs b/Emby.Drawing.Net/ImageHelpers.cs
index 90bde8b3bd..1afc47cd03 100644
--- a/Emby.Drawing/ImageHelpers.cs
+++ b/Emby.Drawing.Net/ImageHelpers.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
-namespace Emby.Drawing
+namespace Emby.Drawing.Net
{
internal static class ImageHelpers
{
diff --git a/Emby.Drawing/GDI/PercentPlayedDrawer.cs b/Emby.Drawing.Net/PercentPlayedDrawer.cs
index c7afda60e4..fac15ba47a 100644
--- a/Emby.Drawing/GDI/PercentPlayedDrawer.cs
+++ b/Emby.Drawing.Net/PercentPlayedDrawer.cs
@@ -1,7 +1,7 @@
using System;
using System.Drawing;
-namespace Emby.Drawing.GDI
+namespace Emby.Drawing.Net
{
public class PercentPlayedDrawer
{
diff --git a/Emby.Drawing/GDI/PlayedIndicatorDrawer.cs b/Emby.Drawing.Net/PlayedIndicatorDrawer.cs
index 4428e4cbac..53683e6f45 100644
--- a/Emby.Drawing/GDI/PlayedIndicatorDrawer.cs
+++ b/Emby.Drawing.Net/PlayedIndicatorDrawer.cs
@@ -1,6 +1,6 @@
using System.Drawing;
-namespace Emby.Drawing.GDI
+namespace Emby.Drawing.Net
{
public class PlayedIndicatorDrawer
{
diff --git a/Emby.Drawing.Net/Properties/AssemblyInfo.cs b/Emby.Drawing.Net/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..321c3a297c
--- /dev/null
+++ b/Emby.Drawing.Net/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Emby.Drawing.Net")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Emby.Drawing.Net")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("c97a239e-a96c-4d64-a844-ccf8cc30aecb")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Emby.Drawing/GDI/UnplayedCountIndicator.cs b/Emby.Drawing.Net/UnplayedCountIndicator.cs
index 6420abb27f..a38abeb324 100644
--- a/Emby.Drawing/GDI/UnplayedCountIndicator.cs
+++ b/Emby.Drawing.Net/UnplayedCountIndicator.cs
@@ -1,6 +1,6 @@
using System.Drawing;
-namespace Emby.Drawing.GDI
+namespace Emby.Drawing.Net
{
public class UnplayedCountIndicator
{
diff --git a/Emby.Drawing/GDI/empty.png b/Emby.Drawing.Net/empty.png
index 42e2b375e5..42e2b375e5 100644
--- a/Emby.Drawing/GDI/empty.png
+++ b/Emby.Drawing.Net/empty.png
Binary files differ
diff --git a/Emby.Drawing/Common/ImageHeader.cs b/Emby.Drawing/Common/ImageHeader.cs
index 45a8f0d474..c385779a1e 100644
--- a/Emby.Drawing/Common/ImageHeader.cs
+++ b/Emby.Drawing/Common/ImageHeader.cs
@@ -48,7 +48,7 @@ namespace Emby.Drawing.Common
/// <exception cref="ArgumentException">The image was of an unrecognised format.</exception>
public static ImageSize GetDimensions(string path, ILogger logger, IFileSystem fileSystem)
{
- using (var fs = File.OpenRead(path))
+ using (var fs = fileSystem.OpenRead(path))
{
using (var binaryReader = new BinaryReader(fs))
{
diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj
index a883d06495..90418f6317 100644
--- a/Emby.Drawing/Emby.Drawing.csproj
+++ b/Emby.Drawing/Emby.Drawing.csproj
@@ -9,10 +9,11 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Emby.Drawing</RootNamespace>
<AssemblyName>Emby.Drawing</AssemblyName>
- <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
- <TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -32,18 +33,6 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Reference Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\ImageMagickSharp.1.0.0.18\lib\net45\ImageMagickSharp.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Drawing" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
<Reference Include="TagLib.Portable">
<HintPath>..\ThirdParty\taglib\TagLib.Portable.dll</HintPath>
</Reference>
@@ -53,25 +42,9 @@
<Link>Properties\SharedVersion.cs</Link>
</Compile>
<Compile Include="Common\ImageHeader.cs" />
- <Compile Include="GDI\DynamicImageHelpers.cs" />
- <Compile Include="GDI\GDIImageEncoder.cs" />
- <Compile Include="GDI\ImageExtensions.cs" />
- <Compile Include="GDI\PercentPlayedDrawer.cs" />
- <Compile Include="GDI\PlayedIndicatorDrawer.cs" />
- <Compile Include="GDI\UnplayedCountIndicator.cs" />
- <Compile Include="IImageEncoder.cs" />
- <Compile Include="ImageHelpers.cs" />
- <Compile Include="ImageMagick\ImageMagickEncoder.cs" />
- <Compile Include="ImageMagick\StripCollageBuilder.cs" />
<Compile Include="ImageProcessor.cs" />
- <Compile Include="ImageMagick\PercentPlayedDrawer.cs" />
- <Compile Include="ImageMagick\PlayedIndicatorDrawer.cs" />
<Compile Include="NullImageEncoder.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="ImageMagick\UnplayedCountIndicator.cs" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="ImageMagick\fonts\robotoregular.ttf" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
@@ -87,13 +60,8 @@
<Name>MediaBrowser.Model</Name>
</ProjectReference>
</ItemGroup>
- <ItemGroup>
- <None Include="packages.config" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="GDI\empty.png" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <ItemGroup />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs
index aa18058719..292896856d 100644
--- a/Emby.Drawing/ImageProcessor.cs
+++ b/Emby.Drawing/ImageProcessor.cs
@@ -21,8 +21,8 @@ using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Threading;
using TagLib;
-using File = System.IO.File;
namespace Emby.Drawing
{
@@ -65,7 +65,7 @@ namespace Emby.Drawing
IFileSystem fileSystem,
IJsonSerializer jsonSerializer,
IImageEncoder imageEncoder,
- int maxConcurrentImageProcesses, Func<ILibraryManager> libraryManager)
+ int maxConcurrentImageProcesses, Func<ILibraryManager> libraryManager, ITimerFactory timerFactory)
{
_logger = logger;
_fileSystem = fileSystem;
@@ -75,7 +75,7 @@ namespace Emby.Drawing
_appPaths = appPaths;
ImageEnhancers = new List<IImageEnhancer>();
- _saveImageSizeTimer = new Timer(SaveImageSizeCallback, null, Timeout.Infinite, Timeout.Infinite);
+ _saveImageSizeTimer = timerFactory.Create(SaveImageSizeCallback, null, Timeout.Infinite, Timeout.Infinite);
Dictionary<Guid, ImageSize> sizeDictionary;
@@ -89,7 +89,7 @@ namespace Emby.Drawing
// No biggie
sizeDictionary = new Dictionary<Guid, ImageSize>();
}
- catch (DirectoryNotFoundException)
+ catch (IOException)
{
// No biggie
sizeDictionary = new Dictionary<Guid, ImageSize>();
@@ -286,7 +286,7 @@ namespace Emby.Drawing
{
try
{
- File.Copy(src, destination, true);
+ _fileSystem.CopyFile(src, destination, true);
}
catch
{
@@ -600,7 +600,7 @@ namespace Emby.Drawing
return ImageHeader.GetDimensions(path, _logger, _fileSystem);
}
- private readonly Timer _saveImageSizeTimer;
+ private readonly ITimer _saveImageSizeTimer;
private const int SaveImageSizeTimeout = 5000;
private readonly object _saveImageSizeLock = new object();
private void StartSaveImageSizeTimer()
@@ -801,7 +801,7 @@ namespace Emby.Drawing
try
{
- File.Copy(tmpPath, enhancedImagePath, true);
+ _fileSystem.CopyFile(tmpPath, enhancedImagePath, true);
}
catch
{
diff --git a/Emby.Drawing/project.json b/Emby.Drawing/project.json
new file mode 100644
index 0000000000..fbbe9eaf32
--- /dev/null
+++ b/Emby.Drawing/project.json
@@ -0,0 +1,17 @@
+{
+ "frameworks":{
+ "netstandard1.6":{
+ "dependencies":{
+ "NETStandard.Library":"1.6.0",
+ }
+ },
+ ".NETPortable,Version=v4.5,Profile=Profile7":{
+ "buildOptions": {
+ "define": [ ]
+ },
+ "frameworkAssemblies":{
+
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Core/Activity/ActivityRepository.cs
index f3c52088be..c11dcf7238 100644
--- a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs
+++ b/Emby.Server.Core/Activity/ActivityRepository.cs
@@ -1,16 +1,16 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Model.Activity;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Querying;
-using MediaBrowser.Server.Implementations.Persistence;
-using System;
+using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Threading.Tasks;
+using Emby.Server.Core.Data;
+using MediaBrowser.Controller;
+using MediaBrowser.Model.Activity;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Querying;
-namespace MediaBrowser.Server.Implementations.Activity
+namespace Emby.Server.Core.Activity
{
public class ActivityRepository : BaseSqliteRepository, IActivityRepository
{
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/Emby.Server.Core/ApplicationHost.cs
index c155a968e9..9e0aee325b 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/Emby.Server.Core/ApplicationHost.cs
@@ -1,7 +1,4 @@
-using Emby.Drawing;
-using Emby.Drawing.GDI;
-using Emby.Drawing.ImageMagick;
-using MediaBrowser.Api;
+using MediaBrowser.Api;
using MediaBrowser.Common;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Events;
@@ -48,19 +45,6 @@ using MediaBrowser.Model.Updates;
using MediaBrowser.Providers.Chapters;
using MediaBrowser.Providers.Manager;
using MediaBrowser.Providers.Subtitles;
-using MediaBrowser.Server.Implementations;
-using MediaBrowser.Server.Implementations.Activity;
-using MediaBrowser.Server.Implementations.Configuration;
-using MediaBrowser.Server.Implementations.Devices;
-using MediaBrowser.Server.Implementations.HttpServer;
-using MediaBrowser.Server.Implementations.IO;
-using MediaBrowser.Server.Implementations.Notifications;
-using MediaBrowser.Server.Implementations.Persistence;
-using MediaBrowser.Server.Implementations.Security;
-using MediaBrowser.Server.Implementations.Social;
-using MediaBrowser.Server.Implementations.Sync;
-using MediaBrowser.Server.Startup.Common.FFMpeg;
-using MediaBrowser.Server.Startup.Common.Migrations;
using MediaBrowser.WebDashboard.Api;
using MediaBrowser.XbmcMetadata.Providers;
using System;
@@ -72,11 +56,14 @@ using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Emby.Common.Implementations;
+using Emby.Common.Implementations.Archiving;
using Emby.Common.Implementations.Networking;
using Emby.Common.Implementations.Reflection;
+using Emby.Common.Implementations.Serialization;
using Emby.Common.Implementations.TextEncoding;
using Emby.Common.Implementations.Updates;
using Emby.Common.Implementations.Xml;
@@ -95,6 +82,19 @@ using Emby.Dlna.ContentDirectory;
using Emby.Dlna.Main;
using Emby.Dlna.MediaReceiverRegistrar;
using Emby.Dlna.Ssdp;
+using Emby.Server.Core;
+using Emby.Server.Core.Activity;
+using Emby.Server.Core.Configuration;
+using Emby.Server.Core.Data;
+using Emby.Server.Core.Devices;
+using Emby.Server.Core.FFMpeg;
+using Emby.Server.Core.IO;
+using Emby.Server.Core.Localization;
+using Emby.Server.Core.Migrations;
+using Emby.Server.Core.Notifications;
+using Emby.Server.Core.Security;
+using Emby.Server.Core.Social;
+using Emby.Server.Core.Sync;
using Emby.Server.Implementations.Activity;
using Emby.Server.Implementations.Channels;
using Emby.Server.Implementations.Collections;
@@ -103,6 +103,7 @@ using Emby.Server.Implementations.Devices;
using Emby.Server.Implementations.Dto;
using Emby.Server.Implementations.EntryPoints;
using Emby.Server.Implementations.FileOrganization;
+using Emby.Server.Implementations.HttpServer;
using Emby.Server.Implementations.HttpServer.Security;
using Emby.Server.Implementations.Library;
using Emby.Server.Implementations.LiveTv;
@@ -130,13 +131,13 @@ using MediaBrowser.Model.Services;
using MediaBrowser.Model.Social;
using MediaBrowser.Model.Text;
using MediaBrowser.Model.Xml;
-using MediaBrowser.Server.Implementations.Archiving;
-using MediaBrowser.Server.Implementations.Serialization;
using OpenSubtitlesHandler;
using ServiceStack;
+using SocketHttpListener.Primitives;
using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions;
+using Emby.Drawing;
-namespace MediaBrowser.Server.Startup.Common
+namespace Emby.Server.Core
{
/// <summary>
/// Class CompositionRoot
@@ -262,6 +263,10 @@ namespace MediaBrowser.Server.Startup.Common
internal INativeApp NativeApp { get; set; }
internal IPowerManagement PowerManagement { get; private set; }
+ internal IImageEncoder ImageEncoder { get; private set; }
+
+ private readonly Action<string, string> _certificateGenerator;
+ private readonly Func<string> _defaultUserNameFactory;
/// <summary>
/// Initializes a new instance of the <see cref="ApplicationHost" /> class.
@@ -270,16 +275,33 @@ namespace MediaBrowser.Server.Startup.Common
ILogManager logManager,
StartupOptions options,
IFileSystem fileSystem,
- INativeApp nativeApp,
+ INativeApp nativeApp,
IPowerManagement powerManagement,
- string releaseAssetFilename)
- : base(applicationPaths, logManager, fileSystem)
+ string releaseAssetFilename,
+ IEnvironmentInfo environmentInfo,
+ IImageEncoder imageEncoder,
+ ISystemEvents systemEvents,
+ IMemoryStreamFactory memoryStreamFactory,
+ INetworkManager networkManager,
+ Action<string, string> certificateGenerator,
+ Func<string> defaultUsernameFactory)
+ : base(applicationPaths,
+ logManager,
+ fileSystem,
+ environmentInfo,
+ systemEvents,
+ memoryStreamFactory,
+ networkManager)
{
_startupOptions = options;
+ _certificateGenerator = certificateGenerator;
_releaseAssetFilename = releaseAssetFilename;
+ _defaultUserNameFactory = defaultUsernameFactory;
NativeApp = nativeApp;
PowerManagement = powerManagement;
+ ImageEncoder = imageEncoder;
+
SetBaseExceptionMessage();
}
@@ -292,15 +314,10 @@ namespace MediaBrowser.Server.Startup.Common
{
get
{
- return _version ?? (_version = NativeApp.GetType().Assembly.GetName().Version);
+ return _version ?? (_version = GetAssembly(NativeApp.GetType()).GetName().Version);
}
}
- public override string OperatingSystemDisplayName
- {
- get { return NativeApp.Environment.OperatingSystemVersionString; }
- }
-
public override bool IsRunningAsService
{
get { return NativeApp.IsRunningAsService; }
@@ -311,11 +328,6 @@ namespace MediaBrowser.Server.Startup.Common
get { return NativeApp.SupportsRunningAsService; }
}
- public bool SupportsLibraryMonitor
- {
- get { return NativeApp.SupportsLibraryMonitor; }
- }
-
/// <summary>
/// Gets the name.
/// </summary>
@@ -328,6 +340,11 @@ namespace MediaBrowser.Server.Startup.Common
}
}
+ private Assembly GetAssembly(Type type)
+ {
+ return type.GetTypeInfo().Assembly;
+ }
+
/// <summary>
/// Gets a value indicating whether this instance can self restart.
/// </summary>
@@ -412,21 +429,6 @@ namespace MediaBrowser.Server.Startup.Common
LogManager.RemoveConsoleOutput();
}
- protected override IMemoryStreamFactory CreateMemoryStreamProvider()
- {
- if (Environment.OSVersion.Platform == PlatformID.Win32NT)
- {
- return new RecyclableMemoryStreamProvider();
- }
-
- return new MemoryStreamProvider();
- }
-
- protected override ISystemEvents CreateSystemEvents()
- {
- return new SystemEvents(LogManager.GetLogger("SystemEvents"));
- }
-
protected override IJsonSerializer CreateJsonSerializer()
{
try
@@ -578,11 +580,11 @@ namespace MediaBrowser.Server.Startup.Common
UserRepository = await GetUserRepository().ConfigureAwait(false);
- var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths, NativeApp.GetDbConnector(), MemoryStreamProvider);
+ var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths, NativeApp.GetDbConnector(), MemoryStreamFactory);
DisplayPreferencesRepository = displayPreferencesRepo;
RegisterSingleInstance(DisplayPreferencesRepository);
- var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, NativeApp.GetDbConnector(), MemoryStreamProvider);
+ var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, NativeApp.GetDbConnector(), MemoryStreamFactory);
ItemRepository = itemRepo;
RegisterSingleInstance(ItemRepository);
@@ -595,7 +597,7 @@ namespace MediaBrowser.Server.Startup.Common
SyncRepository = await GetSyncRepository().ConfigureAwait(false);
RegisterSingleInstance(SyncRepository);
- UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager, CryptographyProvider, Environment.UserName);
+ UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager, CryptographyProvider, _defaultUserNameFactory());
RegisterSingleInstance(UserManager);
LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager);
@@ -607,17 +609,17 @@ namespace MediaBrowser.Server.Startup.Common
LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, TimerFactory, SystemEvents, EnvironmentInfo);
RegisterSingleInstance(LibraryMonitor);
- ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer, MemoryStreamProvider);
+ ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer, MemoryStreamFactory);
RegisterSingleInstance(ProviderManager);
RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LogManager, LibraryManager, UserManager));
- HttpServer = ServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, MemoryStreamProvider, "Emby", "web/index.html", textEncoding, SocketFactory, CryptographyProvider, JsonSerializer, XmlSerializer);
+ HttpServer = HttpServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, MemoryStreamFactory, "Emby", "web/index.html", textEncoding, SocketFactory, CryptographyProvider, JsonSerializer, XmlSerializer, EnvironmentInfo, Certificate);
HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading");
RegisterSingleInstance(HttpServer, false);
progress.Report(10);
- ServerManager = new ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager, MemoryStreamProvider, textEncoding);
+ ServerManager = new ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager, MemoryStreamFactory, textEncoding);
RegisterSingleInstance(ServerManager);
var innerProgress = new ActionableProgress<double>();
@@ -629,7 +631,7 @@ namespace MediaBrowser.Server.Startup.Common
TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager);
RegisterSingleInstance(TVSeriesManager);
- SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder, FileSystemManager, () => SubtitleEncoder, ServerConfigurationManager, UserDataManager, () => MediaSourceManager, JsonSerializer, TaskManager, MemoryStreamProvider);
+ SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder, FileSystemManager, () => SubtitleEncoder, ServerConfigurationManager, UserDataManager, () => MediaSourceManager, JsonSerializer, TaskManager, MemoryStreamFactory);
RegisterSingleInstance(SyncManager);
DtoService = new DtoService(LogManager.GetLogger("DtoService"), LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager, () => LiveTvManager);
@@ -717,7 +719,7 @@ namespace MediaBrowser.Server.Startup.Common
AuthService = new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager, DeviceManager);
RegisterSingleInstance<IAuthService>(AuthService);
- SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, MemoryStreamProvider, ProcessFactory, textEncoding);
+ SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, MemoryStreamFactory, ProcessFactory, textEncoding);
RegisterSingleInstance(SubtitleEncoder);
await displayPreferencesRepo.Initialize().ConfigureAwait(false);
@@ -735,47 +737,42 @@ namespace MediaBrowser.Server.Startup.Common
await ((UserManager)UserManager).Initialize().ConfigureAwait(false);
}
- private IImageProcessor GetImageProcessor()
+ private ICertificate GetCertificate(string certificateLocation)
{
- var maxConcurrentImageProcesses = Math.Max(Environment.ProcessorCount, 4);
-
- if (_startupOptions.ContainsOption("-imagethreads"))
+ if (string.IsNullOrWhiteSpace(certificateLocation))
{
- int.TryParse(_startupOptions.GetOption("-imagethreads"), NumberStyles.Any, CultureInfo.InvariantCulture, out maxConcurrentImageProcesses);
+ return null;
}
- return new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, GetImageEncoder(), maxConcurrentImageProcesses, () => LibraryManager);
- }
-
- private IImageEncoder GetImageEncoder()
- {
- if (!_startupOptions.ContainsOption("-enablegdi"))
+ try
{
- try
+ X509Certificate2 localCert = new X509Certificate2(certificateLocation);
+ //localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA;
+ if (!localCert.HasPrivateKey)
{
- return new ImageMagickEncoder(LogManager.GetLogger("ImageMagick"), ApplicationPaths, HttpClient, FileSystemManager, ServerConfigurationManager);
+ //throw new FileNotFoundException("Secure requested, no private key included", certificateLocation);
+ return null;
}
- catch
- {
- Logger.Error("Error loading ImageMagick. Will revert to GDI.");
- }
- }
- try
- {
- return new GDIImageEncoder(FileSystemManager, LogManager.GetLogger("GDI"));
+ return new Certificate(localCert);
}
- catch
+ catch (Exception ex)
{
- Logger.Error("Error loading GDI. Will revert to NullImageEncoder.");
+ Logger.ErrorException("Error loading cert from {0}", ex, certificateLocation);
+ return null;
}
-
- return new NullImageEncoder();
}
- protected override INetworkManager CreateNetworkManager(ILogger logger)
+ private IImageProcessor GetImageProcessor()
{
- return NativeApp.CreateNetworkManager(logger);
+ var maxConcurrentImageProcesses = Math.Max(Environment.ProcessorCount, 4);
+
+ if (_startupOptions.ContainsOption("-imagethreads"))
+ {
+ int.TryParse(_startupOptions.GetOption("-imagethreads"), NumberStyles.Any, CultureInfo.InvariantCulture, out maxConcurrentImageProcesses);
+ }
+
+ return new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, ImageEncoder, maxConcurrentImageProcesses, () => LibraryManager, TimerFactory);
}
/// <summary>
@@ -787,8 +784,8 @@ namespace MediaBrowser.Server.Startup.Common
string encoderPath = null;
string probePath = null;
- var info = await new FFMpegLoader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, NativeApp.Environment, NativeApp.GetFfmpegInstallInfo())
- .GetFFMpegInfo(NativeApp.Environment, _startupOptions, progress).ConfigureAwait(false);
+ var info = await new FFMpegLoader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, NativeApp.GetFfmpegInstallInfo())
+ .GetFFMpegInfo(_startupOptions, progress).ConfigureAwait(false);
encoderPath = info.EncoderPath;
probePath = info.ProbePath;
@@ -809,10 +806,11 @@ namespace MediaBrowser.Server.Startup.Common
() => SubtitleEncoder,
() => MediaSourceManager,
HttpClient,
- ZipClient, MemoryStreamProvider,
+ ZipClient,
+ MemoryStreamFactory,
ProcessFactory,
- Environment.Is64BitOperatingSystem ? (Environment.ProcessorCount > 2 ? 14000 : 20000) : 40000,
- Environment.OSVersion.Platform == PlatformID.Win32NT);
+ (Environment.ProcessorCount > 2 ? 14000 : 40000),
+ EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows);
MediaEncoder = mediaEncoder;
RegisterSingleInstance(MediaEncoder);
@@ -824,7 +822,7 @@ namespace MediaBrowser.Server.Startup.Common
/// <returns>Task{IUserRepository}.</returns>
private async Task<IUserRepository> GetUserRepository()
{
- var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer, NativeApp.GetDbConnector(), MemoryStreamProvider);
+ var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer, NativeApp.GetDbConnector(), MemoryStreamFactory);
await repo.Initialize().ConfigureAwait(false);
@@ -968,6 +966,7 @@ namespace MediaBrowser.Server.Startup.Common
}
private string CertificatePath { get; set; }
+ private ICertificate Certificate { get; set; }
private IEnumerable<string> GetUrlPrefixes()
{
@@ -997,10 +996,11 @@ namespace MediaBrowser.Server.Startup.Common
private void StartServer()
{
CertificatePath = GetCertificatePath(true);
+ Certificate = GetCertificate(CertificatePath);
try
{
- ServerManager.Start(GetUrlPrefixes(), CertificatePath);
+ ServerManager.Start(GetUrlPrefixes());
return;
}
catch (Exception ex)
@@ -1017,7 +1017,7 @@ namespace MediaBrowser.Server.Startup.Common
try
{
- ServerManager.Start(GetUrlPrefixes(), CertificatePath);
+ ServerManager.Start(GetUrlPrefixes());
}
catch (Exception ex)
{
@@ -1047,7 +1047,7 @@ namespace MediaBrowser.Server.Startup.Common
try
{
- NetworkManager.GenerateSelfSignedSslCertificate(certPath, certHost);
+ _certificateGenerator(certPath, certHost);
}
catch (Exception ex)
{
@@ -1158,51 +1158,51 @@ namespace MediaBrowser.Server.Startup.Common
// This will prevent the .dll file from getting locked, and allow us to replace it when needed
// Include composable parts in the Api assembly
- list.Add(typeof(ApiEntryPoint).Assembly);
+ list.Add(GetAssembly(typeof(ApiEntryPoint)));
// Include composable parts in the Dashboard assembly
- list.Add(typeof(DashboardService).Assembly);
+ list.Add(GetAssembly(typeof(DashboardService)));
// Include composable parts in the Model assembly
- list.Add(typeof(SystemInfo).Assembly);
+ list.Add(GetAssembly(typeof(SystemInfo)));
// Include composable parts in the Common assembly
- list.Add(typeof(IApplicationHost).Assembly);
+ list.Add(GetAssembly(typeof(IApplicationHost)));
// Include composable parts in the Controller assembly
- list.Add(typeof(IServerApplicationHost).Assembly);
+ list.Add(GetAssembly(typeof(IServerApplicationHost)));
// Include composable parts in the Providers assembly
- list.Add(typeof(ProviderUtils).Assembly);
+ list.Add(GetAssembly(typeof(ProviderUtils)));
// Include composable parts in the Photos assembly
- list.Add(typeof(PhotoProvider).Assembly);
+ list.Add(GetAssembly(typeof(PhotoProvider)));
// Common implementations
- list.Add(typeof(TaskManager).Assembly);
-
- // MediaBrowser.Server implementations
- list.Add(typeof(ServerApplicationPaths).Assembly);
+ list.Add(GetAssembly(typeof(TaskManager)));
// Emby.Server implementations
- list.Add(typeof(InstallationManager).Assembly);
+ list.Add(GetAssembly(typeof(InstallationManager)));
+
+ // Emby.Server.Core
+ list.Add(GetAssembly(typeof(ServerApplicationPaths)));
// MediaEncoding
- list.Add(typeof(MediaEncoder).Assembly);
+ list.Add(GetAssembly(typeof(MediaEncoder)));
// Dlna
- list.Add(typeof(DlnaEntryPoint).Assembly);
+ list.Add(GetAssembly(typeof(DlnaEntryPoint)));
// Local metadata
- list.Add(typeof(BoxSetXmlSaver).Assembly);
+ list.Add(GetAssembly(typeof(BoxSetXmlSaver)));
// Xbmc
- list.Add(typeof(ArtistNfoProvider).Assembly);
+ list.Add(GetAssembly(typeof(ArtistNfoProvider)));
list.AddRange(NativeApp.GetAssembliesWithParts());
// Include composable parts in the running assembly
- list.Add(GetType().Assembly);
+ list.Add(GetAssembly(GetType()));
return list;
}
@@ -1267,7 +1267,7 @@ namespace MediaBrowser.Server.Startup.Common
HttpServerPortNumber = HttpPort,
SupportsHttps = SupportsHttps,
HttpsPortNumber = HttpsPort,
- OperatingSystem = NativeApp.Environment.OperatingSystem.ToString(),
+ OperatingSystem = EnvironmentInfo.OperatingSystem.ToString(),
OperatingSystemDisplayName = OperatingSystemDisplayName,
CanSelfRestart = CanSelfRestart,
CanSelfUpdate = CanSelfUpdate,
@@ -1279,9 +1279,9 @@ namespace MediaBrowser.Server.Startup.Common
SupportsRunningAsService = SupportsRunningAsService,
ServerName = FriendlyName,
LocalAddress = localAddress,
- SupportsLibraryMonitor = SupportsLibraryMonitor,
+ SupportsLibraryMonitor = true,
EncoderLocationType = MediaEncoder.EncoderLocationType,
- SystemArchitecture = NativeApp.Environment.SystemArchitecture,
+ SystemArchitecture = EnvironmentInfo.SystemArchitecture,
SystemUpdateLevel = ConfigurationManager.CommonConfiguration.SystemUpdateLevel,
PackageName = _startupOptions.GetOption("-package")
};
@@ -1297,7 +1297,7 @@ namespace MediaBrowser.Server.Startup.Common
public bool SupportsHttps
{
- get { return !string.IsNullOrWhiteSpace(HttpServer.CertificatePath); }
+ get { return Certificate != null; }
}
public async Task<string> GetLocalApiUrl()
diff --git a/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs b/Emby.Server.Core/Browser/BrowserLauncher.cs
index 1a0e2d9731..4ccc41c30b 100644
--- a/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs
+++ b/Emby.Server.Core/Browser/BrowserLauncher.cs
@@ -1,7 +1,7 @@
using MediaBrowser.Controller;
using System;
-namespace MediaBrowser.Server.Startup.Common.Browser
+namespace Emby.Server.Core.Browser
{
/// <summary>
/// Class BrowserLauncher
diff --git a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs b/Emby.Server.Core/Configuration/ServerConfigurationManager.cs
index 4b61951925..f98c096ca3 100644
--- a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs
+++ b/Emby.Server.Core/Configuration/ServerConfigurationManager.cs
@@ -1,7 +1,10 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Emby.Common.Implementations.Configuration;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Events;
-using Emby.Common.Implementations.Configuration;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
@@ -10,16 +13,11 @@ using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Events;
+using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
-using System;
-using System.IO;
-using System.Linq;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.IO;
-namespace MediaBrowser.Server.Implementations.Configuration
+namespace Emby.Server.Core.Configuration
{
/// <summary>
/// Class ServerConfigurationManager
diff --git a/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs b/Emby.Server.Core/Data/BaseSqliteRepository.cs
index 233ab56fed..8d3cbe10a4 100644
--- a/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs
+++ b/Emby.Server.Core/Data/BaseSqliteRepository.cs
@@ -1,10 +1,10 @@
-using MediaBrowser.Model.Logging;
-using System;
+using System;
using System.Data;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Logging;
-namespace MediaBrowser.Server.Implementations.Persistence
+namespace Emby.Server.Core.Data
{
public abstract class BaseSqliteRepository : IDisposable
{
diff --git a/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs b/Emby.Server.Core/Data/DataExtensions.cs
index 179101ca29..b633d92178 100644
--- a/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs
+++ b/Emby.Server.Core/Data/DataExtensions.cs
@@ -1,15 +1,14 @@
-using System.Text;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using System;
+using System;
using System.Data;
using System.IO;
-using MediaBrowser.Common.IO;
+using System.Text;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
-namespace MediaBrowser.Server.Implementations.Persistence
+namespace Emby.Server.Core.Data
{
- static class DataExtensions
+ public static class DataExtensions
{
/// <summary>
/// Determines whether the specified conn is open.
diff --git a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs b/Emby.Server.Core/Data/IDbConnector.cs
index 596cf8407a..ca6c13daee 100644
--- a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs
+++ b/Emby.Server.Core/Data/IDbConnector.cs
@@ -1,7 +1,7 @@
using System.Data;
using System.Threading.Tasks;
-namespace MediaBrowser.Server.Implementations.Persistence
+namespace Emby.Server.Core.Data
{
public interface IDbConnector
{
diff --git a/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs b/Emby.Server.Core/Data/MediaStreamColumns.cs
index 1d9be2e0d6..cb46a56025 100644
--- a/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs
+++ b/Emby.Server.Core/Data/MediaStreamColumns.cs
@@ -3,7 +3,7 @@ using System.Data;
using System.Text;
using MediaBrowser.Model.Logging;
-namespace MediaBrowser.Server.Implementations.Persistence
+namespace Emby.Server.Core.Data
{
public class MediaStreamColumns
{
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Core/Data/SqliteDisplayPreferencesRepository.cs
index c97ba87927..a9e63a11d0 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs
+++ b/Emby.Server.Core/Data/SqliteDisplayPreferencesRepository.cs
@@ -1,19 +1,18 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using System;
+using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
-namespace MediaBrowser.Server.Implementations.Persistence
+namespace Emby.Server.Core.Data
{
/// <summary>
/// Class SQLiteDisplayPreferencesRepository
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs b/Emby.Server.Core/Data/SqliteFileOrganizationRepository.cs
index 7a5e000905..a858db28a7 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs
+++ b/Emby.Server.Core/Data/SqliteFileOrganizationRepository.cs
@@ -1,9 +1,4 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.FileOrganization;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Querying;
-using System;
+using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
@@ -11,8 +6,13 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.FileOrganization;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Querying;
-namespace MediaBrowser.Server.Implementations.Persistence
+namespace Emby.Server.Core.Data
{
public class SqliteFileOrganizationRepository : BaseSqliteRepository, IFileOrganizationRepository, IDisposable
{
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/Emby.Server.Core/Data/SqliteItemRepository.cs
index 3577d1883e..2ca86c8318 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/Emby.Server.Core/Data/SqliteItemRepository.cs
@@ -1,13 +1,3 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Entities.Movies;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Querying;
-using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Data;
@@ -18,21 +8,28 @@ using System.Runtime.Serialization;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Extensions;
+using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Playlists;
using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.LiveTv;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Querying;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Server.Implementations.Devices;
using MediaBrowser.Server.Implementations.Playlists;
-namespace MediaBrowser.Server.Implementations.Persistence
+namespace Emby.Server.Core.Data
{
/// <summary>
/// Class SQLiteItemRepository
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/Emby.Server.Core/Data/SqliteUserDataRepository.cs
index 62d9e76347..2c883e0431 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
+++ b/Emby.Server.Core/Data/SqliteUserDataRepository.cs
@@ -1,8 +1,4 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Logging;
-using System;
+using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
@@ -10,8 +6,12 @@ using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.Logging;
-namespace MediaBrowser.Server.Implementations.Persistence
+namespace Emby.Server.Core.Data
{
public class SqliteUserDataRepository : BaseSqliteRepository, IUserDataRepository
{
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs b/Emby.Server.Core/Data/SqliteUserRepository.cs
index 0c1367e0a2..54851fffbf 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs
+++ b/Emby.Server.Core/Data/SqliteUserRepository.cs
@@ -1,18 +1,17 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using System;
+using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
-namespace MediaBrowser.Server.Implementations.Persistence
+namespace Emby.Server.Core.Data
{
/// <summary>
/// Class SQLiteUserRepository
diff --git a/MediaBrowser.Server.Implementations/Persistence/TypeMapper.cs b/Emby.Server.Core/Data/TypeMapper.cs
index 2de02d8171..f8eb5dd2d8 100644
--- a/MediaBrowser.Server.Implementations/Persistence/TypeMapper.cs
+++ b/Emby.Server.Core/Data/TypeMapper.cs
@@ -2,7 +2,7 @@
using System.Collections.Concurrent;
using System.Linq;
-namespace MediaBrowser.Server.Implementations.Persistence
+namespace Emby.Server.Core.Data
{
/// <summary>
/// Class TypeMapper
diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs b/Emby.Server.Core/Devices/DeviceRepository.cs
index 05e3b68f19..63aa7b67a0 100644
--- a/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs
+++ b/Emby.Server.Core/Devices/DeviceRepository.cs
@@ -1,20 +1,18 @@
-using MediaBrowser.Common.Configuration;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Model.Devices;
+using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.IO;
-namespace MediaBrowser.Server.Implementations.Devices
+namespace Emby.Server.Core.Devices
{
public class DeviceRepository : IDeviceRepository
{
diff --git a/Emby.Server.Core/Emby.Server.Core.xproj b/Emby.Server.Core/Emby.Server.Core.xproj
new file mode 100644
index 0000000000..00f7664bd6
--- /dev/null
+++ b/Emby.Server.Core/Emby.Server.Core.xproj
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>65aa7d67-8059-40cd-91f1-16d02687226c</ProjectGuid>
+ <RootNamespace>Emby.Server.Core</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\ServiceStack\ServiceStack.csproj" />
+ <ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj" />
+ <ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj" />
+ <ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj" />
+ <ProjectReference Include="..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj" />
+ <ProjectReference Include="..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj" />
+ <ProjectReference Include="..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj" />
+ <ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj" />
+ <ProjectReference Include="..\Emby.Dlna\Emby.Dlna.csproj" />
+ <ProjectReference Include="..\Emby.Server.Implementations\Emby.Server.Implementations.csproj" />
+ <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
+ <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
+ <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
+ </ItemGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project> \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Core/EntryPoints/ExternalPortForwarding.cs
index dcfa27cc04..c1a19a71fa 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
+++ b/Emby.Server.Core/EntryPoints/ExternalPortForwarding.cs
@@ -1,19 +1,18 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Dlna;
-using MediaBrowser.Controller.Plugins;
-using MediaBrowser.Model.Logging;
-using Mono.Nat;
-using System;
+using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Threading;
+using Mono.Nat;
-namespace MediaBrowser.Server.Implementations.EntryPoints
+namespace Emby.Server.Core.EntryPoints
{
public class ExternalPortForwarding : IServerEntryPoint
{
diff --git a/MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs b/Emby.Server.Core/EntryPoints/StartupWizard.cs
index f9d173c595..30ceca073d 100644
--- a/MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs
+++ b/Emby.Server.Core/EntryPoints/StartupWizard.cs
@@ -1,9 +1,9 @@
using MediaBrowser.Controller;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Logging;
-using MediaBrowser.Server.Startup.Common.Browser;
+using Emby.Server.Core.Browser;
-namespace MediaBrowser.Server.Startup.Common.EntryPoints
+namespace Emby.Server.Core.EntryPoints
{
/// <summary>
/// Class StartupWizard
diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInfo.cs b/Emby.Server.Core/FFMpeg/FFMpegInfo.cs
index d33b12a9a7..fc197cba32 100644
--- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInfo.cs
+++ b/Emby.Server.Core/FFMpeg/FFMpegInfo.cs
@@ -1,4 +1,4 @@
-namespace MediaBrowser.Server.Startup.Common.FFMpeg
+namespace Emby.Server.Core.FFMpeg
{
/// <summary>
/// Class FFMpegInfo
diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInstallInfo.cs b/Emby.Server.Core/FFMpeg/FFMpegInstallInfo.cs
index a2a44f805c..f1eaeb8894 100644
--- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInstallInfo.cs
+++ b/Emby.Server.Core/FFMpeg/FFMpegInstallInfo.cs
@@ -1,5 +1,5 @@

-namespace MediaBrowser.Server.Startup.Common.FFMpeg
+namespace Emby.Server.Core.FFMpeg
{
public class FFMpegInstallInfo
{
diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs b/Emby.Server.Core/FFMpeg/FFMpegLoader.cs
index 757e43db66..6b090102ab 100644
--- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs
+++ b/Emby.Server.Core/FFMpeg/FFMpegLoader.cs
@@ -2,18 +2,16 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
-using Mono.Unix.Native;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.IO;
+using Emby.Server.Core;
+using Emby.Server.Core.FFMpeg;
-namespace MediaBrowser.Server.Startup.Common.FFMpeg
+namespace Emby.Server.Core.FFMpeg
{
public class FFMpegLoader
{
@@ -22,21 +20,19 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
private readonly ILogger _logger;
private readonly IZipClient _zipClient;
private readonly IFileSystem _fileSystem;
- private readonly NativeEnvironment _environment;
private readonly FFMpegInstallInfo _ffmpegInstallInfo;
- public FFMpegLoader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IZipClient zipClient, IFileSystem fileSystem, NativeEnvironment environment, FFMpegInstallInfo ffmpegInstallInfo)
+ public FFMpegLoader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IZipClient zipClient, IFileSystem fileSystem, FFMpegInstallInfo ffmpegInstallInfo)
{
_logger = logger;
_appPaths = appPaths;
_httpClient = httpClient;
_zipClient = zipClient;
_fileSystem = fileSystem;
- _environment = environment;
_ffmpegInstallInfo = ffmpegInstallInfo;
}
- public async Task<FFMpegInfo> GetFFMpegInfo(NativeEnvironment environment, StartupOptions options, IProgress<double> progress)
+ public async Task<FFMpegInfo> GetFFMpegInfo(StartupOptions options, IProgress<double> progress)
{
var customffMpegPath = options.GetOption("-ffmpeg");
var customffProbePath = options.GetOption("-ffprobe");
@@ -211,13 +207,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
private void SetFilePermissions(string path)
{
- // Linux: File permission to 666, and user's execute bit
- if (_environment.OperatingSystem == OperatingSystem.Bsd || _environment.OperatingSystem == OperatingSystem.Linux || _environment.OperatingSystem == OperatingSystem.Osx)
- {
- _logger.Info("Syscall.chmod {0} FilePermissions.DEFFILEMODE | FilePermissions.S_IRWXU | FilePermissions.S_IXGRP | FilePermissions.S_IXOTH", path);
-
- Syscall.chmod(path, FilePermissions.DEFFILEMODE | FilePermissions.S_IRWXU | FilePermissions.S_IXGRP | FilePermissions.S_IXOTH);
- }
+ _fileSystem.SetExecutable(path);
}
private void ExtractArchive(FFMpegInstallInfo downloadinfo, string archivePath, string targetPath)
diff --git a/Emby.Server.Core/HttpServerFactory.cs b/Emby.Server.Core/HttpServerFactory.cs
new file mode 100644
index 0000000000..d6c07e2581
--- /dev/null
+++ b/Emby.Server.Core/HttpServerFactory.cs
@@ -0,0 +1,107 @@
+using System;
+using System.IO;
+using System.Net.Security;
+using System.Net.Sockets;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading.Tasks;
+using Emby.Common.Implementations.Net;
+using Emby.Server.Implementations.HttpServer;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Net;
+using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.System;
+using MediaBrowser.Model.Text;
+using ServiceStack.Text.Jsv;
+using SocketHttpListener.Primitives;
+
+namespace Emby.Server.Core
+{
+ /// <summary>
+ /// Class ServerFactory
+ /// </summary>
+ public static class HttpServerFactory
+ {
+ /// <summary>
+ /// Creates the server.
+ /// </summary>
+ /// <returns>IHttpServer.</returns>
+ public static IHttpServer CreateServer(IServerApplicationHost applicationHost,
+ ILogManager logManager,
+ IServerConfigurationManager config,
+ INetworkManager networkmanager,
+ IMemoryStreamFactory streamProvider,
+ string serverName,
+ string defaultRedirectpath,
+ ITextEncoding textEncoding,
+ ISocketFactory socketFactory,
+ ICryptoProvider cryptoProvider,
+ IJsonSerializer json,
+ IXmlSerializer xml,
+ IEnvironmentInfo environment,
+ ICertificate certificate)
+ {
+ var logger = logManager.GetLogger("HttpServer");
+
+ return new HttpListenerHost(applicationHost,
+ logger,
+ config,
+ serverName,
+ defaultRedirectpath,
+ networkmanager,
+ streamProvider,
+ textEncoding,
+ socketFactory,
+ cryptoProvider,
+ json,
+ xml,
+ environment,
+ certificate,
+ new StreamFactory(),
+ GetParseFn);
+ }
+
+ private static Func<string, object> GetParseFn(Type propertyType)
+ {
+ return s => JsvReader.GetParseFn(propertyType)(s);
+ }
+ }
+
+ public class StreamFactory : IStreamFactory
+ {
+ public Stream CreateNetworkStream(ISocket socket, bool ownsSocket)
+ {
+ var netSocket = (NetSocket)socket;
+
+ return new NetworkStream(netSocket.Socket, ownsSocket);
+ }
+
+ public Task AuthenticateSslStreamAsServer(Stream stream, ICertificate certificate)
+ {
+ var sslStream = (SslStream)stream;
+ var cert = (Certificate)certificate;
+
+ return sslStream.AuthenticateAsServerAsync(cert.X509Certificate);
+ }
+
+ public Stream CreateSslStream(Stream innerStream, bool leaveInnerStreamOpen)
+ {
+ return new SslStream(innerStream, leaveInnerStreamOpen);
+ }
+ }
+
+ public class Certificate : ICertificate
+ {
+ public Certificate(X509Certificate x509Certificate)
+ {
+ X509Certificate = x509Certificate;
+ }
+
+ public X509Certificate X509Certificate { get; private set; }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/INativeApp.cs b/Emby.Server.Core/INativeApp.cs
index df29dfde42..a4e4b32217 100644
--- a/MediaBrowser.Server.Startup.Common/INativeApp.cs
+++ b/Emby.Server.Core/INativeApp.cs
@@ -2,10 +2,11 @@
using MediaBrowser.Model.Logging;
using System.Collections.Generic;
using System.Reflection;
-using MediaBrowser.Server.Implementations.Persistence;
-using MediaBrowser.Server.Startup.Common.FFMpeg;
+using Emby.Server.Core;
+using Emby.Server.Core.Data;
+using Emby.Server.Core.FFMpeg;
-namespace MediaBrowser.Server.Startup.Common
+namespace Emby.Server.Core
{
public interface INativeApp
{
@@ -18,19 +19,9 @@ namespace MediaBrowser.Server.Startup.Common
/// <summary>
/// Authorizes the server.
/// </summary>
- /// <param name="udpPort">The UDP port.</param>
- /// <param name="httpServerPort">The HTTP server port.</param>
- /// <param name="httpsServerPort">The HTTPS server port.</param>
- /// <param name="tempDirectory">The temporary directory.</param>
void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory);
/// <summary>
- /// Gets the environment.
- /// </summary>
- /// <value>The environment.</value>
- NativeEnvironment Environment { get; }
-
- /// <summary>
/// Gets a value indicating whether [supports running as service].
/// </summary>
/// <value><c>true</c> if [supports running as service]; otherwise, <c>false</c>.</value>
@@ -53,12 +44,6 @@ namespace MediaBrowser.Server.Startup.Common
/// </summary>
/// <value><c>true</c> if [supports autorun at startup]; otherwise, <c>false</c>.</value>
bool SupportsAutoRunAtStartup { get; }
-
- /// <summary>
- /// Gets a value indicating whether [supports library monitor].
- /// </summary>
- /// <value><c>true</c> if [supports library monitor]; otherwise, <c>false</c>.</value>
- bool SupportsLibraryMonitor { get; }
/// <summary>
/// Gets a value indicating whether this instance can self update.
@@ -82,12 +67,6 @@ namespace MediaBrowser.Server.Startup.Common
/// <param name="autorun">if set to <c>true</c> [autorun].</param>
void ConfigureAutoRun(bool autorun);
- /// <summary>
- /// Gets the network manager.
- /// </summary>
- /// <returns>INetworkManager.</returns>
- INetworkManager CreateNetworkManager(ILogger logger);
-
FFMpegInstallInfo GetFfmpegInstallInfo();
void LaunchUrl(string url);
diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Core/IO/LibraryMonitor.cs
index a8363558d5..6ed096f441 100644
--- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
+++ b/Emby.Server.Core/IO/LibraryMonitor.cs
@@ -1,25 +1,21 @@
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Plugins;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Logging;
-using System;
+using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using Emby.Server.Implementations.IO;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.IO;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.IO;
+using MediaBrowser.Model.Logging;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Threading;
+using Emby.Server.Implementations.IO;
-namespace MediaBrowser.Server.Implementations.IO
+namespace Emby.Server.Core.IO
{
public class LibraryMonitor : ILibraryMonitor
{
@@ -297,7 +293,7 @@ namespace MediaBrowser.Server.Implementations.IO
IncludeSubdirectories = true
};
- if (Environment.OSVersion.Platform == PlatformID.Win32NT)
+ if (_environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows)
{
newWatcher.InternalBufferSize = 32767;
}
diff --git a/MediaBrowser.Server.Startup.Common/TextLocalizer.cs b/Emby.Server.Core/Localization/TextLocalizer.cs
index c578199a07..016d596590 100644
--- a/MediaBrowser.Server.Startup.Common/TextLocalizer.cs
+++ b/Emby.Server.Core/Localization/TextLocalizer.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using Emby.Server.Implementations.Localization;
-namespace MediaBrowser.Server.Startup.Common
+namespace Emby.Server.Core.Localization
{
public class TextLocalizer : ITextLocalizer
{
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs b/Emby.Server.Core/Migrations/DbMigration.cs
index e095275b12..17e0860938 100644
--- a/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs
+++ b/Emby.Server.Core/Migrations/DbMigration.cs
@@ -2,9 +2,9 @@
using Emby.Server.Implementations.Persistence;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Tasks;
-using MediaBrowser.Server.Implementations.Persistence;
+using Emby.Server.Core.Data;
-namespace MediaBrowser.Server.Startup.Common.Migrations
+namespace Emby.Server.Core.Migrations
{
public class DbMigration : IVersionMigration
{
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/IVersionMigration.cs b/Emby.Server.Core/Migrations/IVersionMigration.cs
index 6ef08fae97..0190e289a4 100644
--- a/MediaBrowser.Server.Startup.Common/Migrations/IVersionMigration.cs
+++ b/Emby.Server.Core/Migrations/IVersionMigration.cs
@@ -1,6 +1,6 @@
using System.Threading.Tasks;
-namespace MediaBrowser.Server.Startup.Common.Migrations
+namespace Emby.Server.Core.Migrations
{
public interface IVersionMigration
{
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs b/Emby.Server.Core/Migrations/UpdateLevelMigration.cs
index b0214041b1..bbedd7b63c 100644
--- a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs
+++ b/Emby.Server.Core/Migrations/UpdateLevelMigration.cs
@@ -10,7 +10,7 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Updates;
-namespace MediaBrowser.Server.Startup.Common.Migrations
+namespace Emby.Server.Core.Migrations
{
public class UpdateLevelMigration : IVersionMigration
{
diff --git a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs b/Emby.Server.Core/Notifications/SqliteNotificationsRepository.cs
index f30ba3e542..8a7fc92701 100644
--- a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs
+++ b/Emby.Server.Core/Notifications/SqliteNotificationsRepository.cs
@@ -1,17 +1,17 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Notifications;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Notifications;
-using MediaBrowser.Server.Implementations.Persistence;
-using System;
+using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Emby.Server.Core.Data;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Notifications;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Notifications;
-namespace MediaBrowser.Server.Implementations.Notifications
+namespace Emby.Server.Core.Notifications
{
public class SqliteNotificationsRepository : BaseSqliteRepository, INotificationsRepository
{
diff --git a/Emby.Server.Core/Properties/AssemblyInfo.cs b/Emby.Server.Core/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..69df3d58db
--- /dev/null
+++ b/Emby.Server.Core/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Emby.Server.Core")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("65aa7d67-8059-40cd-91f1-16d02687226c")]
diff --git a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs b/Emby.Server.Core/Security/AuthenticationRepository.cs
index 74a552dccc..eaf91c710e 100644
--- a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs
+++ b/Emby.Server.Core/Security/AuthenticationRepository.cs
@@ -1,17 +1,17 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Security;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Querying;
-using MediaBrowser.Server.Implementations.Persistence;
-using System;
+using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
+using Emby.Server.Core.Data;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Security;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Querying;
-namespace MediaBrowser.Server.Implementations.Security
+namespace Emby.Server.Core.Security
{
public class AuthenticationRepository : BaseSqliteRepository, IAuthenticationRepository
{
diff --git a/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs b/Emby.Server.Core/ServerApplicationPaths.cs
index c8dea90050..d59dd89d9c 100644
--- a/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs
+++ b/Emby.Server.Core/ServerApplicationPaths.cs
@@ -1,8 +1,8 @@
-using Emby.Common.Implementations;
+using System.IO;
+using Emby.Common.Implementations;
using MediaBrowser.Controller;
-using System.IO;
-namespace MediaBrowser.Server.Implementations
+namespace Emby.Server.Core
{
/// <summary>
/// Extends BaseApplicationPaths to add paths that are only applicable on the server
diff --git a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs b/Emby.Server.Core/Social/SharingRepository.cs
index dec43e4cbb..5503b7ab3b 100644
--- a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs
+++ b/Emby.Server.Core/Social/SharingRepository.cs
@@ -1,14 +1,14 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Social;
-using MediaBrowser.Server.Implementations.Persistence;
-using System;
+using System;
using System.Data;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
+using Emby.Server.Core.Data;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Social;
-namespace MediaBrowser.Server.Implementations.Social
+namespace Emby.Server.Core.Social
{
public class SharingRepository : BaseSqliteRepository, ISharingRepository
{
diff --git a/MediaBrowser.Server.Startup.Common/StartupOptions.cs b/Emby.Server.Core/StartupOptions.cs
index 1acaf63486..5da42394d5 100644
--- a/MediaBrowser.Server.Startup.Common/StartupOptions.cs
+++ b/Emby.Server.Core/StartupOptions.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
-namespace MediaBrowser.Server.Startup.Common
+namespace Emby.Server.Core
{
public class StartupOptions
{
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/Emby.Server.Core/Sync/SyncRepository.cs
index 64ed00ded1..bfcf76767c 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
+++ b/Emby.Server.Core/Sync/SyncRepository.cs
@@ -1,20 +1,20 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Sync;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Querying;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Sync;
-using MediaBrowser.Server.Implementations.Persistence;
-using System;
+using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using Emby.Server.Core.Data;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Sync;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Querying;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Sync;
-namespace MediaBrowser.Server.Implementations.Sync
+namespace Emby.Server.Core.Sync
{
public class SyncRepository : BaseSqliteRepository, ISyncRepository
{
diff --git a/MediaBrowser.Server.Startup.Common/UnhandledExceptionWriter.cs b/Emby.Server.Core/UnhandledExceptionWriter.cs
index 696c3892e1..5147be9e7c 100644
--- a/MediaBrowser.Server.Startup.Common/UnhandledExceptionWriter.cs
+++ b/Emby.Server.Core/UnhandledExceptionWriter.cs
@@ -3,7 +3,7 @@ using MediaBrowser.Model.Logging;
using System;
using System.IO;
-namespace MediaBrowser.Server.Startup.Common
+namespace Emby.Server.Core
{
public class UnhandledExceptionWriter
{
diff --git a/Emby.Server.Core/project.json b/Emby.Server.Core/project.json
new file mode 100644
index 0000000000..1a8e3432cc
--- /dev/null
+++ b/Emby.Server.Core/project.json
@@ -0,0 +1,131 @@
+{
+ "version": "1.0.0-*",
+
+ "dependencies": {
+
+ },
+
+ "frameworks": {
+ "net46": {
+ "frameworkAssemblies": {
+ "System.Runtime": "4.0.0"
+ },
+ "dependencies": {
+ "MediaBrowser.Model": {
+ "target": "project"
+ },
+ "MediaBrowser.Common": {
+ "target": "project"
+ },
+ "MediaBrowser.Controller": {
+ "target": "project"
+ },
+ "Emby.Common.Implementations": {
+ "target": "project"
+ },
+ "Mono.Nat": {
+ "target": "project"
+ },
+ "Emby.Server.Implementations": {
+ "target": "project"
+ },
+ "MediaBrowser.Server.Implementations": {
+ "target": "project"
+ },
+ "Emby.Dlna": {
+ "target": "project"
+ },
+ "Emby.Photos": {
+ "target": "project"
+ },
+ "MediaBrowser.Api": {
+ "target": "project"
+ },
+ "MediaBrowser.MediaEncoding": {
+ "target": "project"
+ },
+ "MediaBrowser.XbmcMetadata": {
+ "target": "project"
+ },
+ "MediaBrowser.LocalMetadata": {
+ "target": "project"
+ },
+ "MediaBrowser.WebDashboard": {
+ "target": "project"
+ },
+ "Emby.Drawing": {
+ "target": "project"
+ },
+ "ServiceStack": {
+ "target": "project"
+ },
+ "SocketHttpListener.Portable": {
+ "target": "project"
+ }
+ }
+ },
+ "netstandard1.6": {
+ "imports": "dnxcore50",
+ "dependencies": {
+ "NETStandard.Library": "1.6.0",
+ "System.AppDomain": "2.0.11",
+ "System.Globalization.Extensions": "4.0.1",
+ "System.IO.FileSystem.Watcher": "4.0.0",
+ "System.Net.Security": "4.0.0",
+ "System.Security.Cryptography.X509Certificates": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "MediaBrowser.Model": {
+ "target": "project"
+ },
+ "MediaBrowser.Common": {
+ "target": "project"
+ },
+ "MediaBrowser.Controller": {
+ "target": "project"
+ },
+ "Emby.Common.Implementations": {
+ "target": "project"
+ },
+ "Mono.Nat": {
+ "target": "project"
+ },
+ "Emby.Server.Implementations": {
+ "target": "project"
+ },
+ "MediaBrowser.Server.Implementations": {
+ "target": "project"
+ },
+ "Emby.Dlna": {
+ "target": "project"
+ },
+ "Emby.Photos": {
+ "target": "project"
+ },
+ "MediaBrowser.Api": {
+ "target": "project"
+ },
+ "MediaBrowser.MediaEncoding": {
+ "target": "project"
+ },
+ "MediaBrowser.XbmcMetadata": {
+ "target": "project"
+ },
+ "MediaBrowser.LocalMetadata": {
+ "target": "project"
+ },
+ "MediaBrowser.WebDashboard": {
+ "target": "project"
+ },
+ "Emby.Drawing": {
+ "target": "project"
+ },
+ "SocketHttpListener.Portable": {
+ "target": "project"
+ },
+ "ServiceStack": {
+ "target": "project"
+ }
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionsDynamicFolder.cs b/Emby.Server.Implementations/Collections/CollectionsDynamicFolder.cs
index 2d0c3642ea..4ff33e6451 100644
--- a/MediaBrowser.Server.Implementations/Collections/CollectionsDynamicFolder.cs
+++ b/Emby.Server.Implementations/Collections/CollectionsDynamicFolder.cs
@@ -6,7 +6,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.IO;
-namespace MediaBrowser.Server.Implementations.Collections
+namespace Emby.Server.Implementations.Collections
{
public class CollectionsDynamicFolder : IVirtualFolderCreator
{
diff --git a/Emby.Server.Implementations/Devices/CameraUploadsDynamicFolder.cs b/Emby.Server.Implementations/Devices/CameraUploadsDynamicFolder.cs
new file mode 100644
index 0000000000..e2d5d0272f
--- /dev/null
+++ b/Emby.Server.Implementations/Devices/CameraUploadsDynamicFolder.cs
@@ -0,0 +1,41 @@
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Controller.Entities;
+using System;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.IO;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Server.Implementations.Devices;
+
+namespace Emby.Server.Implementations.Devices
+{
+ public class CameraUploadsDynamicFolder : IVirtualFolderCreator
+ {
+ private readonly IApplicationPaths _appPaths;
+ private readonly IFileSystem _fileSystem;
+
+ public CameraUploadsDynamicFolder(IApplicationPaths appPaths, IFileSystem fileSystem)
+ {
+ _appPaths = appPaths;
+ _fileSystem = fileSystem;
+ }
+
+ public BasePluginFolder GetFolder()
+ {
+ var path = Path.Combine(_appPaths.DataPath, "camerauploads");
+
+ _fileSystem.CreateDirectory(path);
+
+ return new CameraUploadsFolder
+ {
+ Path = path
+ };
+ }
+ }
+
+}
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 7e885b7798..8f92f062c9 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -43,11 +43,13 @@
<Compile Include="Channels\RefreshChannelsScheduledTask.cs" />
<Compile Include="Collections\CollectionImageProvider.cs" />
<Compile Include="Collections\CollectionManager.cs" />
+ <Compile Include="Collections\CollectionsDynamicFolder.cs" />
<Compile Include="Connect\ConnectData.cs" />
<Compile Include="Connect\ConnectEntryPoint.cs" />
<Compile Include="Connect\ConnectManager.cs" />
<Compile Include="Connect\Responses.cs" />
<Compile Include="Connect\Validator.cs" />
+ <Compile Include="Devices\CameraUploadsDynamicFolder.cs" />
<Compile Include="Devices\DeviceManager.cs" />
<Compile Include="Dto\DtoService.cs" />
<Compile Include="EntryPoints\AutomaticRestartEntryPoint.cs" />
@@ -69,6 +71,8 @@
<Compile Include="FileOrganization\OrganizerScheduledTask.cs" />
<Compile Include="FileOrganization\TvFolderOrganizer.cs" />
<Compile Include="HttpServer\GetSwaggerResource.cs" />
+ <Compile Include="HttpServer\HttpListenerHost.cs" />
+ <Compile Include="HttpServer\HttpResultFactory.cs" />
<Compile Include="HttpServer\LoggerUtils.cs" />
<Compile Include="HttpServer\RangeRequestWriter.cs" />
<Compile Include="HttpServer\ResponseFilter.cs" />
@@ -78,14 +82,17 @@
<Compile Include="HttpServer\Security\AuthorizationContext.cs" />
<Compile Include="HttpServer\Security\AuthService.cs" />
<Compile Include="HttpServer\Security\SessionContext.cs" />
+ <Compile Include="HttpServer\SocketSharp\RequestMono.cs" />
<Compile Include="HttpServer\SocketSharp\SharpWebSocket.cs" />
<Compile Include="HttpServer\SocketSharp\WebSocketSharpListener.cs" />
+ <Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" />
<Compile Include="HttpServer\SocketSharp\WebSocketSharpResponse.cs" />
<Compile Include="HttpServer\StreamWriter.cs" />
<Compile Include="HttpServer\SwaggerService.cs" />
<Compile Include="Images\BaseDynamicImageProvider.cs" />
<Compile Include="Intros\DefaultIntroProvider.cs" />
<Compile Include="IO\FileRefresher.cs" />
+ <Compile Include="IO\MbLinkShortcutHandler.cs" />
<Compile Include="IO\ThrottledStream.cs" />
<Compile Include="Library\CoreResolutionIgnoreRule.cs" />
<Compile Include="Library\LibraryManager.cs" />
@@ -156,7 +163,6 @@
<Compile Include="LiveTv\TunerHosts\MulticastStream.cs" />
<Compile Include="LiveTv\TunerHosts\QueueStream.cs" />
<Compile Include="Localization\LocalizationManager.cs" />
- <Compile Include="Logging\PatternsLogger.cs" />
<Compile Include="MediaEncoder\EncodingManager.cs" />
<Compile Include="News\NewsEntryPoint.cs" />
<Compile Include="News\NewsService.cs" />
@@ -171,6 +177,7 @@
<Compile Include="Photos\PhotoAlbumImageProvider.cs" />
<Compile Include="Playlists\PlaylistImageProvider.cs" />
<Compile Include="Playlists\PlaylistManager.cs" />
+ <Compile Include="Playlists\PlaylistsDynamicFolder.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ScheduledTasks\ChapterImagesTask.cs" />
<Compile Include="ScheduledTasks\PeopleValidationTask.cs" />
@@ -263,135 +270,32 @@
<Project>{442b5058-dcaf-4263-bb6a-f21e31120a1b}</Project>
<Name>MediaBrowser.Providers</Name>
</ProjectReference>
- <Reference Include="SocketHttpListener.Portable">
- <HintPath>..\ThirdParty\emby\SocketHttpListener.Portable.dll</HintPath>
- </Reference>
- <Reference Include="UniversalDetector, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\UniversalDetector.1.0.1\lib\portable-net45+sl4+wp71+win8+wpa81\UniversalDetector.dll</HintPath>
- <Private>True</Private>
- </Reference>
+ <ProjectReference Include="..\MediaBrowser.Server.Implementations\MediaBrowser.Server.Implementations.csproj">
+ <Project>{2e781478-814d-4a48-9d80-bff206441a65}</Project>
+ <Name>MediaBrowser.Server.Implementations</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\ServiceStack\ServiceStack.csproj">
+ <Project>{680a1709-25eb-4d52-a87f-ee03ffd94baa}</Project>
+ <Name>ServiceStack</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\SocketHttpListener.Portable\SocketHttpListener.Portable.csproj">
+ <Project>{4f26d5d8-a7b0-42b3-ba42-7cb7d245934e}</Project>
+ <Name>SocketHttpListener.Portable</Name>
+ </ProjectReference>
<Reference Include="Emby.XmlTv, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\Emby.XmlTv.1.0.0.63\lib\portable-net45+win8\Emby.XmlTv.dll</HintPath>
+ <HintPath>..\packages\Emby.XmlTv.1.0.1\lib\portable-net45+win8\Emby.XmlTv.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="MediaBrowser.Naming, Version=1.0.6151.30291, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\MediaBrowser.Naming.1.0.0.59\lib\portable-net45+win8\MediaBrowser.Naming.dll</HintPath>
+ <Reference Include="MediaBrowser.Naming, Version=1.0.6159.25070, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\MediaBrowser.Naming.1.0.2\lib\portable-net45+win8\MediaBrowser.Naming.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="Patterns.Logging, Version=1.0.6151.30227, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\Patterns.Logging.1.0.0.6\lib\portable-net45+win8\Patterns.Logging.dll</HintPath>
+ <Reference Include="UniversalDetector, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\UniversalDetector.1.0.1\lib\portable-net45+sl4+wp71+win8+wpa81\UniversalDetector.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\backbone-min.js">
- <Link>swagger-ui\lib\backbone-min.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\handlebars-2.0.0.js">
- <Link>swagger-ui\lib\handlebars-2.0.0.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\highlight.7.3.pack.js">
- <Link>swagger-ui\lib\highlight.7.3.pack.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\jquery-1.8.0.min.js">
- <Link>swagger-ui\lib\jquery-1.8.0.min.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\jquery.ba-bbq.min.js">
- <Link>swagger-ui\lib\jquery.ba-bbq.min.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\jquery.slideto.min.js">
- <Link>swagger-ui\lib\jquery.slideto.min.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\jquery.wiggle.min.js">
- <Link>swagger-ui\lib\jquery.wiggle.min.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\marked.js">
- <Link>swagger-ui\lib\marked.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\shred.bundle.js">
- <Link>swagger-ui\lib\shred.bundle.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\swagger-client.js">
- <Link>swagger-ui\lib\swagger-client.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\swagger-oauth.js">
- <Link>swagger-ui\lib\swagger-oauth.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\lib\underscore-min.js">
- <Link>swagger-ui\lib\underscore-min.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\o2c.html">
- <Link>swagger-ui\o2c.html</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\patch.js">
- <Link>swagger-ui\patch.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\swagger-ui.js">
- <Link>swagger-ui\swagger-ui.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\swagger-ui.min.js">
- <Link>swagger-ui\swagger-ui.min.js</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\fonts\droid-sans-v6-latin-700.eot">
- <Link>swagger-ui\fonts\droid-sans-v6-latin-700.eot</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\fonts\droid-sans-v6-latin-700.ttf">
- <Link>swagger-ui\fonts\droid-sans-v6-latin-700.ttf</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\fonts\droid-sans-v6-latin-700.woff">
- <Link>swagger-ui\fonts\droid-sans-v6-latin-700.woff</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\fonts\droid-sans-v6-latin-700.woff2">
- <Link>swagger-ui\fonts\droid-sans-v6-latin-700.woff2</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\fonts\droid-sans-v6-latin-regular.eot">
- <Link>swagger-ui\fonts\droid-sans-v6-latin-regular.eot</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\fonts\droid-sans-v6-latin-regular.ttf">
- <Link>swagger-ui\fonts\droid-sans-v6-latin-regular.ttf</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\fonts\droid-sans-v6-latin-regular.woff">
- <Link>swagger-ui\fonts\droid-sans-v6-latin-regular.woff</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\fonts\droid-sans-v6-latin-regular.woff2">
- <Link>swagger-ui\fonts\droid-sans-v6-latin-regular.woff2</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\css\reset.css">
- <Link>swagger-ui\css\reset.css</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\css\screen.css">
- <Link>swagger-ui\css\screen.css</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="..\ThirdParty\ServiceStack\swagger-ui\css\typography.css">
- <Link>swagger-ui\css\typography.css</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<EmbeddedResource Include="Localization\Core\ar.json" />
<EmbeddedResource Include="Localization\Core\bg-BG.json" />
<EmbeddedResource Include="Localization\Core\ca.json" />
diff --git a/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
index 3f4ede4789..cc2dcb6fd1 100644
--- a/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
+++ b/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
@@ -15,7 +15,6 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.Library;
-using Emby.Server.Implementations.Logging;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
@@ -71,7 +70,7 @@ namespace Emby.Server.Implementations.FileOrganization
}
var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
- var resolver = new EpisodeResolver(namingOptions, new PatternsLogger());
+ var resolver = new EpisodeResolver(namingOptions, new NullLogger());
var episodeInfo = resolver.Resolve(path, false) ??
new MediaBrowser.Naming.TV.EpisodeInfo();
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index 643d0c9560..64f498b124 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -2,20 +2,14 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Logging;
-using MediaBrowser.Server.Implementations.HttpServer.SocketSharp;
using ServiceStack;
using ServiceStack.Host;
-using ServiceStack.Web;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Net.Security;
-using System.Net.Sockets;
using System.Reflection;
-using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
-using Emby.Common.Implementations.Net;
using Emby.Server.Implementations.HttpServer;
using Emby.Server.Implementations.HttpServer.SocketSharp;
using MediaBrowser.Common.Net;
@@ -27,11 +21,12 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
+using MediaBrowser.Model.System;
using MediaBrowser.Model.Text;
using SocketHttpListener.Net;
using SocketHttpListener.Primitives;
-namespace MediaBrowser.Server.Implementations.HttpServer
+namespace Emby.Server.Implementations.HttpServer
{
public class HttpListenerHost : ServiceStackHost, IHttpServer
{
@@ -47,8 +42,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
public event EventHandler<WebSocketConnectEventArgs> WebSocketConnected;
public event EventHandler<WebSocketConnectingEventArgs> WebSocketConnecting;
- public string CertificatePath { get; private set; }
-
private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager;
private readonly IMemoryStreamFactory _memoryStreamProvider;
@@ -61,13 +54,17 @@ namespace MediaBrowser.Server.Implementations.HttpServer
private readonly IJsonSerializer _jsonSerializer;
private readonly IXmlSerializer _xmlSerializer;
+ private readonly ICertificate _certificate;
+ private readonly IEnvironmentInfo _environment;
+ private readonly IStreamFactory _streamFactory;
+ private readonly Func<Type, Func<string, object>> _funcParseFn;
public HttpListenerHost(IServerApplicationHost applicationHost,
- ILogManager logManager,
+ ILogger logger,
IServerConfigurationManager config,
string serviceName,
- string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, IJsonSerializer jsonSerializer, IXmlSerializer xmlSerializer)
- : base(serviceName, new Assembly[] { })
+ string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, IJsonSerializer jsonSerializer, IXmlSerializer xmlSerializer, IEnvironmentInfo environment, ICertificate certificate, IStreamFactory streamFactory, Func<Type, Func<string, object>> funcParseFn)
+ : base(serviceName)
{
_appHost = applicationHost;
DefaultRedirectPath = defaultRedirectPath;
@@ -78,28 +75,29 @@ namespace MediaBrowser.Server.Implementations.HttpServer
_cryptoProvider = cryptoProvider;
_jsonSerializer = jsonSerializer;
_xmlSerializer = xmlSerializer;
+ _environment = environment;
+ _certificate = certificate;
+ _streamFactory = streamFactory;
+ _funcParseFn = funcParseFn;
_config = config;
- _logger = logManager.GetLogger("HttpServer");
+ _logger = logger;
}
public string GlobalResponse { get; set; }
public override void Configure()
{
- HostConfig.Instance.DefaultRedirectPath = DefaultRedirectPath;
-
- HostConfig.Instance.MapExceptionToStatusCode = new Dictionary<Type, int>
+ var mapExceptionToStatusCode = new Dictionary<Type, int>
{
{typeof (InvalidOperationException), 500},
{typeof (NotImplementedException), 500},
{typeof (ResourceNotFoundException), 404},
{typeof (FileNotFoundException), 404},
- {typeof (DirectoryNotFoundException), 404},
+ //{typeof (DirectoryNotFoundException), 404},
{typeof (SecurityException), 401},
{typeof (PaymentRequiredException), 402},
{typeof (UnauthorizedAccessException), 500},
- {typeof (ApplicationException), 500},
{typeof (PlatformNotSupportedException), 500},
{typeof (NotSupportedException), 500}
};
@@ -136,18 +134,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
return _appHost.CreateInstance(type);
}
- public override void OnConfigLoad()
- {
- base.OnConfigLoad();
-
- Config.HandlerFactoryPath = null;
- }
-
- protected override ServiceController CreateServiceController(params Assembly[] assembliesWithServices)
+ protected override ServiceController CreateServiceController()
{
var types = _restServices.Select(r => r.GetType()).ToArray();
- return new ServiceController(this, () => types);
+ return new ServiceController(() => types);
}
public override ServiceStackHost Start(string listeningAtUrlBase)
@@ -161,7 +152,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
/// </summary>
private void StartListener()
{
- HostContext.Config.HandlerFactoryPath = GetHandlerPathIfAny(UrlPrefixes.First());
+ WebSocketSharpRequest.HandlerFactoryPath = GetHandlerPathIfAny(UrlPrefixes.First());
_listener = GetListener();
@@ -187,34 +178,18 @@ namespace MediaBrowser.Server.Implementations.HttpServer
private IHttpListener GetListener()
{
- var cert = !string.IsNullOrWhiteSpace(CertificatePath) && File.Exists(CertificatePath)
- ? GetCert(CertificatePath) :
- null;
-
- var enableDualMode = Environment.OSVersion.Platform == PlatformID.Win32NT;
-
- return new WebSocketSharpListener(_logger, cert, _memoryStreamProvider, _textEncoding, _networkManager, _socketFactory, _cryptoProvider, new StreamFactory(), enableDualMode, GetRequest);
- }
-
- public ICertificate GetCert(string certificateLocation)
- {
- try
- {
- X509Certificate2 localCert = new X509Certificate2(certificateLocation);
- //localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA;
- if (localCert.PrivateKey == null)
- {
- //throw new FileNotFoundException("Secure requested, no private key included", certificateLocation);
- return null;
- }
+ var enableDualMode = _environment.OperatingSystem == OperatingSystem.Windows;
- return new Certificate(localCert);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error loading cert from {0}", ex, certificateLocation);
- return null;
- }
+ return new WebSocketSharpListener(_logger,
+ _certificate,
+ _memoryStreamProvider,
+ _textEncoding,
+ _networkManager,
+ _socketFactory,
+ _cryptoProvider,
+ _streamFactory,
+ enableDualMode,
+ GetRequest);
}
private IHttpRequest GetRequest(HttpListenerContext httpContext)
@@ -328,7 +303,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer
// this gets all the query string key value pairs as a collection
var newQueryString = MyHttpUtility.ParseQueryString(uri.Query);
- if (newQueryString.Count == 0)
+ var originalCount = newQueryString.Count;
+
+ if (originalCount == 0)
{
return url;
}
@@ -336,8 +313,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer
// this removes the key if exists
newQueryString.Remove(key);
+ if (originalCount == newQueryString.Count)
+ {
+ return url;
+ }
+
// this gets the page path from root without QueryString
- string pagePathWithoutQueryString = uri.GetLeftPart(UriPartial.Path);
+ string pagePathWithoutQueryString = url.Split(new[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[0];
return newQueryString.Count > 0
? String.Format("{0}?{1}", pagePathWithoutQueryString, newQueryString)
@@ -578,28 +560,28 @@ namespace MediaBrowser.Server.Implementations.HttpServer
base.Init();
}
- public override Model.Services.RouteAttribute[] GetRouteAttributes(Type requestType)
+ public override RouteAttribute[] GetRouteAttributes(Type requestType)
{
var routes = base.GetRouteAttributes(requestType).ToList();
var clone = routes.ToList();
foreach (var route in clone)
{
- routes.Add(new Model.Services.RouteAttribute(NormalizeEmbyRoutePath(route.Path), route.Verbs)
+ routes.Add(new RouteAttribute(NormalizeEmbyRoutePath(route.Path), route.Verbs)
{
Notes = route.Notes,
Priority = route.Priority,
Summary = route.Summary
});
- routes.Add(new Model.Services.RouteAttribute(NormalizeRoutePath(route.Path), route.Verbs)
+ routes.Add(new RouteAttribute(NormalizeRoutePath(route.Path), route.Verbs)
{
Notes = route.Notes,
Priority = route.Priority,
Summary = route.Summary
});
- routes.Add(new Model.Services.RouteAttribute(DoubleNormalizeEmbyRoutePath(route.Path), route.Verbs)
+ routes.Add(new RouteAttribute(DoubleNormalizeEmbyRoutePath(route.Path), route.Verbs)
{
Notes = route.Notes,
Priority = route.Priority,
@@ -610,6 +592,38 @@ namespace MediaBrowser.Server.Implementations.HttpServer
return routes.ToArray();
}
+ public override object GetTaskResult(Task task, string requestName)
+ {
+ try
+ {
+ var taskObject = task as Task<object>;
+ if (taskObject != null)
+ {
+ return taskObject.Result;
+ }
+
+ task.Wait();
+
+ var type = task.GetType().GetTypeInfo();
+ if (!type.IsGenericType)
+ {
+ return null;
+ }
+
+ Logger.Warn("Getting task result from " + requestName + " using reflection. For better performance have your api return Task<object>");
+ return type.GetDeclaredProperty("Result").GetValue(task);
+ }
+ catch (TypeAccessException)
+ {
+ return null; //return null for void Task's
+ }
+ }
+
+ public override Func<string, object> GetParseFn(Type propertyType)
+ {
+ return _funcParseFn(propertyType);
+ }
+
public override void SerializeToJson(object o, Stream stream)
{
_jsonSerializer.SerializeToStream(o, stream);
@@ -687,44 +701,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer
GC.SuppressFinalize(this);
}
- public void StartServer(IEnumerable<string> urlPrefixes, string certificatePath)
+ public void StartServer(IEnumerable<string> urlPrefixes)
{
- CertificatePath = certificatePath;
UrlPrefixes = urlPrefixes.ToList();
Start(UrlPrefixes.First());
}
}
-
- public class StreamFactory : IStreamFactory
- {
- public Stream CreateNetworkStream(ISocket socket, bool ownsSocket)
- {
- var netSocket = (NetSocket)socket;
-
- return new NetworkStream(netSocket.Socket, ownsSocket);
- }
-
- public Task AuthenticateSslStreamAsServer(Stream stream, ICertificate certificate)
- {
- var sslStream = (SslStream)stream;
- var cert = (Certificate)certificate;
-
- return sslStream.AuthenticateAsServerAsync(cert.X509Certificate);
- }
-
- public Stream CreateSslStream(Stream innerStream, bool leaveInnerStreamOpen)
- {
- return new SslStream(innerStream, leaveInnerStreamOpen);
- }
- }
-
- public class Certificate : ICertificate
- {
- public Certificate(X509Certificate x509Certificate)
- {
- X509Certificate = x509Certificate;
- }
-
- public X509Certificate X509Certificate { get; private set; }
- }
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
index b013a0952b..bbd5566616 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -21,7 +21,7 @@ using IRequest = MediaBrowser.Model.Services.IRequest;
using MimeTypes = MediaBrowser.Model.Net.MimeTypes;
using StreamWriter = Emby.Server.Implementations.HttpServer.StreamWriter;
-namespace MediaBrowser.Server.Implementations.HttpServer
+namespace Emby.Server.Implementations.HttpServer
{
/// <summary>
/// Class HttpResultFactory
@@ -161,13 +161,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer
public static string GetCompressionType(IRequest request)
{
- var prefs = new RequestPreferences(request);
+ var acceptEncoding = request.Headers["Accept-Encoding"];
- if (prefs.AcceptsDeflate)
- return "deflate";
+ if (!string.IsNullOrWhiteSpace(acceptEncoding))
+ {
+ if (acceptEncoding.Contains("deflate"))
+ return "deflate";
- if (prefs.AcceptsGzip)
- return "gzip";
+ if (acceptEncoding.Contains("gzip"))
+ return "gzip";
+ }
return null;
}
@@ -187,14 +190,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer
if (compressionType == null)
{
var contentType = request.ResponseContentType;
- var contentTypeAttr = ContentFormat.GetEndpointAttributes(contentType);
- switch (contentTypeAttr)
+ switch (GetRealContentType(contentType))
{
- case RequestAttributes.Xml:
+ case "application/xml":
+ case "text/xml":
+ case "text/xml; charset=utf-8": //"text/xml; charset=utf-8" also matches xml
return SerializeToXmlString(dto);
- case RequestAttributes.Json:
+ case "application/json":
+ case "text/json":
return _jsonSerializer.SerializeToString(dto);
}
}
@@ -204,7 +209,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
using (var compressionStream = GetCompressionStream(ms, compressionType))
{
ContentTypes.Instance.SerializeToStream(request, dto, compressionStream);
- compressionStream.Close();
+ compressionStream.Dispose();
var compressedBytes = ms.ToArray();
@@ -221,6 +226,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer
}
}
+ public static string GetRealContentType(string contentType)
+ {
+ return contentType == null
+ ? null
+ : contentType.Split(';')[0].ToLower().Trim();
+ }
+
public static string SerializeToXmlString(object from)
{
using (var ms = new MemoryStream())
@@ -520,7 +532,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
private bool ShouldCompressResponse(IRequest requestContext, string contentType)
{
// It will take some work to support compression with byte range requests
- if (!string.IsNullOrEmpty(requestContext.GetHeader("Range")))
+ if (!string.IsNullOrEmpty(requestContext.Headers.Get("Range")))
{
return false;
}
@@ -573,7 +585,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
if (!compress || string.IsNullOrEmpty(requestedCompressionType))
{
- var rangeHeader = requestContext.GetHeader("Range");
+ var rangeHeader = requestContext.Headers.Get("Range");
var stream = await factoryFn().ConfigureAwait(false);
@@ -648,7 +660,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
using (var zipStream = new DeflateStream(ms, CompressionMode.Compress))
{
zipStream.Write(bytes, 0, bytes.Length);
- zipStream.Close();
+ zipStream.Dispose();
return ms.ToArray();
}
@@ -665,7 +677,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
using (var zipStream = new GZipStream(ms, CompressionMode.Compress))
{
zipStream.Write(buffer, 0, buffer.Length);
- zipStream.Close();
+ zipStream.Dispose();
return ms.ToArray();
}
@@ -747,7 +759,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
{
var isNotModified = true;
- var ifModifiedSinceHeader = requestContext.GetHeader("If-Modified-Since");
+ var ifModifiedSinceHeader = requestContext.Headers.Get("If-Modified-Since");
if (!string.IsNullOrEmpty(ifModifiedSinceHeader))
{
@@ -759,7 +771,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
}
}
- var ifNoneMatchHeader = requestContext.GetHeader("If-None-Match");
+ var ifNoneMatchHeader = requestContext.Headers.Get("If-None-Match");
// Validate If-None-Match
if (isNotModified && (cacheKey.HasValue || !string.IsNullOrEmpty(ifNoneMatchHeader)))
diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs
index 543eb4afe2..ec14c32c8f 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs
+++ b/Emby.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
@@ -7,7 +8,7 @@ using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
-namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
+namespace Emby.Server.Implementations.HttpServer.SocketSharp
{
public partial class WebSocketSharpRequest : IHttpRequest
{
@@ -68,7 +69,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
input.Position = e.Start;
input.Read(copy, 0, (int)e.Length);
- form.Add(e.Name, (e.Encoding ?? ContentEncoding).GetString(copy));
+ form.Add(e.Name, (e.Encoding ?? ContentEncoding).GetString(copy, 0, copy.Length));
}
else
{
@@ -76,7 +77,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
// We use a substream, as in 2.x we will support large uploads streamed to disk,
//
HttpPostedFile sub = new HttpPostedFile(e.Filename, e.ContentType, input, e.Start, e.Length);
- files.AddFile(e.Name, sub);
+ files[e.Name] = sub;
}
}
}
@@ -89,7 +90,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
if (form == null)
{
form = new WebROCollection();
- files = new HttpFileCollection();
+ files = new Dictionary<string, HttpPostedFile>();
if (IsContentType("multipart/form-data", true))
{
@@ -224,7 +225,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
if (starts_with)
return StrUtils.StartsWith(ContentType, ct, true);
- return String.Compare(ContentType, ct, true, Helpers.InvariantCulture) == 0;
+ return string.Equals(ContentType, ct, StringComparison.OrdinalIgnoreCase);
}
async Task LoadWwwForm()
@@ -287,67 +288,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
WebROCollection form;
- HttpFileCollection files;
+ Dictionary<string, HttpPostedFile> files;
- public sealed class HttpFileCollection : NameObjectCollectionBase
- {
- internal HttpFileCollection()
- {
- }
-
- internal void AddFile(string name, HttpPostedFile file)
- {
- BaseAdd(name, file);
- }
-
- public void CopyTo(Array dest, int index)
- {
- /* XXX this is kind of gross and inefficient
- * since it makes a copy of the superclass's
- * list */
- object[] values = BaseGetAllValues();
- values.CopyTo(dest, index);
- }
-
- public string GetKey(int index)
- {
- return BaseGetKey(index);
- }
-
- public HttpPostedFile Get(int index)
- {
- return (HttpPostedFile)BaseGet(index);
- }
-
- public HttpPostedFile Get(string key)
- {
- return (HttpPostedFile)BaseGet(key);
- }
-
- public HttpPostedFile this[string key]
- {
- get
- {
- return Get(key);
- }
- }
-
- public HttpPostedFile this[int index]
- {
- get
- {
- return Get(index);
- }
- }
-
- public string[] AllKeys
- {
- get
- {
- return BaseGetAllKeys();
- }
- }
- }
class WebROCollection : QueryParamCollection
{
bool got_id;
@@ -589,29 +531,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
internal sealed class StrUtils
{
- StrUtils() { }
-
- public static bool StartsWith(string str1, string str2)
- {
- return StartsWith(str1, str2, false);
- }
-
public static bool StartsWith(string str1, string str2, bool ignore_case)
{
- int l2 = str2.Length;
- if (l2 == 0)
- return true;
-
- int l1 = str1.Length;
- if (l2 > l1)
+ if (string.IsNullOrWhiteSpace(str1))
+ {
return false;
+ }
- return 0 == String.Compare(str1, 0, str2, 0, l2, ignore_case, Helpers.InvariantCulture);
- }
-
- public static bool EndsWith(string str1, string str2)
- {
- return EndsWith(str1, str2, false);
+ var comparison = ignore_case ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
+ return str1.IndexOf(str2, comparison) == 0;
}
public static bool EndsWith(string str1, string str2, bool ignore_case)
@@ -624,7 +552,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
if (l2 > l1)
return false;
- return 0 == String.Compare(str1, l1 - l2, str2, 0, l2, ignore_case, Helpers.InvariantCulture);
+ var comparison = ignore_case ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
+ return str1.IndexOf(str2, comparison) == str1.Length - str2.Length - 1;
}
}
@@ -742,7 +671,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
for (int i = temp.Length - 1; i >= 0; i--)
source[i] = (byte)temp[i];
- return encoding.GetString(source);
+ return encoding.GetString(source, 0, source.Length);
}
bool ReadBoundary()
diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
index db7b9bc4b4..94cc383a7a 100644
--- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
+++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
@@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using Emby.Server.Implementations.Logging;
using MediaBrowser.Common.Net;
using MediaBrowser.Model.Cryptography;
using MediaBrowser.Model.IO;
@@ -55,7 +54,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
public void Start(IEnumerable<string> urlPrefixes)
{
if (_listener == null)
- _listener = new HttpListener(new PatternsLogger(_logger), _cryptoProvider, _streamFactory, _socketFactory, _networkManager, _textEncoding, _memoryStreamProvider);
+ _listener = new HttpListener(_logger, _cryptoProvider, _streamFactory, _socketFactory, _networkManager, _textEncoding, _memoryStreamProvider);
_listener.EnableDualMode = _enableDualMode;
diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs
index 95b2ccaba3..b3fcde7456 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs
+++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs
@@ -1,20 +1,20 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Net;
using System.Text;
+using Emby.Server.Implementations.HttpServer;
using Emby.Server.Implementations.HttpServer.SocketSharp;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Services;
-using ServiceStack;
-using ServiceStack.Host;
using SocketHttpListener.Net;
using IHttpFile = MediaBrowser.Model.Services.IHttpFile;
using IHttpRequest = MediaBrowser.Model.Services.IHttpRequest;
using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse;
using IResponse = MediaBrowser.Model.Services.IResponse;
-namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
+namespace Emby.Server.Implementations.HttpServer.SocketSharp
{
public partial class WebSocketSharpRequest : IHttpRequest
{
@@ -244,14 +244,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
var specifiedContentType = GetQueryStringContentType(httpReq);
if (!string.IsNullOrEmpty(specifiedContentType)) return specifiedContentType;
+ var serverDefaultContentType = "application/json";
+
var acceptContentTypes = httpReq.AcceptTypes;
var defaultContentType = httpReq.ContentType;
if (HasAnyOfContentTypes(httpReq, FormUrlEncoded, MultiPartFormData))
{
- defaultContentType = HostContext.Config.DefaultContentType;
+ defaultContentType = serverDefaultContentType;
}
- var customContentTypes = ContentTypes.Instance.ContentTypeFormats.Values;
var preferredContentTypes = new string[] {};
var acceptsAnything = false;
@@ -261,7 +262,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
var hasPreferredContentTypes = new bool[preferredContentTypes.Length];
foreach (var acceptsType in acceptContentTypes)
{
- var contentType = ContentFormat.GetRealContentType(acceptsType);
+ var contentType = HttpResultFactory.GetRealContentType(acceptsType);
acceptsAnything = acceptsAnything || contentType == "*/*";
for (var i = 0; i < preferredContentTypes.Length; i++)
@@ -285,17 +286,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
{
if (hasDefaultContentType)
return defaultContentType;
- if (HostContext.Config.DefaultContentType != null)
- return HostContext.Config.DefaultContentType;
- }
-
- foreach (var contentType in acceptContentTypes)
- {
- foreach (var customContentType in customContentTypes)
- {
- if (contentType.StartsWith(customContentType, StringComparison.OrdinalIgnoreCase))
- return customContentType;
- }
+ if (serverDefaultContentType != null)
+ return serverDefaultContentType;
}
}
@@ -305,8 +297,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
}
//We could also send a '406 Not Acceptable', but this is allowed also
- return HostContext.Config.DefaultContentType;
+ return serverDefaultContentType;
}
+
public const string Soap11 = "text/xml; charset=utf-8";
public static bool HasAnyOfContentTypes(IRequest request, params string[] contentTypes)
@@ -334,22 +327,30 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
var pi = httpReq.PathInfo;
if (pi == null || pi.Length <= formatMaxLength) return null;
if (pi[0] == '/') pi = pi.Substring(1);
- format = pi.LeftPart('/');
+ format = LeftPart(pi, '/');
if (format.Length > formatMaxLength) return null;
}
- format = format.LeftPart('.').ToLower();
+ format = LeftPart(format, '.').ToLower();
if (format.Contains("json")) return "application/json";
if (format.Contains("xml")) return Xml;
- string contentType;
- ContentTypes.Instance.ContentTypeFormats.TryGetValue(format, out contentType);
+ return null;
+ }
- return contentType;
+ public static string LeftPart(string strVal, char needle)
+ {
+ if (strVal == null) return null;
+ var pos = strVal.IndexOf(needle);
+ return pos == -1
+ ? strVal
+ : strVal.Substring(0, pos);
}
public bool HasExplicitResponseContentType { get; private set; }
+ public static string HandlerFactoryPath;
+
private string pathInfo;
public string PathInfo
{
@@ -357,7 +358,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
{
if (this.pathInfo == null)
{
- var mode = HostContext.Config.HandlerFactoryPath;
+ var mode = HandlerFactoryPath;
var pos = request.RawUrl.IndexOf("?");
if (pos != -1)
@@ -373,7 +374,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
this.pathInfo = request.RawUrl;
}
- this.pathInfo = this.pathInfo.UrlDecode();
+ this.pathInfo = WebUtility.UrlDecode(pathInfo);
this.pathInfo = NormalizePathInfo(pathInfo, mode);
}
return this.pathInfo;
@@ -437,9 +438,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
if (cookies == null)
{
cookies = new Dictionary<string, System.Net.Cookie>();
- for (var i = 0; i < this.request.Cookies.Count; i++)
+ foreach (var cookie in this.request.Cookies)
{
- var httpCookie = this.request.Cookies[i];
+ var httpCookie = (Cookie) cookie;
cookies[httpCookie.Name] = new System.Net.Cookie(httpCookie.Name, httpCookie.Value, httpCookie.Path, httpCookie.Domain);
}
}
@@ -549,10 +550,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
return httpFiles = new IHttpFile[0];
httpFiles = new IHttpFile[files.Count];
- for (var i = 0; i < files.Count; i++)
+ var i = 0;
+ foreach (var pair in files)
{
- var reqFile = files[i];
-
+ var reqFile = pair.Value;
httpFiles[i] = new HttpFile
{
ContentType = reqFile.ContentType,
@@ -560,6 +561,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
FileName = reqFile.FileName,
InputStream = reqFile.InputStream,
};
+ i++;
}
}
return httpFiles;
@@ -571,14 +573,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
if (stream is MemoryStream)
{
var other = (MemoryStream)stream;
- try
- {
- return new MemoryStream(other.GetBuffer(), 0, (int)other.Length, false, true);
- }
- catch (UnauthorizedAccessException)
+
+ byte[] buffer;
+ if (streamProvider.TryGetBuffer(other, out buffer))
{
- return new MemoryStream(other.ToArray(), 0, (int)other.Length, false, true);
+ return streamProvider.CreateNew(buffer);
}
+ return streamProvider.CreateNew(other.ToArray());
}
return stream;
@@ -587,7 +588,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
public static string GetHandlerPathIfAny(string listenerUrl)
{
if (listenerUrl == null) return null;
- var pos = listenerUrl.IndexOf("://", StringComparison.InvariantCultureIgnoreCase);
+ var pos = listenerUrl.IndexOf("://", StringComparison.OrdinalIgnoreCase);
if (pos == -1) return null;
var startHostUrl = listenerUrl.Substring(pos + "://".Length);
var endPos = startHostUrl.IndexOf('/');
@@ -599,7 +600,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
public static string NormalizePathInfo(string pathInfo, string handlerPath)
{
if (handlerPath != null && pathInfo.TrimStart('/').StartsWith(
- handlerPath, StringComparison.InvariantCultureIgnoreCase))
+ handlerPath, StringComparison.OrdinalIgnoreCase))
{
return pathInfo.TrimStart('/').Substring(handlerPath.Length);
}
diff --git a/MediaBrowser.Server.Startup.Common/MbLinkShortcutHandler.cs b/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs
index 26318365b6..0b1391ae02 100644
--- a/MediaBrowser.Server.Startup.Common/MbLinkShortcutHandler.cs
+++ b/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs
@@ -4,7 +4,7 @@ using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
-namespace MediaBrowser.Server.Startup.Common
+namespace Emby.Server.Implementations.IO
{
public class MbLinkShortcutHandler : IShortcutHandler
{
@@ -49,7 +49,7 @@ namespace MediaBrowser.Server.Startup.Common
throw new ArgumentNullException("targetPath");
}
- File.WriteAllText(shortcutPath, targetPath);
+ _fileSystem.WriteAllText(shortcutPath, targetPath);
}
}
}
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 8800777ca9..13c6485e5b 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -29,7 +29,6 @@ using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.Library.Resolvers;
using Emby.Server.Implementations.Library.Validators;
-using Emby.Server.Implementations.Logging;
using Emby.Server.Implementations.ScheduledTasks;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller.Channels;
@@ -2266,7 +2265,7 @@ namespace Emby.Server.Implementations.Library
public bool IsVideoFile(string path, LibraryOptions libraryOptions)
{
- var resolver = new VideoResolver(GetNamingOptions(libraryOptions), new PatternsLogger());
+ var resolver = new VideoResolver(GetNamingOptions(libraryOptions), new NullLogger());
return resolver.IsVideoFile(path);
}
@@ -2294,7 +2293,7 @@ namespace Emby.Server.Implementations.Library
public bool FillMissingEpisodeNumbersFromPath(Episode episode)
{
var resolver = new EpisodeResolver(GetNamingOptions(),
- new PatternsLogger());
+ new NullLogger());
var isFolder = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd ||
episode.VideoType == VideoType.HdDvd;
@@ -2440,7 +2439,7 @@ namespace Emby.Server.Implementations.Library
public ItemLookupInfo ParseName(string name)
{
- var resolver = new VideoResolver(GetNamingOptions(), new PatternsLogger());
+ var resolver = new VideoResolver(GetNamingOptions(), new NullLogger());
var result = resolver.CleanDateTime(name);
var cleanName = resolver.CleanString(result.Name);
@@ -2459,7 +2458,7 @@ namespace Emby.Server.Implementations.Library
.SelectMany(i => _fileSystem.GetFiles(i.FullName, false))
.ToList();
- var videoListResolver = new VideoListResolver(GetNamingOptions(), new PatternsLogger());
+ var videoListResolver = new VideoListResolver(GetNamingOptions(), new NullLogger());
var videos = videoListResolver.Resolve(fileSystemChildren);
@@ -2505,7 +2504,7 @@ namespace Emby.Server.Implementations.Library
.SelectMany(i => _fileSystem.GetFiles(i.FullName, false))
.ToList();
- var videoListResolver = new VideoListResolver(GetNamingOptions(), new PatternsLogger());
+ var videoListResolver = new VideoListResolver(GetNamingOptions(), new NullLogger());
var videos = videoListResolver.Resolve(fileSystemChildren);
@@ -2628,7 +2627,7 @@ namespace Emby.Server.Implementations.Library
private void SetExtraTypeFromFilename(Video item)
{
- var resolver = new ExtraResolver(GetNamingOptions(), new PatternsLogger(), new RegexProvider());
+ var resolver = new ExtraResolver(GetNamingOptions(), new NullLogger(), new RegexProvider());
var result = resolver.GetExtraInfo(item.Path);
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
index f8e1051951..871b2d46d6 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
@@ -8,7 +8,6 @@ using MediaBrowser.Naming.Audio;
using System;
using System.Collections.Generic;
using System.IO;
-using Emby.Server.Implementations.Logging;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller.Configuration;
@@ -164,7 +163,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
{
var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(libraryOptions);
- var parser = new AlbumParser(namingOptions, new PatternsLogger());
+ var parser = new AlbumParser(namingOptions, new NullLogger());
var result = parser.ParseMultiPart(path);
return result.IsMultiPart;
diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
index b7819eb68c..d9c3ac5ab2 100644
--- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
@@ -4,7 +4,7 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Naming.Video;
using System;
using System.IO;
-using Emby.Server.Implementations.Logging;
+using MediaBrowser.Model.Logging;
namespace Emby.Server.Implementations.Library.Resolvers
{
@@ -45,7 +45,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
// If the path is a file check for a matching extensions
- var parser = new MediaBrowser.Naming.Video.VideoResolver(namingOptions, new PatternsLogger());
+ var parser = new MediaBrowser.Naming.Video.VideoResolver(namingOptions, new NullLogger());
if (args.IsDirectory)
{
@@ -258,7 +258,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
{
var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
- var resolver = new Format3DParser(namingOptions, new PatternsLogger());
+ var resolver = new Format3DParser(namingOptions, new NullLogger());
var result = resolver.Parse(video.Path);
Set3DFormat(video, result.Is3D, result.Format3D);
diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index d8c8b2024e..002505b569 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -11,10 +11,10 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using Emby.Server.Implementations.Logging;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
namespace Emby.Server.Implementations.Library.Resolvers.Movies
{
@@ -133,7 +133,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
- var resolver = new VideoListResolver(namingOptions, new PatternsLogger());
+ var resolver = new VideoListResolver(namingOptions, new NullLogger());
var resolverResult = resolver.Resolve(files, suppportMultiEditions).ToList();
var result = new MultiItemResolverResult
@@ -486,7 +486,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
}
var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
- var resolver = new StackResolver(namingOptions, new PatternsLogger());
+ var resolver = new StackResolver(namingOptions, new NullLogger());
var result = resolver.ResolveDirectories(folderPaths);
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index 44eb0e3e2c..e5cad9f91b 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -10,7 +10,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using Emby.Server.Implementations.Logging;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller.Configuration;
@@ -171,7 +170,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
.ToList();
}
- var episodeResolver = new MediaBrowser.Naming.TV.EpisodeResolver(namingOptions, new PatternsLogger());
+ var episodeResolver = new MediaBrowser.Naming.TV.EpisodeResolver(namingOptions, new NullLogger());
var episodeInfo = episodeResolver.Resolve(fullName, false, false);
if (episodeInfo != null && episodeInfo.EpisodeNumber.HasValue)
{
diff --git a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
index 813f07fffd..c32af8eb1e 100644
--- a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
@@ -127,23 +127,7 @@ namespace Emby.Server.Implementations.Library.Validators
{
var item = _libraryManager.GetPerson(person.Key);
- var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview);
- var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 30;
-
- var defaultMetadataRefreshMode = performFullRefresh
- ? MetadataRefreshMode.FullRefresh
- : MetadataRefreshMode.Default;
-
- var imageRefreshMode = performFullRefresh
- ? ImageRefreshMode.FullRefresh
- : ImageRefreshMode.Default;
-
- var options = new MetadataRefreshOptions(_fileSystem)
- {
- MetadataRefreshMode = person.Value ? defaultMetadataRefreshMode : MetadataRefreshMode.ValidationOnly,
- ImageRefreshMode = person.Value ? imageRefreshMode : ImageRefreshMode.ValidationOnly,
- ForceSave = performFullRefresh
- };
+ var options = new MetadataRefreshOptions(_fileSystem);
await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false);
}
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index 57723e3c53..33db69ee2c 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -116,7 +116,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
}
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
- var reader = new XmlTvReader(path, GetLanguage(), null);
+ var reader = new XmlTvReader(path, GetLanguage());
var results = reader.GetProgrammes(channelNumber, startDateUtc, endDateUtc, cancellationToken);
return results.Select(p => GetProgramInfo(p, info));
@@ -175,7 +175,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// Add the channel image url
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
- var reader = new XmlTvReader(path, GetLanguage(), null);
+ var reader = new XmlTvReader(path, GetLanguage());
var results = reader.GetChannels().ToList();
if (channels != null)
@@ -208,7 +208,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, CancellationToken.None).ConfigureAwait(false);
- var reader = new XmlTvReader(path, GetLanguage(), null);
+ var reader = new XmlTvReader(path, GetLanguage());
var results = reader.GetChannels();
// Should this method be async?
@@ -219,7 +219,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
- var reader = new XmlTvReader(path, GetLanguage(), null);
+ var reader = new XmlTvReader(path, GetLanguage());
var results = reader.GetChannels();
// Should this method be async?
diff --git a/Emby.Server.Implementations/Logging/PatternsLogger.cs b/Emby.Server.Implementations/Logging/PatternsLogger.cs
deleted file mode 100644
index 6dbf33d617..0000000000
--- a/Emby.Server.Implementations/Logging/PatternsLogger.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using Patterns.Logging;
-using System;
-
-namespace Emby.Server.Implementations.Logging
-{
- public class PatternsLogger : ILogger
- {
- private readonly MediaBrowser.Model.Logging.ILogger _logger;
-
- public PatternsLogger()
- : this(new MediaBrowser.Model.Logging.NullLogger())
- {
- }
-
- public PatternsLogger(MediaBrowser.Model.Logging.ILogger logger)
- {
- _logger = logger;
- }
-
- public void Debug(string message, params object[] paramList)
- {
- _logger.Debug(message, paramList);
- }
-
- public void Error(string message, params object[] paramList)
- {
- _logger.Error(message, paramList);
- }
-
- public void ErrorException(string message, Exception exception, params object[] paramList)
- {
- _logger.ErrorException(message, exception, paramList);
- }
-
- public void Fatal(string message, params object[] paramList)
- {
- _logger.Fatal(message, paramList);
- }
-
- public void FatalException(string message, Exception exception, params object[] paramList)
- {
- _logger.FatalException(message, exception, paramList);
- }
-
- public void Info(string message, params object[] paramList)
- {
- _logger.Info(message, paramList);
- }
-
- public void Warn(string message, params object[] paramList)
- {
- _logger.Warn(message, paramList);
- }
-
- public void Log(LogSeverity severity, string message, params object[] paramList)
- {
- }
-
- public void LogMultiline(string message, LogSeverity severity, System.Text.StringBuilder additionalContent)
- {
- }
- }
-}
diff --git a/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs b/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs
new file mode 100644
index 0000000000..dacc937e1a
--- /dev/null
+++ b/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs
@@ -0,0 +1,32 @@
+using System.IO;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Server.Implementations.Playlists;
+
+namespace Emby.Server.Implementations.Playlists
+{
+ public class PlaylistsDynamicFolder : IVirtualFolderCreator
+ {
+ private readonly IApplicationPaths _appPaths;
+ private readonly IFileSystem _fileSystem;
+
+ public PlaylistsDynamicFolder(IApplicationPaths appPaths, IFileSystem fileSystem)
+ {
+ _appPaths = appPaths;
+ _fileSystem = fileSystem;
+ }
+
+ public BasePluginFolder GetFolder()
+ {
+ var path = Path.Combine(_appPaths.DataPath, "playlists");
+
+ _fileSystem.CreateDirectory(path);
+
+ return new PlaylistsFolder
+ {
+ Path = path
+ };
+ }
+ }
+}
diff --git a/Emby.Server.Implementations/ServerManager/ServerManager.cs b/Emby.Server.Implementations/ServerManager/ServerManager.cs
index f660d01ec5..f7e4c0ce2b 100644
--- a/Emby.Server.Implementations/ServerManager/ServerManager.cs
+++ b/Emby.Server.Implementations/ServerManager/ServerManager.cs
@@ -112,22 +112,22 @@ namespace Emby.Server.Implementations.ServerManager
/// <summary>
/// Starts this instance.
/// </summary>
- public void Start(IEnumerable<string> urlPrefixes, string certificatePath)
+ public void Start(IEnumerable<string> urlPrefixes)
{
- ReloadHttpServer(urlPrefixes, certificatePath);
+ ReloadHttpServer(urlPrefixes);
}
/// <summary>
/// Restarts the Http Server, or starts it if not currently running
/// </summary>
- private void ReloadHttpServer(IEnumerable<string> urlPrefixes, string certificatePath)
+ private void ReloadHttpServer(IEnumerable<string> urlPrefixes)
{
_logger.Info("Loading Http Server");
try
{
HttpServer = _applicationHost.Resolve<IHttpServer>();
- HttpServer.StartServer(urlPrefixes, certificatePath);
+ HttpServer.StartServer(urlPrefixes);
}
catch (Exception ex)
{
diff --git a/Emby.Server.Implementations/packages.config b/Emby.Server.Implementations/packages.config
index 75c14aa58d..71fdbffc2d 100644
--- a/Emby.Server.Implementations/packages.config
+++ b/Emby.Server.Implementations/packages.config
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="MediaBrowser.Naming" version="1.0.0.59" targetFramework="portable45-net45+win8" />
- <package id="Patterns.Logging" version="1.0.0.6" targetFramework="portable45-net45+win8" />
+ <package id="Emby.XmlTv" version="1.0.1" targetFramework="portable45-net45+win8" />
+ <package id="MediaBrowser.Naming" version="1.0.2" targetFramework="portable45-net45+win8" />
<package id="UniversalDetector" version="1.0.1" targetFramework="portable45-net45+win8" />
- <package id="Emby.XmlTv" version="1.0.63" targetFramework="portable45-net45+win8" />
</packages> \ No newline at end of file
diff --git a/Emby.Server.sln b/Emby.Server.sln
index dce5e562ee..c6e057c424 100644
--- a/Emby.Server.sln
+++ b/Emby.Server.sln
@@ -34,25 +34,36 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSubtitlesHandler", "Ope
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Emby.Common.Implementations", "Emby.Common.Implementations\Emby.Common.Implementations.xproj", "{5A27010A-09C6-4E86-93EA-437484C10917}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Mono.Nat", "Mono.Nat\Mono.Nat.xproj", "{0A82260B-4C22-4FD2-869A-E510044E3502}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Photos", "Emby.Photos\Emby.Photos.csproj", "{89AB4548-770D-41FD-A891-8DAFF44F452C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Api", "MediaBrowser.Api\MediaBrowser.Api.csproj", "{4FD51AC5-2C16-4308-A993-C3A84F3B4582}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.MediaEncoding", "MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj", "{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Server.Implementations", "Emby.Server.Implementations\Emby.Server.Implementations.csproj", "{D08B8079-08B3-48F2-83C4-E9CCCE48AFF1}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RSSDP", "RSSDP\RSSDP.csproj", "{21002819-C39A-4D3E-BE83-2A276A77FB1F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Dlna", "Emby.Dlna\Emby.Dlna.csproj", "{805844AB-E92F-45E6-9D99-4F6D48D129A5}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Implementations", "MediaBrowser.Server.Implementations\MediaBrowser.Server.Implementations.csproj", "{2E781478-814D-4A48-9D80-BFF206441A65}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Mono.Nat", "Mono.Nat\Mono.Nat.xproj", "{4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Server.Implementations", "Emby.Server.Implementations\Emby.Server.Implementations.csproj", "{E383961B-9356-4D5D-8233-9A1079D03055}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Emby.Server.Core", "Emby.Server.Core\Emby.Server.Core.xproj", "{65AA7D67-8059-40CD-91F1-16D02687226C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack", "ServiceStack\ServiceStack.csproj", "{680A1709-25EB-4D52-A87F-EE03FFD94BAA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SocketHttpListener.Portable", "SocketHttpListener.Portable\SocketHttpListener.Portable.csproj", "{4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release Mono|Any CPU = Release Mono|Any CPU
Release|Any CPU = Release|Any CPU
+ Signed|Any CPU = Signed|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DDAFF431-0B3D-4857-8762-990A32DC8472}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -61,114 +72,192 @@ Global
{DDAFF431-0B3D-4857-8762-990A32DC8472}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{DDAFF431-0B3D-4857-8762-990A32DC8472}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDAFF431-0B3D-4857-8762-990A32DC8472}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DDAFF431-0B3D-4857-8762-990A32DC8472}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {DDAFF431-0B3D-4857-8762-990A32DC8472}.Signed|Any CPU.Build.0 = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|Any CPU.Build.0 = Release|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|Any CPU.Build.0 = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|Any CPU.Build.0 = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|Any CPU.Build.0 = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|Any CPU.Build.0 = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|Any CPU.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|Any CPU.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|Any CPU.Build.0 = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|Any CPU.Build.0 = Release|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|Any CPU.Build.0 = Release|Any CPU
{5A27010A-09C6-4E86-93EA-437484C10917}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A27010A-09C6-4E86-93EA-437484C10917}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A27010A-09C6-4E86-93EA-437484C10917}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
{5A27010A-09C6-4E86-93EA-437484C10917}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{5A27010A-09C6-4E86-93EA-437484C10917}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A27010A-09C6-4E86-93EA-437484C10917}.Release|Any CPU.Build.0 = Release|Any CPU
- {0A82260B-4C22-4FD2-869A-E510044E3502}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0A82260B-4C22-4FD2-869A-E510044E3502}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0A82260B-4C22-4FD2-869A-E510044E3502}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
- {0A82260B-4C22-4FD2-869A-E510044E3502}.Release Mono|Any CPU.Build.0 = Release|Any CPU
- {0A82260B-4C22-4FD2-869A-E510044E3502}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0A82260B-4C22-4FD2-869A-E510044E3502}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|Any CPU.Build.0 = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|Any CPU.Build.0 = Release|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|Any CPU.Build.0 = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.Build.0 = Release|Any CPU
- {D08B8079-08B3-48F2-83C4-E9CCCE48AFF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D08B8079-08B3-48F2-83C4-E9CCCE48AFF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D08B8079-08B3-48F2-83C4-E9CCCE48AFF1}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
- {D08B8079-08B3-48F2-83C4-E9CCCE48AFF1}.Release Mono|Any CPU.Build.0 = Release|Any CPU
- {D08B8079-08B3-48F2-83C4-E9CCCE48AFF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D08B8079-08B3-48F2-83C4-E9CCCE48AFF1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|Any CPU.Build.0 = Release|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|Any CPU.Build.0 = Release|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|Any CPU.Build.0 = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|Any CPU.ActiveCfg = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|Any CPU.Build.0 = Signed|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -186,12 +275,17 @@ Global
{442B5058-DCAF-4263-BB6A-F21E31120A1B} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
{4A4402D4-E910-443B-B8FC-2C18286A2CA0} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
{5A27010A-09C6-4E86-93EA-437484C10917} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
- {0A82260B-4C22-4FD2-869A-E510044E3502} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
{89AB4548-770D-41FD-A891-8DAFF44F452C} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
{4FD51AC5-2C16-4308-A993-C3A84F3B4582} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
- {D08B8079-08B3-48F2-83C4-E9CCCE48AFF1} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
{21002819-C39A-4D3E-BE83-2A276A77FB1F} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
{805844AB-E92F-45E6-9D99-4F6D48D129A5} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
+ {2E781478-814D-4A48-9D80-BFF206441A65} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
+ {E383961B-9356-4D5D-8233-9A1079D03055} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
+ {65AA7D67-8059-40CD-91F1-16D02687226C} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
EndGlobalSection
EndGlobal
diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs
index 779db0a828..5ac701f820 100644
--- a/MediaBrowser.Common/Net/INetworkManager.cs
+++ b/MediaBrowser.Common/Net/INetworkManager.cs
@@ -54,12 +54,5 @@ namespace MediaBrowser.Common.Net
bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo);
Task<IpAddressInfo[]> GetHostAddressesAsync(string host);
-
- /// <summary>
- /// Generates a self signed certificate at the locatation specified by <paramref name="certificatePath"/>.
- /// </summary>
- /// <param name="certificatePath">The path to generate the certificate.</param>
- /// <param name="hostname">The common name for the certificate.</param>
- void GenerateSelfSignedSslCertificate(string certificatePath, string hostname);
}
} \ No newline at end of file
diff --git a/Emby.Drawing/IImageEncoder.cs b/MediaBrowser.Controller/Drawing/IImageEncoder.cs
index 73b5398993..de1909e542 100644
--- a/Emby.Drawing/IImageEncoder.cs
+++ b/MediaBrowser.Controller/Drawing/IImageEncoder.cs
@@ -1,8 +1,7 @@
-using MediaBrowser.Controller.Drawing;
+using System;
using MediaBrowser.Model.Drawing;
-using System;
-namespace Emby.Drawing
+namespace MediaBrowser.Controller.Drawing
{
public interface IImageEncoder : IDisposable
{
diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs
index d2cf23f43f..44c0031974 100644
--- a/MediaBrowser.Controller/IServerApplicationHost.cs
+++ b/MediaBrowser.Controller/IServerApplicationHost.cs
@@ -26,12 +26,6 @@ namespace MediaBrowser.Controller
/// </summary>
/// <value><c>true</c> if [supports automatic run at startup]; otherwise, <c>false</c>.</value>
bool SupportsAutoRunAtStartup { get; }
-
- /// <summary>
- /// Gets a value indicating whether [supports library monitor].
- /// </summary>
- /// <value><c>true</c> if [supports library monitor]; otherwise, <c>false</c>.</value>
- bool SupportsLibraryMonitor { get; }
/// <summary>
/// Gets the HTTP server port.
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 518daa6d75..2f96088ab9 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -88,6 +88,7 @@
<Compile Include="Dlna\IEventManager.cs" />
<Compile Include="Dlna\IMediaReceiverRegistrar.cs" />
<Compile Include="Dlna\IUpnpService.cs" />
+ <Compile Include="Drawing\IImageEncoder.cs" />
<Compile Include="Drawing\IImageProcessor.cs" />
<Compile Include="Drawing\ImageCollageOptions.cs" />
<Compile Include="Drawing\ImageProcessingOptions.cs" />
diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs
index 8c503c199b..f319244dae 100644
--- a/MediaBrowser.Controller/Net/IHttpServer.cs
+++ b/MediaBrowser.Controller/Net/IHttpServer.cs
@@ -16,18 +16,10 @@ namespace MediaBrowser.Controller.Net
IEnumerable<string> UrlPrefixes { get; }
/// <summary>
- /// Gets the certificate path.
- /// </summary>
- /// <value>The certificate path.</value>
- string CertificatePath { get; }
-
- /// <summary>
/// Starts the specified server name.
/// </summary>
/// <param name="urlPrefixes">The URL prefixes.</param>
- /// <param name="certificatePath">If an https prefix is specified,
- /// the ssl certificate localtion on the file system.</param>
- void StartServer(IEnumerable<string> urlPrefixes, string certificatePath);
+ void StartServer(IEnumerable<string> urlPrefixes);
/// <summary>
/// Stops this instance.
diff --git a/MediaBrowser.Controller/Net/IServerManager.cs b/MediaBrowser.Controller/Net/IServerManager.cs
index 5191a62e31..202df29824 100644
--- a/MediaBrowser.Controller/Net/IServerManager.cs
+++ b/MediaBrowser.Controller/Net/IServerManager.cs
@@ -15,9 +15,7 @@ namespace MediaBrowser.Controller.Net
/// Starts this instance.
/// </summary>
/// <param name="urlPrefixes">The URL prefixes.</param>
- /// <param name="certificatePath">If an https prefix is specified,
- /// the ssl certificate localtion on the file system.</param>
- void Start(IEnumerable<string> urlPrefixes, string certificatePath);
+ void Start(IEnumerable<string> urlPrefixes);
/// <summary>
/// Sends a message to all clients currently connected via a web socket
diff --git a/MediaBrowser.LocalMetadata/Providers/PersonXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/PersonXmlProvider.cs
index 72cd1c4c8e..f430df2971 100644
--- a/MediaBrowser.LocalMetadata/Providers/PersonXmlProvider.cs
+++ b/MediaBrowser.LocalMetadata/Providers/PersonXmlProvider.cs
@@ -11,28 +11,28 @@ using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Providers
{
- public class PersonXmlProvider : BaseXmlProvider<Person>
- {
- private readonly ILogger _logger;
- private readonly IProviderManager _providerManager;
- protected IXmlReaderSettingsFactory XmlReaderSettingsFactory { get; private set; }
+ //public class PersonXmlProvider : BaseXmlProvider<Person>
+ //{
+ // private readonly ILogger _logger;
+ // private readonly IProviderManager _providerManager;
+ // protected IXmlReaderSettingsFactory XmlReaderSettingsFactory { get; private set; }
- public PersonXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
- : base(fileSystem)
- {
- _logger = logger;
- _providerManager = providerManager;
- XmlReaderSettingsFactory = xmlReaderSettingsFactory;
- }
+ // public PersonXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
+ // : base(fileSystem)
+ // {
+ // _logger = logger;
+ // _providerManager = providerManager;
+ // XmlReaderSettingsFactory = xmlReaderSettingsFactory;
+ // }
- protected override void Fetch(MetadataResult<Person> result, string path, CancellationToken cancellationToken)
- {
- new BaseItemXmlParser<Person>(_logger, _providerManager, XmlReaderSettingsFactory, FileSystem).Fetch(result, path, cancellationToken);
- }
+ // protected override void Fetch(MetadataResult<Person> result, string path, CancellationToken cancellationToken)
+ // {
+ // new BaseItemXmlParser<Person>(_logger, _providerManager, XmlReaderSettingsFactory, FileSystem).Fetch(result, path, cancellationToken);
+ // }
- protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService)
- {
- return directoryService.GetFile(Path.Combine(info.Path, "person.xml"));
- }
- }
+ // protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService)
+ // {
+ // return directoryService.GetFile(Path.Combine(info.Path, "person.xml"));
+ // }
+ //}
}
diff --git a/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs
index 84b766a6ac..8409e483d0 100644
--- a/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs
@@ -10,48 +10,48 @@ using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Savers
{
- /// <summary>
- /// Class PersonXmlSaver
- /// </summary>
- public class PersonXmlSaver : BaseXmlSaver
- {
- public override bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
- {
- if (!item.SupportsLocalMetadata)
- {
- return false;
- }
-
- return item is Person && updateType >= ItemUpdateType.MetadataDownload;
- }
-
- protected override List<string> GetTagsUsed()
- {
- var list = new List<string>
- {
- "PlaceOfBirth"
- };
-
- return list;
- }
-
- protected override void WriteCustomElements(IHasMetadata item, XmlWriter writer)
- {
- var person = (Person)item;
-
- if (person.ProductionLocations.Count > 0)
- {
- writer.WriteElementString("PlaceOfBirth", person.ProductionLocations[0]);
- }
- }
-
- protected override string GetLocalSavePath(IHasMetadata item)
- {
- return Path.Combine(item.Path, "person.xml");
- }
-
- public PersonXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory) : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger, xmlReaderSettingsFactory)
- {
- }
- }
+ ///// <summary>
+ ///// Class PersonXmlSaver
+ ///// </summary>
+ //public class PersonXmlSaver : BaseXmlSaver
+ //{
+ // public override bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
+ // {
+ // if (!item.SupportsLocalMetadata)
+ // {
+ // return false;
+ // }
+
+ // return item is Person && updateType >= ItemUpdateType.MetadataDownload;
+ // }
+
+ // protected override List<string> GetTagsUsed()
+ // {
+ // var list = new List<string>
+ // {
+ // "PlaceOfBirth"
+ // };
+
+ // return list;
+ // }
+
+ // protected override void WriteCustomElements(IHasMetadata item, XmlWriter writer)
+ // {
+ // var person = (Person)item;
+
+ // if (person.ProductionLocations.Count > 0)
+ // {
+ // writer.WriteElementString("PlaceOfBirth", person.ProductionLocations[0]);
+ // }
+ // }
+
+ // protected override string GetLocalSavePath(IHasMetadata item)
+ // {
+ // return Path.Combine(item.Path, "person.xml");
+ // }
+
+ // public PersonXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory) : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger, xmlReaderSettingsFactory)
+ // {
+ // }
+ //}
}
diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs
index d2bb355203..f219d92959 100644
--- a/MediaBrowser.Model/IO/IFileSystem.cs
+++ b/MediaBrowser.Model/IO/IFileSystem.cs
@@ -312,6 +312,8 @@ namespace MediaBrowser.Model.IO
string GetFullPath(string path);
List<FileSystemMetadata> GetDrives();
+
+ void SetExecutable(string path);
}
public enum FileOpenMode
diff --git a/MediaBrowser.Model/Services/IRequest.cs b/MediaBrowser.Model/Services/IRequest.cs
index 5dc995b06f..5a4d240074 100644
--- a/MediaBrowser.Model/Services/IRequest.cs
+++ b/MediaBrowser.Model/Services/IRequest.cs
@@ -120,11 +120,6 @@ namespace MediaBrowser.Model.Services
public interface IResponse
{
- /// <summary>
- /// The underlying ASP.NET or HttpListener HttpResponse
- /// </summary>
- object OriginalResponse { get; }
-
IRequest Request { get; }
int StatusCode { get; set; }
diff --git a/MediaBrowser.Model/System/Architecture.cs b/MediaBrowser.Model/System/Architecture.cs
index 09eedddc13..73f78cd582 100644
--- a/MediaBrowser.Model/System/Architecture.cs
+++ b/MediaBrowser.Model/System/Architecture.cs
@@ -4,6 +4,7 @@
{
X86 = 0,
X64 = 1,
- Arm = 2
+ Arm = 2,
+ Arm64 = 3
}
}
diff --git a/MediaBrowser.Model/System/IEnvironmentInfo.cs b/MediaBrowser.Model/System/IEnvironmentInfo.cs
index 3fcacb30d4..c5f493e7c9 100644
--- a/MediaBrowser.Model/System/IEnvironmentInfo.cs
+++ b/MediaBrowser.Model/System/IEnvironmentInfo.cs
@@ -11,6 +11,7 @@ namespace MediaBrowser.Model.System
MediaBrowser.Model.System.OperatingSystem OperatingSystem { get; }
string OperatingSystemName { get; }
string OperatingSystemVersion { get; }
+ Architecture SystemArchitecture { get; }
}
public enum OperatingSystem
diff --git a/MediaBrowser.Mono.sln b/MediaBrowser.Mono.sln
index 5be6b22f40..35c3962002 100644
--- a/MediaBrowser.Mono.sln
+++ b/MediaBrowser.Mono.sln
@@ -43,6 +43,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RSSDP", "RSSDP\RSSDP.csproj
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Dlna", "Emby.Dlna\Emby.Dlna.csproj", "{805844AB-E92F-45E6-9D99-4F6D48D129A5}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing.ImageMagick", "Emby.Drawing.ImageMagick\Emby.Drawing.ImageMagick.csproj", "{6CFEE013-6E7C-432B-AC37-CABF0880C69A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing.Net", "Emby.Drawing.Net\Emby.Drawing.Net.csproj", "{C97A239E-A96C-4D64-A844-CCF8CC30AECB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack", "ServiceStack\ServiceStack.csproj", "{680A1709-25EB-4D52-A87F-EE03FFD94BAA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SocketHttpListener.Portable", "SocketHttpListener.Portable\SocketHttpListener.Portable.csproj", "{4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -51,6 +59,8 @@ Global
Release Mono|x86 = Release Mono|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
+ Signed|Any CPU = Signed|Any CPU
+ Signed|x86 = Signed|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -64,6 +74,10 @@ Global
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.Build.0 = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x86.ActiveCfg = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x86.Build.0 = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|x86.ActiveCfg = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|x86.Build.0 = Release|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|x86.ActiveCfg = Debug|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|x86.Build.0 = Debug|Any CPU
@@ -74,6 +88,10 @@ Global
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.Build.0 = Release|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.ActiveCfg = Release|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.Build.0 = Release|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|x86.ActiveCfg = Release|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|x86.Build.0 = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|x86.ActiveCfg = Debug|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|x86.Build.0 = Debug|Any CPU
@@ -84,6 +102,10 @@ Global
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.Build.0 = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.ActiveCfg = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.Build.0 = Release|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|x86.ActiveCfg = Release|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|x86.Build.0 = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|x86.ActiveCfg = Debug|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|x86.Build.0 = Debug|Any CPU
@@ -94,6 +116,10 @@ Global
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.Build.0 = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|x86.ActiveCfg = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|x86.Build.0 = Release|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|x86.ActiveCfg = Release|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|x86.Build.0 = Release|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Debug|x86.ActiveCfg = Debug|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Debug|x86.Build.0 = Debug|Any CPU
@@ -104,6 +130,10 @@ Global
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|Any CPU.Build.0 = Release|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|x86.ActiveCfg = Release|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|x86.Build.0 = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|x86.ActiveCfg = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|x86.Build.0 = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|x86.ActiveCfg = Debug|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|x86.Build.0 = Debug|Any CPU
@@ -114,6 +144,10 @@ Global
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.Build.0 = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.ActiveCfg = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.Build.0 = Release|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|x86.ActiveCfg = Release|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|x86.Build.0 = Release|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|x86.ActiveCfg = Debug|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|x86.Build.0 = Debug|Any CPU
@@ -124,6 +158,10 @@ Global
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.Build.0 = Release|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|x86.ActiveCfg = Release|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|x86.Build.0 = Release|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|x86.ActiveCfg = Release|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|x86.Build.0 = Release|Any CPU
{175A9388-F352-4586-A6B4-070DED62B644}.Debug|Any CPU.ActiveCfg = Debug|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Debug|x86.ActiveCfg = Debug|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Debug|x86.Build.0 = Debug|x86
@@ -134,6 +172,10 @@ Global
{175A9388-F352-4586-A6B4-070DED62B644}.Release|Any CPU.Build.0 = Release|Any CPU
{175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.ActiveCfg = Release|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.Build.0 = Release|x86
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|Any CPU.ActiveCfg = Debug|Any CPU
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|Any CPU.Build.0 = Debug|Any CPU
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|x86.ActiveCfg = Release Mono|x86
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|x86.Build.0 = Release Mono|x86
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|x86.ActiveCfg = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|x86.Build.0 = Debug|Any CPU
@@ -144,6 +186,10 @@ Global
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.Build.0 = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x86.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x86.Build.0 = Release|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|x86.ActiveCfg = Release|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|x86.Build.0 = Release|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|x86.ActiveCfg = Debug|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|x86.Build.0 = Debug|Any CPU
@@ -154,6 +200,10 @@ Global
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.Build.0 = Release|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|x86.ActiveCfg = Release|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|x86.Build.0 = Release|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|x86.ActiveCfg = Release|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|x86.Build.0 = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|x86.ActiveCfg = Debug|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|x86.Build.0 = Debug|Any CPU
@@ -164,6 +214,10 @@ Global
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Any CPU.Build.0 = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|x86.ActiveCfg = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|x86.Build.0 = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|x86.ActiveCfg = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|x86.Build.0 = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Debug|x86.ActiveCfg = Debug|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Debug|x86.Build.0 = Debug|Any CPU
@@ -174,6 +228,10 @@ Global
{23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.Build.0 = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release|x86.ActiveCfg = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release|x86.Build.0 = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|x86.ActiveCfg = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|x86.Build.0 = Release|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -183,6 +241,10 @@ Global
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release|Any CPU.Build.0 = Release|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release|x86.ActiveCfg = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|x86.ActiveCfg = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|x86.Build.0 = Release|Any CPU
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -192,6 +254,10 @@ Global
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|Any CPU.Build.0 = Release|Any CPU
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|x86.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|x86.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|x86.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -204,6 +270,10 @@ Global
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Any CPU.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|x86.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|x86.Build.0 = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|x86.ActiveCfg = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|x86.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -216,6 +286,10 @@ Global
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Any CPU.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|x86.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|x86.Build.0 = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|x86.ActiveCfg = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|x86.Build.0 = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -228,6 +302,10 @@ Global
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|Any CPU.Build.0 = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|x86.ActiveCfg = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|x86.Build.0 = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|x86.ActiveCfg = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|x86.Build.0 = Release|Any CPU
{E383961B-9356-4D5D-8233-9A1079D03055}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E383961B-9356-4D5D-8233-9A1079D03055}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E383961B-9356-4D5D-8233-9A1079D03055}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -240,6 +318,10 @@ Global
{E383961B-9356-4D5D-8233-9A1079D03055}.Release|Any CPU.Build.0 = Release|Any CPU
{E383961B-9356-4D5D-8233-9A1079D03055}.Release|x86.ActiveCfg = Release|Any CPU
{E383961B-9356-4D5D-8233-9A1079D03055}.Release|x86.Build.0 = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|x86.ActiveCfg = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|x86.Build.0 = Release|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -252,6 +334,10 @@ Global
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|Any CPU.Build.0 = Release|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|x86.ActiveCfg = Release|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|x86.Build.0 = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|x86.ActiveCfg = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|x86.Build.0 = Release|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -264,6 +350,74 @@ Global
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|Any CPU.Build.0 = Release|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|x86.ActiveCfg = Release|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|x86.Build.0 = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|x86.ActiveCfg = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|x86.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|x86.Build.0 = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|x86.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|x86.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|x86.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|x86.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|x86.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|x86.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|x86.Build.0 = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|x86.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|x86.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|x86.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|x86.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|x86.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|x86.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|x86.Build.0 = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|x86.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|x86.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|x86.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|x86.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|Any CPU.ActiveCfg = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|Any CPU.Build.0 = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|x86.ActiveCfg = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|x86.Build.0 = Signed|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|x86.Build.0 = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|x86.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|x86.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|x86.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|x86.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|x86.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs b/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs
index 19a0593e3b..979a929ca7 100644
--- a/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs
+++ b/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs
@@ -3,13 +3,13 @@ using MediaBrowser.Controller.Entities;
using System;
using System.IO;
using System.Linq;
-using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Server.Implementations.Devices
{
@@ -64,29 +64,4 @@ namespace MediaBrowser.Server.Implementations.Devices
get { return true; }
}
}
-
- public class CameraUploadsDynamicFolder : IVirtualFolderCreator
- {
- private readonly IApplicationPaths _appPaths;
- private readonly IFileSystem _fileSystem;
-
- public CameraUploadsDynamicFolder(IApplicationPaths appPaths, IFileSystem fileSystem)
- {
- _appPaths = appPaths;
- _fileSystem = fileSystem;
- }
-
- public BasePluginFolder GetFolder()
- {
- var path = Path.Combine(_appPaths.DataPath, "camerauploads");
-
- _fileSystem.CreateDirectory(path);
-
- return new CameraUploadsFolder
- {
- Path = path
- };
- }
- }
-
}
diff --git a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs
deleted file mode 100644
index abcf84abda..0000000000
--- a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Cryptography;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Net;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Text;
-
-namespace MediaBrowser.Server.Implementations.HttpServer
-{
- /// <summary>
- /// Class ServerFactory
- /// </summary>
- public static class ServerFactory
- {
- /// <summary>
- /// Creates the server.
- /// </summary>
- /// <returns>IHttpServer.</returns>
- public static IHttpServer CreateServer(IServerApplicationHost applicationHost,
- ILogManager logManager,
- IServerConfigurationManager config,
- INetworkManager networkmanager,
- IMemoryStreamFactory streamProvider,
- string serverName,
- string defaultRedirectpath,
- ITextEncoding textEncoding,
- ISocketFactory socketFactory,
- ICryptoProvider cryptoProvider,
- IJsonSerializer json,
- IXmlSerializer xml)
- {
- return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, networkmanager, streamProvider, textEncoding, socketFactory, cryptoProvider, json, xml);
- }
- }
-}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index a2edc7aa84..3bfbff6e67 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -11,10 +11,9 @@
<AssemblyName>MediaBrowser.Server.Implementations</AssemblyName>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
- <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
- <ReleaseVersion>
- </ReleaseVersion>
- <TargetFrameworkProfile />
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -42,125 +41,14 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Emby.Common.Implementations">
- <HintPath>..\ThirdParty\emby\Emby.Common.Implementations.dll</HintPath>
- </Reference>
- <Reference Include="Emby.XmlTv, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\Emby.XmlTv.1.0.0.63\lib\portable-net45+win8\Emby.XmlTv.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="INIFileParser, Version=2.3.0.0, Culture=neutral, PublicKeyToken=79af7b307b65cf3c, processorArchitecture=MSIL">
- <HintPath>..\packages\ini-parser.2.3.0\lib\net20\INIFileParser.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="MediaBrowser.Naming, Version=1.0.6151.30291, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\MediaBrowser.Naming.1.0.0.59\lib\portable-net45+win8\MediaBrowser.Naming.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.IO.RecyclableMemoryStream, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
- <HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.1.0.0\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Mono.Nat, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\ThirdParty\emby\Mono.Nat.dll</HintPath>
- </Reference>
- <Reference Include="Patterns.Logging, Version=1.0.6151.30227, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\Patterns.Logging.1.0.0.6\lib\portable-net45+win8\Patterns.Logging.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="SharpCompress, Version=0.10.3.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\ThirdParty\SharpCompress\SharpCompress.dll</HintPath>
- </Reference>
- <Reference Include="SocketHttpListener.Portable">
- <HintPath>..\ThirdParty\emby\SocketHttpListener.Portable.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.IO.Compression" />
- <Reference Include="System.Net" />
- <Reference Include="System.Runtime.Serialization" />
- <Reference Include="System.Security" />
- <Reference Include="System.Xml" />
- <Reference Include="ServiceStack">
- <HintPath>..\ThirdParty\ServiceStack\ServiceStack.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.Text">
- <HintPath>..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll</HintPath>
- </Reference>
- <Reference Include="System.Xml.Linq" />
- <Reference Include="UniversalDetector, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\UniversalDetector.1.0.1\lib\portable-net45+sl4+wp71+win8+wpa81\UniversalDetector.dll</HintPath>
- <Private>True</Private>
- </Reference>
- </ItemGroup>
- <ItemGroup>
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
- <Compile Include="Activity\ActivityRepository.cs" />
- <Compile Include="Archiving\ZipClient.cs" />
- <Compile Include="Collections\CollectionsDynamicFolder.cs" />
- <Compile Include="Configuration\ServerConfigurationManager.cs" />
- <Compile Include="Devices\DeviceRepository.cs" />
<Compile Include="Devices\CameraUploadsFolder.cs" />
- <Compile Include="EntryPoints\ExternalPortForwarding.cs" />
- <Compile Include="HttpServer\HttpListenerHost.cs" />
- <Compile Include="HttpServer\HttpResultFactory.cs" />
- <Compile Include="HttpServer\ServerFactory.cs" />
- <Compile Include="HttpServer\SocketSharp\RequestMono.cs" />
- <Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" />
- <Compile Include="IO\LibraryMonitor.cs" />
- <Compile Include="IO\MemoryStreamProvider.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\ChannelScan.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\ReportBlock.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpAppPacket.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpByePacket.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpListener.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpPacket.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpReceiverReportPacket.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpSenderReportPacket.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpSourceDescriptionPacket.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\SourceDescriptionBlock.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\SourceDescriptionItem.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtp\RtpListener.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtp\RtpPacket.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspMethod.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspRequest.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspResponse.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspSession.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspStatusCode.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\SatIpDiscovery.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\SatIpHost.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\TransmissionMode.cs" />
- <Compile Include="LiveTv\TunerHosts\SatIp\Utils.cs" />
- <Compile Include="Persistence\BaseSqliteRepository.cs" />
- <Compile Include="Persistence\DataExtensions.cs" />
- <Compile Include="Persistence\IDbConnector.cs" />
- <Compile Include="Persistence\MediaStreamColumns.cs" />
- <Compile Include="Serialization\JsonSerializer.cs" />
- <Compile Include="Social\SharingRepository.cs" />
- <Compile Include="Persistence\SqliteFileOrganizationRepository.cs" />
- <Compile Include="Notifications\SqliteNotificationsRepository.cs" />
- <Compile Include="Persistence\TypeMapper.cs" />
<Compile Include="Playlists\ManualPlaylistsFolder.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Security\AuthenticationRepository.cs" />
- <Compile Include="ServerApplicationPaths.cs" />
- <Compile Include="Persistence\SqliteDisplayPreferencesRepository.cs" />
- <Compile Include="Persistence\SqliteItemRepository.cs" />
- <Compile Include="Persistence\SqliteUserDataRepository.cs" />
- <Compile Include="Persistence\SqliteUserRepository.cs" />
- <Compile Include="Sync\SyncRepository.cs" />
</ItemGroup>
<ItemGroup>
- <ProjectReference Include="..\Emby.Server.Implementations\Emby.Server.Implementations.csproj">
- <Project>{e383961b-9356-4d5d-8233-9a1079d03055}</Project>
- <Name>Emby.Server.Implementations</Name>
- </ProjectReference>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142EEFA-7570-41E1-BFCC-468BB571AF2F}</Project>
<Name>MediaBrowser.Common</Name>
@@ -173,186 +61,12 @@
<Project>{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}</Project>
<Name>MediaBrowser.Model</Name>
</ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Providers\MediaBrowser.Providers.csproj">
- <Project>{442b5058-dcaf-4263-bb6a-f21e31120a1b}</Project>
- <Name>MediaBrowser.Providers</Name>
- </ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0030.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0049.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0070.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0090.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0100.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0130.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0160.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0170.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0192.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0200.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0215.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0235.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0255.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0260.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0282.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0305.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0308.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0310.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0315.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0330.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0360.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0380.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0390.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0400.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0420.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0435.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0450.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0460.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0475.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0480.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0490.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0505.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0510.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0520.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0525.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0530.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0549.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0560.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0570.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0600.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0620.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0642.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0650.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0660.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0685.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0705.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0721.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0740.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0750.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0765.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0785.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0830.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0851.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0865.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0875.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0880.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0900.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0915.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0922.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0935.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0950.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0965.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1005.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1030.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1055.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1082.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1100.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1105.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1130.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1155.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1160.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1180.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1195.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1222.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1240.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1250.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1280.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1320.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1340.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1380.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1400.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1440.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1500.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1520.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1540.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1560.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1590.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1600 OPTUS D1 FTA %28160.0E%29.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1600.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1620.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1640.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1660.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1690.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1720.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1800.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1830.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2210.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2230.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2250.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2270.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2290.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2310.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2330.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2350.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2370.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2390.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2410.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2432.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2451.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2470.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2489.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2500.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2527.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2550.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2570.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2590.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2608.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2630.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2650.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2669.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2690.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2710.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2728.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2730.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2750.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2760.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2770.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2780.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2812.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2820.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2830.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2850.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2873.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2880.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2881.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2882.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2900.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2930.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2950.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2970.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2985.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2990.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3020.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3045.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3070.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3100.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3125.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3150.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3169.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3195.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3225.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3255.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3285.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3300.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3325.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3355.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3380.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3400.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3420.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3450.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3460.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3475.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3490.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3520.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3527.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3550.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3560.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3592.ini" />
- <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3594.ini" />
- <None Include="packages.config" />
</ItemGroup>
<ItemGroup />
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
diff --git a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
index eff77574d3..07773d846b 100644
--- a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
+++ b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
@@ -1,14 +1,13 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Playlists;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Playlists;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Querying;
-using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Server.Implementations.Playlists
{
@@ -29,6 +28,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
return base.GetEligibleChildrenForRecursiveChildren(user).OfType<Playlist>();
}
+ [IgnoreDataMember]
public override bool IsHidden
{
get
@@ -37,9 +37,10 @@ namespace MediaBrowser.Server.Implementations.Playlists
}
}
+ [IgnoreDataMember]
public override string CollectionType
{
- get { return Model.Entities.CollectionType.Playlists; }
+ get { return MediaBrowser.Model.Entities.CollectionType.Playlists; }
}
protected override Task<QueryResult<BaseItem>> GetItemsInternal(InternalItemsQuery query)
@@ -48,29 +49,5 @@ namespace MediaBrowser.Server.Implementations.Playlists
return base.GetItemsInternal(query);
}
}
-
- public class PlaylistsDynamicFolder : IVirtualFolderCreator
- {
- private readonly IApplicationPaths _appPaths;
- private readonly IFileSystem _fileSystem;
-
- public PlaylistsDynamicFolder(IApplicationPaths appPaths, IFileSystem fileSystem)
- {
- _appPaths = appPaths;
- _fileSystem = fileSystem;
- }
-
- public BasePluginFolder GetFolder()
- {
- var path = Path.Combine(_appPaths.DataPath, "playlists");
-
- _fileSystem.CreateDirectory(path);
-
- return new PlaylistsFolder
- {
- Path = path
- };
- }
- }
}
diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config
deleted file mode 100644
index 84a5d5a1d8..0000000000
--- a/MediaBrowser.Server.Implementations/packages.config
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="Emby.XmlTv" version="1.0.0.63" targetFramework="net46" />
- <package id="ini-parser" version="2.3.0" targetFramework="net45" />
- <package id="MediaBrowser.Naming" version="1.0.0.59" targetFramework="net46" />
- <package id="Microsoft.IO.RecyclableMemoryStream" version="1.1.0.0" targetFramework="net46" />
- <package id="Patterns.Logging" version="1.0.0.6" targetFramework="net46" />
- <package id="UniversalDetector" version="1.0.1" targetFramework="net46" />
-</packages> \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/project.json b/MediaBrowser.Server.Implementations/project.json
new file mode 100644
index 0000000000..fbbe9eaf32
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/project.json
@@ -0,0 +1,17 @@
+{
+ "frameworks":{
+ "netstandard1.6":{
+ "dependencies":{
+ "NETStandard.Library":"1.6.0",
+ }
+ },
+ ".NETPortable,Version=v4.5,Profile=Profile7":{
+ "buildOptions": {
+ "define": [ ]
+ },
+ "frameworkAssemblies":{
+
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
index c7de9a62b6..090e8ea9a1 100644
--- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
+++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
@@ -61,6 +61,9 @@
<Reference Include="Emby.Common.Implementations">
<HintPath>..\ThirdParty\emby\Emby.Common.Implementations.dll</HintPath>
</Reference>
+ <Reference Include="Emby.Server.Core">
+ <HintPath>..\ThirdParty\emby\Emby.Server.Core.dll</HintPath>
+ </Reference>
<Reference Include="Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Mono.Posix.4.0.0.0\lib\net40\Mono.Posix.dll</HintPath>
@@ -69,14 +72,19 @@
<HintPath>..\packages\NLog.4.4.0-betaV15\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="Patterns.Logging, Version=1.0.6151.30227, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\Patterns.Logging.1.0.0.6\lib\portable-net45+win8\Patterns.Logging.dll</HintPath>
+ <Reference Include="ServiceStack.Text, Version=4.5.4.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\ServiceStack.Text.4.5.4\lib\net45\ServiceStack.Text.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="System" />
- <Reference Include="ServiceStack.Interfaces">
- <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll</HintPath>
+ <Reference Include="SharpCompress, Version=0.14.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll</HintPath>
+ <Private>True</Private>
</Reference>
+ <Reference Include="SimpleInjector, Version=3.2.4.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
+ <HintPath>..\packages\SimpleInjector.3.2.4\lib\net45\SimpleInjector.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System" />
<Reference Include="MediaBrowser.IsoMounting.Linux">
<HintPath>..\ThirdParty\MediaBrowser.IsoMounting.Linux\MediaBrowser.IsoMounting.Linux.dll</HintPath>
</Reference>
@@ -92,7 +100,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
- <Compile Include="..\MediaBrowser.Server.Implementations\Persistence\SqliteExtensions.cs">
+ <Compile Include="..\MediaBrowser.Server.Startup.Common\Persistence\SqliteExtensions.cs">
<Link>Native\SqliteExtensions.cs</Link>
</Compile>
<Compile Include="..\SharedVersion.cs">
@@ -100,12 +108,17 @@
</Compile>
<Compile Include="Native\MonoApp.cs" />
<Compile Include="Native\DbConnector.cs" />
+ <Compile Include="Native\MonoFileSystem.cs" />
<Compile Include="Native\PowerManagement.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
+ <ProjectReference Include="..\Emby.Server.Implementations\Emby.Server.Implementations.csproj">
+ <Project>{e383961b-9356-4d5d-8233-9a1079d03055}</Project>
+ <Name>Emby.Server.Implementations</Name>
+ </ProjectReference>
<ProjectReference Include="..\MediaBrowser.Server.Startup.Common\MediaBrowser.Server.Startup.Common.csproj">
<Project>{b90ab8f2-1bff-4568-a3fd-2a338a435a75}</Project>
<Name>MediaBrowser.Server.Startup.Common</Name>
diff --git a/MediaBrowser.Server.Mono/Native/DbConnector.cs b/MediaBrowser.Server.Mono/Native/DbConnector.cs
index 39b53b3709..f25955c91e 100644
--- a/MediaBrowser.Server.Mono/Native/DbConnector.cs
+++ b/MediaBrowser.Server.Mono/Native/DbConnector.cs
@@ -1,7 +1,7 @@
using System.Data;
using System.Threading.Tasks;
+using Emby.Server.Core.Data;
using MediaBrowser.Model.Logging;
-using MediaBrowser.Server.Implementations.Persistence;
namespace MediaBrowser.Server.Mono.Native
{
diff --git a/MediaBrowser.Server.Mono/Native/MonoApp.cs b/MediaBrowser.Server.Mono/Native/MonoApp.cs
index bc4a9978e9..8257a1b8df 100644
--- a/MediaBrowser.Server.Mono/Native/MonoApp.cs
+++ b/MediaBrowser.Server.Mono/Native/MonoApp.cs
@@ -7,11 +7,11 @@ using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
+using Emby.Common.Implementations.Networking;
+using Emby.Server.Core;
+using Emby.Server.Core.Data;
+using Emby.Server.Core.FFMpeg;
using MediaBrowser.Model.System;
-using MediaBrowser.Server.Implementations.Persistence;
-using MediaBrowser.Server.Startup.Common.FFMpeg;
-using MediaBrowser.Server.Startup.Common.Networking;
-using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem;
namespace MediaBrowser.Server.Mono.Native
{
@@ -19,11 +19,13 @@ namespace MediaBrowser.Server.Mono.Native
{
protected StartupOptions StartupOptions { get; private set; }
protected ILogger Logger { get; private set; }
+ private readonly MonoEnvironmentInfo _environment;
- public MonoApp(StartupOptions startupOptions, ILogger logger)
+ public MonoApp(StartupOptions startupOptions, ILogger logger, MonoEnvironmentInfo environment)
{
StartupOptions = startupOptions;
Logger = logger;
+ _environment = environment;
}
/// <summary>
@@ -76,11 +78,6 @@ namespace MediaBrowser.Server.Mono.Native
{
var list = new List<Assembly>();
- if (Environment.OperatingSystem == Startup.Common.OperatingSystem.Linux)
- {
- list.AddRange(GetLinuxAssemblies());
- }
-
list.Add(GetType().Assembly);
return list;
@@ -90,7 +87,7 @@ namespace MediaBrowser.Server.Mono.Native
{
var list = new List<Assembly>();
- list.Add(typeof(LinuxIsoManager).Assembly);
+ //list.Add(typeof(LinuxIsoManager).Assembly);
return list;
}
@@ -99,12 +96,6 @@ namespace MediaBrowser.Server.Mono.Native
{
}
- private NativeEnvironment _nativeEnvironment;
- public NativeEnvironment Environment
- {
- get { return _nativeEnvironment ?? (_nativeEnvironment = GetEnvironmentInfo()); }
- }
-
public bool SupportsRunningAsService
{
get
@@ -121,14 +112,6 @@ namespace MediaBrowser.Server.Mono.Native
}
}
- public bool SupportsLibraryMonitor
- {
- get
- {
- return Environment.OperatingSystem != Startup.Common.OperatingSystem.Osx;
- }
- }
-
public void ConfigureAutoRun(bool autorun)
{
}
@@ -138,98 +121,31 @@ namespace MediaBrowser.Server.Mono.Native
return new NetworkManager(logger);
}
- private NativeEnvironment GetEnvironmentInfo()
+ public FFMpegInstallInfo GetFfmpegInstallInfo()
{
- var info = new NativeEnvironment
- {
- OperatingSystem = Startup.Common.OperatingSystem.Linux
- };
-
- var uname = GetUnixName();
-
- var sysName = uname.sysname ?? string.Empty;
-
- if (string.Equals(sysName, "Darwin", StringComparison.OrdinalIgnoreCase))
- {
- info.OperatingSystem = Startup.Common.OperatingSystem.Osx;
- }
- else if (string.Equals(sysName, "Linux", StringComparison.OrdinalIgnoreCase))
- {
- info.OperatingSystem = Startup.Common.OperatingSystem.Linux;
- }
- else if (string.Equals(sysName, "BSD", StringComparison.OrdinalIgnoreCase))
- {
- info.OperatingSystem = Startup.Common.OperatingSystem.Bsd;
- }
+ var info = new FFMpegInstallInfo();
- var archX86 = new Regex("(i|I)[3-6]86");
+ // Windows builds: http://ffmpeg.zeranoe.com/builds/
+ // Linux builds: http://johnvansickle.com/ffmpeg/
+ // OS X builds: http://ffmpegmac.net/
+ // OS X x64: http://www.evermeet.cx/ffmpeg/
- if (archX86.IsMatch(uname.machine))
- {
- info.SystemArchitecture = Architecture.X86;
- }
- else if (string.Equals(uname.machine, "x86_64", StringComparison.OrdinalIgnoreCase))
- {
- info.SystemArchitecture = Architecture.X64;
- }
- else if (uname.machine.StartsWith("arm", StringComparison.OrdinalIgnoreCase))
- {
- info.SystemArchitecture = Architecture.Arm;
- }
- else if (System.Environment.Is64BitOperatingSystem)
+ if (_environment.IsBsd)
{
- info.SystemArchitecture = Architecture.X64;
+
}
- else
+ else if (_environment.OperatingSystem == Model.System.OperatingSystem.Linux)
{
- info.SystemArchitecture = Architecture.X86;
+ info.ArchiveType = "7z";
+ info.Version = "20160215";
}
- info.OperatingSystemVersionString = string.IsNullOrWhiteSpace(sysName) ?
- System.Environment.OSVersion.VersionString :
- sysName;
+ // No version available - user requirement
+ info.DownloadUrls = new string[] { };
return info;
}
- private Uname _unixName;
-
- private Uname GetUnixName()
- {
- if (_unixName == null)
- {
- var uname = new Uname();
- try
- {
- Utsname utsname;
- var callResult = Syscall.uname(out utsname);
- if (callResult == 0)
- {
- uname.sysname = utsname.sysname ?? string.Empty;
- uname.machine = utsname.machine ?? string.Empty;
- }
-
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error getting unix name", ex);
- }
- _unixName = uname;
- }
- return _unixName;
- }
-
- public class Uname
- {
- public string sysname = string.Empty;
- public string machine = string.Empty;
- }
-
- public FFMpegInstallInfo GetFfmpegInstallInfo()
- {
- return GetInfo(Environment);
- }
-
public void LaunchUrl(string url)
{
throw new NotImplementedException();
@@ -240,33 +156,6 @@ namespace MediaBrowser.Server.Mono.Native
return new DbConnector(Logger);
}
- public static FFMpegInstallInfo GetInfo(NativeEnvironment environment)
- {
- var info = new FFMpegInstallInfo();
-
- // Windows builds: http://ffmpeg.zeranoe.com/builds/
- // Linux builds: http://johnvansickle.com/ffmpeg/
- // OS X builds: http://ffmpegmac.net/
- // OS X x64: http://www.evermeet.cx/ffmpeg/
-
- switch (environment.OperatingSystem)
- {
- case OperatingSystem.Osx:
- case OperatingSystem.Bsd:
- break;
- case OperatingSystem.Linux:
-
- info.ArchiveType = "7z";
- info.Version = "20160215";
- break;
- }
-
- // No version available - user requirement
- info.DownloadUrls = new string[] { };
-
- return info;
- }
-
public void EnableLoopback(string appName)
{
diff --git a/MediaBrowser.Server.Mono/Native/MonoFileSystem.cs b/MediaBrowser.Server.Mono/Native/MonoFileSystem.cs
new file mode 100644
index 0000000000..9639566947
--- /dev/null
+++ b/MediaBrowser.Server.Mono/Native/MonoFileSystem.cs
@@ -0,0 +1,21 @@
+using Emby.Common.Implementations.IO;
+using MediaBrowser.Model.Logging;
+using Mono.Unix.Native;
+
+namespace MediaBrowser.Server.Mono.Native
+{
+ public class MonoFileSystem : ManagedFileSystem
+ {
+ public MonoFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool enableManagedInvalidFileNameChars) : base(logger, supportsAsyncFileStreams, enableManagedInvalidFileNameChars)
+ {
+ }
+
+ public override void SetExecutable(string path)
+ {
+ // Linux: File permission to 666, and user's execute bit
+ Logger.Info("Syscall.chmod {0} FilePermissions.DEFFILEMODE | FilePermissions.S_IRWXU | FilePermissions.S_IXGRP | FilePermissions.S_IXOTH", path);
+
+ Syscall.chmod(path, FilePermissions.DEFFILEMODE | FilePermissions.S_IRWXU | FilePermissions.S_IXGRP | FilePermissions.S_IXOTH);
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs
index 77fa6fd91d..9a8ac7763d 100644
--- a/MediaBrowser.Server.Mono/Program.cs
+++ b/MediaBrowser.Server.Mono/Program.cs
@@ -10,10 +10,21 @@ using System.Linq;
using System.Net;
using System.Net.Security;
using System.Reflection;
-using System.Security.Cryptography.X509Certificates;
+using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using Emby.Common.Implementations.EnvironmentInfo;
using Emby.Common.Implementations.IO;
using Emby.Common.Implementations.Logging;
+using Emby.Common.Implementations.Networking;
+using Emby.Common.Implementations.Security;
+using Emby.Server.Core;
+using Emby.Server.Implementations.IO;
+using MediaBrowser.Model.System;
+using MediaBrowser.Server.Startup.Common.IO;
+using Mono.Unix.Native;
+using NLog;
+using ILogger = MediaBrowser.Model.Logging.ILogger;
+using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate;
namespace MediaBrowser.Server.Mono
{
@@ -75,12 +86,29 @@ namespace MediaBrowser.Server.Mono
// Allow all https requests
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; });
- var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), false, false);
+ var fileSystem = new MonoFileSystem(logManager.GetLogger("FileSystem"), false, false);
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
- var nativeApp = new MonoApp(options, logManager.GetLogger("App"));
+ var environmentInfo = GetEnvironmentInfo();
- _appHost = new ApplicationHost(appPaths, logManager, options, fileSystem, nativeApp, new PowerManagement(), "emby.mono.zip");
+ var nativeApp = new MonoApp(options, logManager.GetLogger("App"), environmentInfo);
+
+ var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths);
+
+ _appHost = new ApplicationHost(appPaths,
+ logManager,
+ options,
+ fileSystem,
+ nativeApp,
+ new PowerManagement(),
+ "emby.mono.zip",
+ environmentInfo,
+ imageEncoder,
+ new Startup.Common.SystemEvents(logManager.GetLogger("SystemEvents")),
+ new MemoryStreamProvider(),
+ new NetworkManager(logManager.GetLogger("NetworkManager")),
+ GenerateCertificate,
+ () => Environment.UserDomainName);
if (options.ContainsOption("-v"))
{
@@ -105,6 +133,92 @@ namespace MediaBrowser.Server.Mono
Task.WaitAll(task);
}
+ private static void GenerateCertificate(string certPath, string certHost)
+ {
+ CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, _logger);
+ }
+
+ private static MonoEnvironmentInfo GetEnvironmentInfo()
+ {
+ var info = new MonoEnvironmentInfo();
+
+ var uname = GetUnixName();
+
+ var sysName = uname.sysname ?? string.Empty;
+
+ if (string.Equals(sysName, "Darwin", StringComparison.OrdinalIgnoreCase))
+ {
+ //info.OperatingSystem = Startup.Common.OperatingSystem.Osx;
+ }
+ else if (string.Equals(sysName, "Linux", StringComparison.OrdinalIgnoreCase))
+ {
+ //info.OperatingSystem = Startup.Common.OperatingSystem.Linux;
+ }
+ else if (string.Equals(sysName, "BSD", StringComparison.OrdinalIgnoreCase))
+ {
+ //info.OperatingSystem = Startup.Common.OperatingSystem.Bsd;
+ info.IsBsd = true;
+ }
+
+ var archX86 = new Regex("(i|I)[3-6]86");
+
+ if (archX86.IsMatch(uname.machine))
+ {
+ info.CustomArchitecture = Architecture.X86;
+ }
+ else if (string.Equals(uname.machine, "x86_64", StringComparison.OrdinalIgnoreCase))
+ {
+ info.CustomArchitecture = Architecture.X64;
+ }
+ else if (uname.machine.StartsWith("arm", StringComparison.OrdinalIgnoreCase))
+ {
+ info.CustomArchitecture = Architecture.Arm;
+ }
+ else if (System.Environment.Is64BitOperatingSystem)
+ {
+ info.CustomArchitecture = Architecture.X64;
+ }
+ else
+ {
+ info.CustomArchitecture = Architecture.X86;
+ }
+
+ return info;
+ }
+
+ private static Uname _unixName;
+
+ private static Uname GetUnixName()
+ {
+ if (_unixName == null)
+ {
+ var uname = new Uname();
+ try
+ {
+ Utsname utsname;
+ var callResult = Syscall.uname(out utsname);
+ if (callResult == 0)
+ {
+ uname.sysname = utsname.sysname ?? string.Empty;
+ uname.machine = utsname.machine ?? string.Empty;
+ }
+
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting unix name", ex);
+ }
+ _unixName = uname;
+ }
+ return _unixName;
+ }
+
+ public class Uname
+ {
+ public string sysname = string.Empty;
+ public string machine = string.Empty;
+ }
+
/// <summary>
/// Handles the SessionEnding event of the SystemEvents control.
/// </summary>
@@ -190,4 +304,9 @@ namespace MediaBrowser.Server.Mono
return true;
}
}
+
+ public class MonoEnvironmentInfo : EnvironmentInfo
+ {
+ public bool IsBsd { get; set; }
+ }
}
diff --git a/MediaBrowser.Server.Mono/packages.config b/MediaBrowser.Server.Mono/packages.config
index 8d1ebc141b..5727f4c185 100644
--- a/MediaBrowser.Server.Mono/packages.config
+++ b/MediaBrowser.Server.Mono/packages.config
@@ -2,5 +2,7 @@
<packages>
<package id="Mono.Posix" version="4.0.0.0" targetFramework="net45" />
<package id="NLog" version="4.4.0-betaV15" targetFramework="net46" />
- <package id="Patterns.Logging" version="1.0.0.6" targetFramework="net46" />
+ <package id="ServiceStack.Text" version="4.5.4" targetFramework="net46" />
+ <package id="SharpCompress" version="0.14.0" targetFramework="net46" />
+ <package id="SimpleInjector" version="3.2.4" targetFramework="net46" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.Server.Startup.Common/Security/ASN1.cs b/MediaBrowser.Server.Startup.Common/Cryptography/ASN1.cs
index a25c270734..a25c270734 100644
--- a/MediaBrowser.Server.Startup.Common/Security/ASN1.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/ASN1.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/ASN1Convert.cs b/MediaBrowser.Server.Startup.Common/Cryptography/ASN1Convert.cs
index 8a2a487c82..8a2a487c82 100644
--- a/MediaBrowser.Server.Startup.Common/Security/ASN1Convert.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/ASN1Convert.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/BitConverterLE.cs b/MediaBrowser.Server.Startup.Common/Cryptography/BitConverterLE.cs
index 240c958a3a..240c958a3a 100644
--- a/MediaBrowser.Server.Startup.Common/Security/BitConverterLE.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/BitConverterLE.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/CertificateGenerator.cs b/MediaBrowser.Server.Startup.Common/Cryptography/CertificateGenerator.cs
index f36b14cae2..9e14b7713d 100644
--- a/MediaBrowser.Server.Startup.Common/Security/CertificateGenerator.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/CertificateGenerator.cs
@@ -5,11 +5,11 @@ using System.Security.Cryptography;
namespace Emby.Common.Implementations.Security
{
- internal class CertificateGenerator
+ public class CertificateGenerator
{
private const string MonoTestRootAgency = "<RSAKeyValue><Modulus>v/4nALBxCE+9JgEC0LnDUvKh6e96PwTpN4Rj+vWnqKT7IAp1iK/JjuqvAg6DQ2vTfv0dTlqffmHH51OyioprcT5nzxcSTsZb/9jcHScG0s3/FRIWnXeLk/fgm7mSYhjUaHNI0m1/NTTktipicjKxo71hGIg9qucCWnDum+Krh/k=</Modulus><Exponent>AQAB</Exponent><P>9jbKxMXEruW2CfZrzhxtull4O8P47+mNsEL+9gf9QsRO1jJ77C+jmzfU6zbzjf8+ViK+q62tCMdC1ZzulwdpXQ==</P><Q>x5+p198l1PkK0Ga2mRh0SIYSykENpY2aLXoyZD/iUpKYAvATm0/wvKNrE4dKJyPCA+y3hfTdgVag+SP9avvDTQ==</Q><DP>ISSjCvXsUfbOGG05eddN1gXxL2pj+jegQRfjpk7RAsnWKvNExzhqd5x+ZuNQyc6QH5wxun54inP4RTUI0P/IaQ==</DP><DQ>R815VQmR3RIbPqzDXzv5j6CSH6fYlcTiQRtkBsUnzhWmkd/y3XmamO+a8zJFjOCCx9CcjpVuGziivBqi65lVPQ==</DQ><InverseQ>iYiu0KwMWI/dyqN3RJYUzuuLj02/oTD1pYpwo2rvNCXU1Q5VscOeu2DpNg1gWqI+1RrRCsEoaTNzXB1xtKNlSw==</InverseQ><D>nIfh1LYF8fjRBgMdAH/zt9UKHWiaCnc+jXzq5tkR8HVSKTVdzitD8bl1JgAfFQD8VjSXiCJqluexy/B5SGrCXQ49c78NIQj0hD+J13Y8/E0fUbW1QYbhj6Ff7oHyhaYe1WOQfkp2t/h+llHOdt1HRf7bt7dUknYp7m8bQKGxoYE=</D></RSAKeyValue>";
- internal static void CreateSelfSignCertificatePfx(
+ public static void CreateSelfSignCertificatePfx(
string fileName,
string hostname,
ILogger logger)
diff --git a/MediaBrowser.Server.Startup.Common/Security/CryptoConvert.cs b/MediaBrowser.Server.Startup.Common/Cryptography/CryptoConvert.cs
index c6e466534b..c6e466534b 100644
--- a/MediaBrowser.Server.Startup.Common/Security/CryptoConvert.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/CryptoConvert.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/PKCS1.cs b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS1.cs
index 85bf9db380..85bf9db380 100644
--- a/MediaBrowser.Server.Startup.Common/Security/PKCS1.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS1.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/PKCS12.cs b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS12.cs
index 2205a71604..2205a71604 100644
--- a/MediaBrowser.Server.Startup.Common/Security/PKCS12.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS12.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/PKCS7.cs b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS7.cs
index 1b1a3295b4..1b1a3295b4 100644
--- a/MediaBrowser.Server.Startup.Common/Security/PKCS7.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS7.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/PKCS8.cs b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS8.cs
index b58ebdaf99..b58ebdaf99 100644
--- a/MediaBrowser.Server.Startup.Common/Security/PKCS8.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS8.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/PfxGenerator.cs b/MediaBrowser.Server.Startup.Common/Cryptography/PfxGenerator.cs
index 3f9b90ac16..3f9b90ac16 100644
--- a/MediaBrowser.Server.Startup.Common/Security/PfxGenerator.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/PfxGenerator.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/X501Name.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X501Name.cs
index 93e1a6bef4..93e1a6bef4 100644
--- a/MediaBrowser.Server.Startup.Common/Security/X501Name.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X501Name.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/X509Builder.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509Builder.cs
index e168559591..e168559591 100644
--- a/MediaBrowser.Server.Startup.Common/Security/X509Builder.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509Builder.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/X509Certificate.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509Certificate.cs
index f49445f0e7..f49445f0e7 100644
--- a/MediaBrowser.Server.Startup.Common/Security/X509Certificate.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509Certificate.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/X509CertificateBuilder.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateBuilder.cs
index fb6f8ec727..fb6f8ec727 100644
--- a/MediaBrowser.Server.Startup.Common/Security/X509CertificateBuilder.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateBuilder.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/X509CertificateCollection.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateCollection.cs
index 5d353f9cfd..5d353f9cfd 100644
--- a/MediaBrowser.Server.Startup.Common/Security/X509CertificateCollection.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateCollection.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/X509Extension.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509Extension.cs
index e82f52bac7..e82f52bac7 100644
--- a/MediaBrowser.Server.Startup.Common/Security/X509Extension.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509Extension.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/X509Extensions.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509Extensions.cs
index c7d5f0046e..c7d5f0046e 100644
--- a/MediaBrowser.Server.Startup.Common/Security/X509Extensions.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509Extensions.cs
diff --git a/MediaBrowser.Server.Startup.Common/Security/X520Attributes.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X520Attributes.cs
index 5062bf80ad..5062bf80ad 100644
--- a/MediaBrowser.Server.Startup.Common/Security/X520Attributes.cs
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X520Attributes.cs
diff --git a/MediaBrowser.Server.Implementations/IO/MemoryStreamProvider.cs b/MediaBrowser.Server.Startup.Common/IO/MemoryStreamProvider.cs
index cb62ffa980..3ca0f4db5a 100644
--- a/MediaBrowser.Server.Implementations/IO/MemoryStreamProvider.cs
+++ b/MediaBrowser.Server.Startup.Common/IO/MemoryStreamProvider.cs
@@ -2,7 +2,7 @@
using MediaBrowser.Model.IO;
using Microsoft.IO;
-namespace MediaBrowser.Server.Implementations.IO
+namespace MediaBrowser.Server.Startup.Common.IO
{
public class RecyclableMemoryStreamProvider : IMemoryStreamFactory
{
diff --git a/MediaBrowser.Server.Startup.Common/ImageEncoderHelper.cs b/MediaBrowser.Server.Startup.Common/ImageEncoderHelper.cs
new file mode 100644
index 0000000000..0a1470f932
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/ImageEncoderHelper.cs
@@ -0,0 +1,47 @@
+using System;
+using Emby.Drawing;
+using Emby.Drawing.Net;
+using Emby.Drawing.ImageMagick;
+using Emby.Server.Core;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Drawing;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+
+namespace MediaBrowser.Server.Startup.Common
+{
+ public class ImageEncoderHelper
+ {
+ public static IImageEncoder GetImageEncoder(ILogger logger,
+ ILogManager logManager,
+ IFileSystem fileSystem,
+ StartupOptions startupOptions,
+ Func<IHttpClient> httpClient,
+ IApplicationPaths appPaths)
+ {
+ if (!startupOptions.ContainsOption("-enablegdi"))
+ {
+ try
+ {
+ return new ImageMagickEncoder(logManager.GetLogger("ImageMagick"), appPaths, httpClient, fileSystem);
+ }
+ catch
+ {
+ logger.Error("Error loading ImageMagick. Will revert to GDI.");
+ }
+ }
+
+ try
+ {
+ return new GDIImageEncoder(fileSystem, logManager.GetLogger("GDI"));
+ }
+ catch
+ {
+ logger.Error("Error loading GDI. Will revert to NullImageEncoder.");
+ }
+
+ return new NullImageEncoder();
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ChannelScan.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ChannelScan.cs
index fdeae25b0e..fdeae25b0e 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ChannelScan.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ChannelScan.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs
index dddd771790..dddd771790 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs
index 990b6dd949..990b6dd949 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs
index c79ea31a89..c79ea31a89 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs
index 2c54f06654..2c54f06654 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs
index 0a949eb7ed..0a949eb7ed 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs
index abb8636522..abb8636522 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs
index dda5d6a033..dda5d6a033 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs
index 0a95a44133..0a95a44133 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs
index bf56087cd8..bf56087cd8 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs
index 5dd0336421..5dd0336421 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs
index ea6a9ba6aa..ea6a9ba6aa 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs
index 489d7f087c..489d7f087c 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs
index 5f286f1db5..5f286f1db5 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs
index 600eda02da..600eda02da 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs
index 97290623b9..97290623b9 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs
index 0f8682b7cc..0f8682b7cc 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs
index 6d6d50623b..6d6d50623b 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
index 8ecdca46b3..8ecdca46b3 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs
index 55101ce10f..55101ce10f 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/TransmissionMode.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/TransmissionMode.cs
index 71d7656d95..71d7656d95 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/TransmissionMode.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/TransmissionMode.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Utils.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Utils.cs
index 3595e4b0ad..3595e4b0ad 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Utils.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Utils.cs
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0030.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0030.ini
index 1caa948cf6..1caa948cf6 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0030.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0030.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0049.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0049.ini
index 92a0e7dda5..92a0e7dda5 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0049.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0049.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0070.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0070.ini
index 800b097c89..800b097c89 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0070.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0070.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0090.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0090.ini
index 6202569d99..6202569d99 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0090.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0090.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0100.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0100.ini
index 0614ba88c6..0614ba88c6 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0100.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0100.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0130.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0130.ini
index 265104298f..265104298f 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0130.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0130.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0160.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0160.ini
index 9a9503eb58..9a9503eb58 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0160.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0160.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0170.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0170.ini
index 52ba9e5f70..52ba9e5f70 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0170.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0170.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0192.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0192.ini
index fbe65c9b5d..fbe65c9b5d 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0192.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0192.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0200.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0200.ini
index 6eb757f162..6eb757f162 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0200.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0200.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0215.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0215.ini
index 30f3d5c6e9..30f3d5c6e9 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0215.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0215.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0235.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0235.ini
index b1abb39c66..b1abb39c66 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0235.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0235.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0255.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0255.ini
index f72c91b41a..f72c91b41a 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0255.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0255.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0260.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0260.ini
index 299779fb54..299779fb54 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0260.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0260.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0282.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0282.ini
index 07c5ccebe7..07c5ccebe7 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0282.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0282.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0305.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0305.ini
index 196196c956..196196c956 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0305.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0305.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0308.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0308.ini
index fe4f41569b..fe4f41569b 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0308.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0308.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0310.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0310.ini
index be556fdd2b..be556fdd2b 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0310.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0310.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0315.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0315.ini
index 6581c91691..6581c91691 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0315.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0315.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0330.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0330.ini
index b395913cc6..b395913cc6 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0330.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0330.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0360.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0360.ini
index 49042dfb7c..49042dfb7c 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0360.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0360.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0380.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0380.ini
index 25b53cd3d8..25b53cd3d8 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0380.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0380.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0390.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0390.ini
index e779197537..e779197537 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0390.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0390.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0400.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0400.ini
index c1a56c8458..c1a56c8458 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0400.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0400.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0420.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0420.ini
index 3d884a86bd..3d884a86bd 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0420.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0420.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0435.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0435.ini
index a7e5fdb799..a7e5fdb799 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0435.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0435.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0450.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0450.ini
index 0737fb4f18..0737fb4f18 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0450.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0450.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0460.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0460.ini
index 7611715ec8..7611715ec8 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0460.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0460.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0475.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0475.ini
index bc671123fe..bc671123fe 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0475.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0475.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0480.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0480.ini
index fa955de652..fa955de652 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0480.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0480.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0490.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0490.ini
index a85ad11b97..a85ad11b97 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0490.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0490.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0505.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0505.ini
index 5bbfe62977..5bbfe62977 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0505.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0505.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0510.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0510.ini
index 355d0e5b5a..355d0e5b5a 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0510.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0510.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0520.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0520.ini
index 8631604aa7..8631604aa7 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0520.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0520.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0525.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0525.ini
index 2eb001a81f..2eb001a81f 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0525.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0525.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0530.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0530.ini
index 965c41f150..965c41f150 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0530.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0530.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0549.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0549.ini
index b2fdf5a5c8..b2fdf5a5c8 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0549.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0549.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0560.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0560.ini
index bed5b87b5a..bed5b87b5a 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0560.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0560.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0570.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0570.ini
index 27df363114..27df363114 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0570.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0570.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0600.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0600.ini
index 1a711cf263..1a711cf263 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0600.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0600.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0620.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0620.ini
index ae5cf34bf1..ae5cf34bf1 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0620.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0620.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0642.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0642.ini
index 324d99e83c..324d99e83c 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0642.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0642.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0650.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0650.ini
index 81021a0b21..81021a0b21 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0650.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0650.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0660.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0660.ini
index a118dfa389..a118dfa389 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0660.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0660.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0685.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0685.ini
index 7c2cab6818..7c2cab6818 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0685.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0685.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0705.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0705.ini
index 0af8237c99..0af8237c99 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0705.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0705.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0721.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0721.ini
index c25a6ecf5c..c25a6ecf5c 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0721.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0721.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0740.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0740.ini
index 91356547c5..91356547c5 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0740.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0740.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0750.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0750.ini
index 8cdc075909..8cdc075909 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0750.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0750.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0765.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0765.ini
index 1a6195f9ae..1a6195f9ae 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0765.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0765.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0785.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0785.ini
index 8dcf19d376..8dcf19d376 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0785.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0785.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0830.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0830.ini
index ac7588e57d..ac7588e57d 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0830.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0830.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0851.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0851.ini
index faefe54dc7..faefe54dc7 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0851.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0851.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0865.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0865.ini
index f5a946f000..f5a946f000 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0865.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0865.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0875.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0875.ini
index 3f856ba713..3f856ba713 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0875.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0875.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0880.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0880.ini
index a2716d7625..a2716d7625 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0880.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0880.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0900.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0900.ini
index d423f69b64..d423f69b64 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0900.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0900.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0915.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0915.ini
index 3c28ff2540..3c28ff2540 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0915.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0915.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0922.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0922.ini
index 1aaa166417..1aaa166417 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0922.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0922.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0935.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0935.ini
index e47df32779..e47df32779 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0935.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0935.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0950.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0950.ini
index 1b6ba4775e..1b6ba4775e 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0950.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0950.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0965.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0965.ini
index 45d28a1fe6..45d28a1fe6 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/0965.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0965.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1005.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1005.ini
index fe9374bcf0..fe9374bcf0 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1005.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1005.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1030.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1030.ini
index f4607ef89f..f4607ef89f 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1030.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1030.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1055.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1055.ini
index 79c54d9d81..79c54d9d81 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1055.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1055.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1082.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1082.ini
index a53b0c2e8b..a53b0c2e8b 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1082.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1082.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1100.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1100.ini
index 789b56cca7..789b56cca7 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1100.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1100.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1105.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1105.ini
index aafe004557..aafe004557 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1105.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1105.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1130.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1130.ini
index d9c69d3f73..d9c69d3f73 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1130.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1130.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1155.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1155.ini
index 4bfa662708..4bfa662708 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1155.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1155.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1160.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1160.ini
index 3ef951d9a5..3ef951d9a5 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1160.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1160.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1180.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1180.ini
index d41e3f5ad2..d41e3f5ad2 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1180.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1180.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1195.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1195.ini
index 42af4d1c98..42af4d1c98 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1195.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1195.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1222.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1222.ini
index 4d833f21bb..4d833f21bb 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1222.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1222.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1240.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1240.ini
index ed948c78ea..ed948c78ea 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1240.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1240.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1250.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1250.ini
index 738a7debe7..738a7debe7 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1250.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1250.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1280.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1280.ini
index bb2f556c08..bb2f556c08 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1280.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1280.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1320.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1320.ini
index 4694425d39..4694425d39 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1320.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1320.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1340.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1340.ini
index 4ca7c83a01..4ca7c83a01 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1340.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1340.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1380.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1380.ini
index cb952425b2..cb952425b2 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1380.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1380.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1400.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1400.ini
index b4e6dc7c0c..b4e6dc7c0c 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1400.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1400.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1440.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1440.ini
index e31e028abf..e31e028abf 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1440.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1440.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1500.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1500.ini
index 6acfb16798..6acfb16798 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1500.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1500.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1520.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1520.ini
index 0034b3e138..0034b3e138 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1520.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1520.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1540.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1540.ini
index 365575a8ce..365575a8ce 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1540.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1540.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1560.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1560.ini
index be5b9c2f69..be5b9c2f69 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1560.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1560.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1590.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1590.ini
index 567b3cc09e..567b3cc09e 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1590.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1590.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1600 OPTUS D1 FTA (160.0E).ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600 OPTUS D1 FTA (160.0E).ini
index 8650617397..8650617397 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1600 OPTUS D1 FTA (160.0E).ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600 OPTUS D1 FTA (160.0E).ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1600.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600.ini
index 08083f62f2..08083f62f2 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1600.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1620.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1620.ini
index 9a16504dc5..9a16504dc5 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1620.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1620.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1640.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1640.ini
index 9650ab47a0..9650ab47a0 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1640.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1640.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1660.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1660.ini
index 8c040e8841..8c040e8841 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1660.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1660.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1690.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1690.ini
index c7470a5e4a..c7470a5e4a 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1690.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1690.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1720.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1720.ini
index 6f0a6f0ea1..6f0a6f0ea1 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1720.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1720.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1800.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1800.ini
index a3f5044cfb..a3f5044cfb 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1800.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1800.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1830.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1830.ini
index 8775bb5d3e..8775bb5d3e 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/1830.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1830.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2210.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2210.ini
index 123055dd4c..123055dd4c 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2210.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2210.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2230.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2230.ini
index fe661385bb..fe661385bb 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2230.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2230.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2250.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2250.ini
index 4f5a9494da..4f5a9494da 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2250.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2250.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2270.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2270.ini
index 18a777c4b7..18a777c4b7 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2270.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2270.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2290.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2290.ini
index 631af13d23..631af13d23 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2290.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2290.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2310.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2310.ini
index 5915c23650..5915c23650 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2310.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2310.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2330.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2330.ini
index 3ab17e6a1f..3ab17e6a1f 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2330.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2330.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2350.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2350.ini
index cdaa5042ea..cdaa5042ea 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2350.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2350.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2370.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2370.ini
index ce1a1f239f..ce1a1f239f 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2370.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2370.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2390.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2390.ini
index 73ca36a7b6..73ca36a7b6 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2390.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2390.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2410.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2410.ini
index 188507e9dd..188507e9dd 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2410.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2410.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2432.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2432.ini
index aacb92c284..aacb92c284 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2432.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2432.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2451.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2451.ini
index 0272503f2e..0272503f2e 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2451.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2451.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2470.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2470.ini
index 0042e0ef12..0042e0ef12 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2470.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2470.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2489.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2489.ini
index c71cfdd790..c71cfdd790 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2489.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2489.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2500.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2500.ini
index 0fb566b488..0fb566b488 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2500.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2500.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2527.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2527.ini
index 41b4e2981c..41b4e2981c 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2527.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2527.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2550.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2550.ini
index d573433b8b..d573433b8b 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2550.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2550.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2570.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2570.ini
index 1fcd356437..1fcd356437 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2570.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2570.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2590.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2590.ini
index 322d683c18..322d683c18 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2590.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2590.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2608.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2608.ini
index e3200b7cdf..e3200b7cdf 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2608.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2608.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2630.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2630.ini
index 1a888553ad..1a888553ad 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2630.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2630.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2650.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2650.ini
index f3c4e0de6f..f3c4e0de6f 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2650.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2650.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2669.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2669.ini
index ccb7e85319..ccb7e85319 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2669.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2669.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2690.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2690.ini
index e3c73e65c4..e3c73e65c4 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2690.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2690.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2710.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2710.ini
index 8e5aa26881..8e5aa26881 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2710.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2710.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2728.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2728.ini
index 9b148a0460..9b148a0460 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2728.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2728.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2730.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2730.ini
index fdb17c5c09..fdb17c5c09 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2730.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2730.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2750.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2750.ini
index 8f2358d56e..8f2358d56e 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2750.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2750.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2760.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2760.ini
index 253d2cced0..253d2cced0 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2760.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2760.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2770.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2770.ini
index 12cbcc729e..12cbcc729e 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2770.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2770.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2780.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2780.ini
index 7080fc519a..7080fc519a 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2780.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2780.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2812.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2812.ini
index 61b29bb930..61b29bb930 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2812.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2812.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2820.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2820.ini
index 0aa5cc903c..0aa5cc903c 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2820.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2820.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2830.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2830.ini
index c6536b22be..c6536b22be 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2830.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2830.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2850.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2850.ini
index cc6088079e..cc6088079e 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2850.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2850.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2873.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2873.ini
index 6c39037ae5..6c39037ae5 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2873.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2873.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2880.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2880.ini
index 2abb9f716b..2abb9f716b 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2880.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2880.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2881.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2881.ini
index 5a3d34b2c1..5a3d34b2c1 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2881.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2881.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2882.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2882.ini
index 591ba2fe42..591ba2fe42 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2882.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2882.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2900.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2900.ini
index 3a4144bf6b..3a4144bf6b 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2900.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2900.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2930.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2930.ini
index b144562e4d..b144562e4d 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2930.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2930.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2950.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2950.ini
index 3b6a477fc3..3b6a477fc3 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2950.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2950.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2970.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2970.ini
index 60e1423fd8..60e1423fd8 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2970.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2970.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2985.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2985.ini
index 1dc03e67ff..1dc03e67ff 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2985.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2985.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2990.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2990.ini
index ce35c62f5d..ce35c62f5d 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/2990.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2990.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3020.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3020.ini
index 3b6673b47d..3b6673b47d 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3020.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3020.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3045.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3045.ini
index 1d462c1a83..1d462c1a83 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3045.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3045.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3070.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3070.ini
index 16baee6ce0..16baee6ce0 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3070.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3070.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3100.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3100.ini
index 2155127dc4..2155127dc4 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3100.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3100.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3125.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3125.ini
index 07c07c7ff9..07c07c7ff9 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3125.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3125.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3150.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3150.ini
index e322e36f86..e322e36f86 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3150.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3150.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3169.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3169.ini
index 8ed74f2ef9..8ed74f2ef9 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3169.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3169.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3195.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3195.ini
index b331b7d64b..b331b7d64b 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3195.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3195.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3225.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3225.ini
index 800e74334f..800e74334f 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3225.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3225.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3255.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3255.ini
index eb56de14b9..eb56de14b9 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3255.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3255.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3285.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3285.ini
index c5632384c1..c5632384c1 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3285.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3285.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3300.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3300.ini
index 7b1595a531..7b1595a531 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3300.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3300.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3325.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3325.ini
index 380ed40725..380ed40725 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3325.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3325.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3355.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3355.ini
index 542d9bd46b..542d9bd46b 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3355.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3355.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3380.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3380.ini
index 39d26fdbb6..39d26fdbb6 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3380.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3380.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3400.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3400.ini
index c23fe0b194..c23fe0b194 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3400.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3400.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3420.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3420.ini
index 2470d71f95..2470d71f95 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3420.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3420.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3450.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3450.ini
index cae2fe8b9d..cae2fe8b9d 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3450.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3450.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3460.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3460.ini
index 46a7c1b624..46a7c1b624 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3460.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3460.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3475.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3475.ini
index e7a7afc1d4..e7a7afc1d4 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3475.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3475.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3490.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3490.ini
index 7d57379795..7d57379795 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3490.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3490.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3520.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3520.ini
index 6274b967e3..6274b967e3 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3520.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3520.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3527.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3527.ini
index b5aa217800..b5aa217800 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3527.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3527.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3550.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3550.ini
index 5ae30b7787..5ae30b7787 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3550.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3550.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3560.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3560.ini
index bf3006b2e4..bf3006b2e4 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3560.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3560.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3592.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3592.ini
index b1118d4fbb..b1118d4fbb 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3592.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3592.ini
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3594.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3594.ini
index f762d2f6fb..f762d2f6fb 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ini/satellite/3594.ini
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3594.ini
diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
index 7e01fd36d6..27acf3ae07 100644
--- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
+++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
@@ -34,27 +34,15 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Emby.Common.Implementations">
- <HintPath>..\ThirdParty\emby\Emby.Common.Implementations.dll</HintPath>
+ <Reference Include="Emby.Server.Core">
+ <HintPath>..\ThirdParty\emby\Emby.Server.Core.dll</HintPath>
</Reference>
- <Reference Include="MediaBrowser.Naming, Version=1.0.6151.30291, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\MediaBrowser.Naming.1.0.0.59\lib\portable-net45+win8\MediaBrowser.Naming.dll</HintPath>
+ <Reference Include="INIFileParser, Version=2.3.0.0, Culture=neutral, PublicKeyToken=79af7b307b65cf3c, processorArchitecture=MSIL">
+ <HintPath>..\packages\ini-parser.2.3.0\lib\net20\INIFileParser.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Mono.Posix.4.0.0.0\lib\net40\Mono.Posix.dll</HintPath>
- </Reference>
- <Reference Include="Patterns.Logging, Version=1.0.6151.30227, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\Patterns.Logging.1.0.0.6\lib\portable-net45+win8\Patterns.Logging.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="ServiceStack.Text, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll</HintPath>
- </Reference>
- <Reference Include="SimpleInjector, Version=3.2.4.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
- <HintPath>..\packages\SimpleInjector.3.2.4\lib\net45\SimpleInjector.dll</HintPath>
+ <Reference Include="Microsoft.IO.RecyclableMemoryStream, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.1.0.0\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
@@ -70,65 +58,69 @@
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
- <Compile Include="ApplicationHost.cs" />
<Compile Include="ApplicationPathHelper.cs" />
- <Compile Include="Browser\BrowserLauncher.cs" />
- <Compile Include="EntryPoints\StartupWizard.cs" />
- <Compile Include="FFMpeg\FFMpegLoader.cs" />
- <Compile Include="FFMpeg\FFMpegInstallInfo.cs" />
- <Compile Include="FFMpeg\FFMpegInfo.cs" />
- <Compile Include="INativeApp.cs" />
- <Compile Include="MbLinkShortcutHandler.cs" />
- <Compile Include="Migrations\IVersionMigration.cs" />
- <Compile Include="Migrations\DbMigration.cs" />
- <Compile Include="Migrations\UpdateLevelMigration.cs" />
- <Compile Include="NativeEnvironment.cs" />
- <Compile Include="Security\CertificateGenerator.cs" />
- <Compile Include="Networking\NetworkManager.cs" />
+ <Compile Include="Cryptography\ASN1.cs" />
+ <Compile Include="Cryptography\ASN1Convert.cs" />
+ <Compile Include="Cryptography\BitConverterLE.cs" />
+ <Compile Include="Cryptography\CertificateGenerator.cs" />
+ <Compile Include="Cryptography\CryptoConvert.cs" />
+ <Compile Include="Cryptography\PfxGenerator.cs" />
+ <Compile Include="Cryptography\PKCS1.cs" />
+ <Compile Include="Cryptography\PKCS12.cs" />
+ <Compile Include="Cryptography\PKCS7.cs" />
+ <Compile Include="Cryptography\PKCS8.cs" />
+ <Compile Include="Cryptography\X501Name.cs" />
+ <Compile Include="Cryptography\X509Builder.cs" />
+ <Compile Include="Cryptography\X509Certificate.cs" />
+ <Compile Include="Cryptography\X509CertificateBuilder.cs" />
+ <Compile Include="Cryptography\X509CertificateCollection.cs" />
+ <Compile Include="Cryptography\X509Extension.cs" />
+ <Compile Include="Cryptography\X509Extensions.cs" />
+ <Compile Include="Cryptography\X520Attributes.cs" />
+ <Compile Include="ImageEncoderHelper.cs" />
+ <Compile Include="IO\MemoryStreamProvider.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\ChannelScan.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\ReportBlock.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpAppPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpByePacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpListener.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpReceiverReportPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpSenderReportPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpSourceDescriptionPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\SourceDescriptionBlock.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\SourceDescriptionItem.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtp\RtpListener.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtp\RtpPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspMethod.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspRequest.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspResponse.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspSession.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspStatusCode.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\SatIpDiscovery.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\SatIpHost.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\TransmissionMode.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Utils.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Security\ASN1.cs" />
- <Compile Include="Security\ASN1Convert.cs" />
- <Compile Include="Security\BitConverterLE.cs" />
- <Compile Include="Security\CryptoConvert.cs" />
- <Compile Include="Security\PfxGenerator.cs" />
- <Compile Include="Security\PKCS1.cs" />
- <Compile Include="Security\PKCS12.cs" />
- <Compile Include="Security\PKCS7.cs" />
- <Compile Include="Security\PKCS8.cs" />
- <Compile Include="Security\X501Name.cs" />
- <Compile Include="Security\X509Builder.cs" />
- <Compile Include="Security\X509Certificate.cs" />
- <Compile Include="Security\X509CertificateBuilder.cs" />
- <Compile Include="Security\X509CertificateCollection.cs" />
- <Compile Include="Security\X509Extension.cs" />
- <Compile Include="Security\X509Extensions.cs" />
- <Compile Include="Security\X520Attributes.cs" />
- <Compile Include="StartupOptions.cs" />
<Compile Include="SystemEvents.cs" />
- <Compile Include="TextLocalizer.cs" />
- <Compile Include="UnhandledExceptionWriter.cs" />
</ItemGroup>
<ItemGroup>
- <ProjectReference Include="..\Emby.Dlna\Emby.Dlna.csproj">
- <Project>{805844ab-e92f-45e6-9d99-4f6d48d129a5}</Project>
- <Name>Emby.Dlna</Name>
+ <ProjectReference Include="..\Emby.Drawing.ImageMagick\Emby.Drawing.ImageMagick.csproj">
+ <Project>{6cfee013-6e7c-432b-ac37-cabf0880c69a}</Project>
+ <Name>Emby.Drawing.ImageMagick</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Emby.Drawing.Net\Emby.Drawing.Net.csproj">
+ <Project>{c97a239e-a96c-4d64-a844-ccf8cc30aecb}</Project>
+ <Name>Emby.Drawing.Net</Name>
</ProjectReference>
<ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj">
<Project>{08fff49b-f175-4807-a2b5-73b0ebd9f716}</Project>
<Name>Emby.Drawing</Name>
</ProjectReference>
- <ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj">
- <Project>{89ab4548-770d-41fd-a891-8daff44f452c}</Project>
- <Name>Emby.Photos</Name>
- </ProjectReference>
<ProjectReference Include="..\Emby.Server.Implementations\Emby.Server.Implementations.csproj">
<Project>{e383961b-9356-4d5d-8233-9a1079d03055}</Project>
<Name>Emby.Server.Implementations</Name>
</ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj">
- <Project>{4fd51ac5-2c16-4308-a993-c3a84f3b4582}</Project>
- <Name>MediaBrowser.Api</Name>
- </ProjectReference>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
<Name>MediaBrowser.Common</Name>
@@ -137,47 +129,187 @@
<Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
<Name>MediaBrowser.Controller</Name>
</ProjectReference>
- <ProjectReference Include="..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj">
- <Project>{7ef9f3e0-697d-42f3-a08f-19deb5f84392}</Project>
- <Name>MediaBrowser.LocalMetadata</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj">
- <Project>{0bd82fa6-eb8a-4452-8af5-74f9c3849451}</Project>
- <Name>MediaBrowser.MediaEncoding</Name>
- </ProjectReference>
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
<Name>MediaBrowser.Model</Name>
</ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Providers\MediaBrowser.Providers.csproj">
- <Project>{442b5058-dcaf-4263-bb6a-f21e31120a1b}</Project>
- <Name>MediaBrowser.Providers</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Server.Implementations\MediaBrowser.Server.Implementations.csproj">
- <Project>{2e781478-814d-4a48-9d80-bff206441a65}</Project>
- <Name>MediaBrowser.Server.Implementations</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj">
- <Project>{5624b7b5-b5a7-41d8-9f10-cc5611109619}</Project>
- <Name>MediaBrowser.WebDashboard</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj">
- <Project>{23499896-b135-4527-8574-c26e926ea99e}</Project>
- <Name>MediaBrowser.XbmcMetadata</Name>
- </ProjectReference>
- <ProjectReference Include="..\OpenSubtitlesHandler\OpenSubtitlesHandler.csproj">
- <Project>{4a4402d4-e910-443b-b8fc-2c18286a2ca0}</Project>
- <Name>OpenSubtitlesHandler</Name>
- </ProjectReference>
- <ProjectReference Include="..\RSSDP\RSSDP.csproj">
- <Project>{21002819-c39a-4d3e-be83-2a276a77fb1f}</Project>
- <Name>RSSDP</Name>
- </ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0030.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0049.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0070.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0090.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0100.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0130.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0160.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0170.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0192.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0200.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0215.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0235.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0255.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0260.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0282.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0305.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0308.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0310.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0315.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0330.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0360.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0380.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0390.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0400.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0420.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0435.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0450.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0460.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0475.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0480.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0490.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0505.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0510.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0520.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0525.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0530.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0549.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0560.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0570.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0600.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0620.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0642.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0650.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0660.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0685.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0705.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0721.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0740.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0750.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0765.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0785.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0830.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0851.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0865.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0875.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0880.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0900.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0915.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0922.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0935.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0950.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0965.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1005.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1030.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1055.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1082.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1100.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1105.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1130.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1155.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1160.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1180.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1195.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1222.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1240.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1250.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1280.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1320.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1340.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1380.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1400.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1440.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1500.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1520.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1540.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1560.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1590.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1600 OPTUS D1 FTA %28160.0E%29.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1600.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1620.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1640.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1660.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1690.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1720.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1800.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1830.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2210.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2230.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2250.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2270.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2290.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2310.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2330.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2350.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2370.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2390.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2410.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2432.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2451.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2470.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2489.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2500.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2527.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2550.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2570.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2590.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2608.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2630.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2650.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2669.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2690.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2710.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2728.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2730.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2750.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2760.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2770.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2780.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2812.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2820.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2830.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2850.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2873.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2880.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2881.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2882.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2900.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2930.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2950.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2970.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2985.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2990.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3020.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3045.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3070.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3100.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3125.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3150.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3169.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3195.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3225.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3255.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3285.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3300.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3325.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3355.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3380.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3400.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3420.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3450.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3460.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3475.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3490.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3520.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3527.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3550.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3560.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3592.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3594.ini" />
<None Include="packages.config" />
</ItemGroup>
+ <ItemGroup>
+ <Folder Include="Persistence\" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/MediaBrowser.Server.Startup.Common/NativeEnvironment.cs b/MediaBrowser.Server.Startup.Common/NativeEnvironment.cs
deleted file mode 100644
index b30509982e..0000000000
--- a/MediaBrowser.Server.Startup.Common/NativeEnvironment.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using MediaBrowser.Model.System;
-
-namespace MediaBrowser.Server.Startup.Common
-{
- public class NativeEnvironment
- {
- public OperatingSystem OperatingSystem { get; set; }
- public Architecture SystemArchitecture { get; set; }
- public string OperatingSystemVersionString { get; set; }
- }
-
- public enum OperatingSystem
- {
- Windows = 0,
- Osx = 1,
- Bsd = 2,
- Linux = 3
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/Networking/NetworkManager.cs b/MediaBrowser.Server.Startup.Common/Networking/NetworkManager.cs
deleted file mode 100644
index bd260bf873..0000000000
--- a/MediaBrowser.Server.Startup.Common/Networking/NetworkManager.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System.Collections.Generic;
-using Emby.Common.Implementations.Networking;
-using Emby.Common.Implementations.Security;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Net;
-
-namespace MediaBrowser.Server.Startup.Common.Networking
-{
- /// <summary>
- /// Class NetUtils
- /// </summary>
- public class NetworkManager : BaseNetworkManager, INetworkManager
- {
- public NetworkManager(ILogger logger)
- : base(logger)
- {
- }
-
- /// <summary>
- /// Gets the network shares.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>IEnumerable{NetworkShare}.</returns>
- public IEnumerable<NetworkShare> GetNetworkShares(string path)
- {
- return new List<NetworkShare>();
- }
-
- /// <summary>
- /// Gets available devices within the domain
- /// </summary>
- /// <returns>PC's in the Domain</returns>
- public IEnumerable<FileSystemEntryInfo> GetNetworkDevices()
- {
- return new List<FileSystemEntryInfo>();
- }
-
- /// <summary>
- /// Generates a self signed certificate at the locatation specified by <paramref name="certificatePath"/>.
- /// </summary>
- /// <param name="certificatePath">The path to generate the certificate.</param>
- /// <param name="hostname">The common name for the certificate.</param>
- public void GenerateSelfSignedSslCertificate(string certificatePath, string hostname)
- {
- CertificateGenerator.CreateSelfSignCertificatePfx(certificatePath, hostname, Logger);
- }
- }
-}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Startup.Common/Persistence/SqliteExtensions.cs
index c273d49458..72ecfc1bf5 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs
+++ b/MediaBrowser.Server.Startup.Common/Persistence/SqliteExtensions.cs
@@ -4,7 +4,7 @@ using System.Data.SQLite;
using System.Threading.Tasks;
using MediaBrowser.Model.Logging;
-namespace MediaBrowser.Server.Implementations.Persistence
+namespace Emby.Server.Core.Data
{
/// <summary>
/// Class SQLiteExtensions
diff --git a/MediaBrowser.Server.Startup.Common/packages.config b/MediaBrowser.Server.Startup.Common/packages.config
index ea3d0e7f8d..061870041a 100644
--- a/MediaBrowser.Server.Startup.Common/packages.config
+++ b/MediaBrowser.Server.Startup.Common/packages.config
@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="MediaBrowser.Naming" version="1.0.0.59" targetFramework="net46" />
- <package id="Mono.Posix" version="4.0.0.0" targetFramework="net45" />
- <package id="Patterns.Logging" version="1.0.0.6" targetFramework="net46" />
- <package id="SimpleInjector" version="3.2.4" targetFramework="net46" />
+ <package id="ini-parser" version="2.3.0" targetFramework="net46" />
+ <package id="Microsoft.IO.RecyclableMemoryStream" version="1.1.0.0" targetFramework="net46" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs
index a3f4096367..09c948a4a8 100644
--- a/MediaBrowser.ServerApplication/MainStartup.cs
+++ b/MediaBrowser.ServerApplication/MainStartup.cs
@@ -1,7 +1,6 @@
using MediaBrowser.Model.Logging;
using MediaBrowser.Server.Implementations;
using MediaBrowser.Server.Startup.Common;
-using MediaBrowser.Server.Startup.Common.Browser;
using MediaBrowser.ServerApplication.Native;
using MediaBrowser.ServerApplication.Splash;
using MediaBrowser.ServerApplication.Updates;
@@ -18,10 +17,17 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
+using Emby.Common.Implementations.EnvironmentInfo;
using Emby.Common.Implementations.IO;
using Emby.Common.Implementations.Logging;
+using Emby.Common.Implementations.Networking;
+using Emby.Common.Implementations.Security;
+using Emby.Server.Core;
+using Emby.Server.Core.Browser;
+using Emby.Server.Implementations.IO;
using ImageMagickSharp;
using MediaBrowser.Common.Net;
+using MediaBrowser.Server.Startup.Common.IO;
namespace MediaBrowser.ServerApplication
{
@@ -61,8 +67,8 @@ namespace MediaBrowser.ServerApplication
return false;
}
/// <summary>
- /// Defines the entry point of the application.
- /// </summary>
+ /// Defines the entry point of the application.
+ /// </summary>
public static void Main()
{
var options = new StartupOptions();
@@ -316,13 +322,22 @@ namespace MediaBrowser.ServerApplication
IsRunningAsService = runService
};
+ var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths);
+
_appHost = new ApplicationHost(appPaths,
logManager,
options,
fileSystem,
- nativeApp,
+ nativeApp,
new PowerManagement(),
- "emby.windows.zip");
+ "emby.windows.zip",
+ new EnvironmentInfo(),
+ imageEncoder,
+ new Server.Startup.Common.SystemEvents(logManager.GetLogger("SystemEvents")),
+ new RecyclableMemoryStreamProvider(),
+ new NetworkManager(logManager.GetLogger("NetworkManager")),
+ GenerateCertificate,
+ () => Environment.UserDomainName);
var initProgress = new Progress<double>();
@@ -363,6 +378,11 @@ namespace MediaBrowser.ServerApplication
}
}
+ private static void GenerateCertificate(string certPath, string certHost)
+ {
+ CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, _logger);
+ }
+
private static ServerNotifyIcon _serverNotifyIcon;
private static TaskScheduler _mainTaskScheduler;
private static void ShowTrayIcon()
diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
index eaf4f31489..f6aef57443 100644
--- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
+++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
@@ -67,6 +67,9 @@
<Reference Include="Emby.Common.Implementations">
<HintPath>..\ThirdParty\emby\Emby.Common.Implementations.dll</HintPath>
</Reference>
+ <Reference Include="Emby.Server.Core">
+ <HintPath>..\ThirdParty\emby\Emby.Server.Core.dll</HintPath>
+ </Reference>
<Reference Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ImageMagickSharp.1.0.0.18\lib\net45\ImageMagickSharp.dll</HintPath>
@@ -75,12 +78,17 @@
<HintPath>..\packages\NLog.4.4.0-betaV15\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="Patterns.Logging, Version=1.0.6151.30227, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\Patterns.Logging.1.0.0.6\lib\portable-net45+win8\Patterns.Logging.dll</HintPath>
+ <Reference Include="ServiceStack.Text, Version=4.5.4.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\ServiceStack.Text.4.5.4\lib\net45\ServiceStack.Text.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="SharpCompress, Version=0.14.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="ServiceStack.Interfaces">
- <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll</HintPath>
+ <Reference Include="SimpleInjector, Version=3.2.4.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
+ <HintPath>..\packages\SimpleInjector.3.2.4\lib\net45\SimpleInjector.dll</HintPath>
+ <Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
@@ -105,7 +113,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
- <Compile Include="..\MediaBrowser.Server.Implementations\Persistence\SqliteExtensions.cs">
+ <Compile Include="..\MediaBrowser.Server.Startup.Common\Persistence\SqliteExtensions.cs">
<Link>Native\SqliteExtensions.cs</Link>
</Compile>
<Compile Include="..\SharedVersion.cs">
@@ -1057,10 +1065,38 @@
<Content Include="Resources\Images\mb3logo800.png" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\BDInfo\BDInfo.csproj">
+ <Project>{88ae38df-19d7-406f-a6a9-09527719a21e}</Project>
+ <Name>BDInfo</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\DvdLib\DvdLib.csproj">
+ <Project>{713f42b5-878e-499d-a878-e4c652b1d5e8}</Project>
+ <Name>DvdLib</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Emby.Dlna\Emby.Dlna.csproj">
+ <Project>{805844ab-e92f-45e6-9d99-4f6d48d129a5}</Project>
+ <Name>Emby.Dlna</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Emby.Drawing.ImageMagick\Emby.Drawing.ImageMagick.csproj">
+ <Project>{6cfee013-6e7c-432b-ac37-cabf0880c69a}</Project>
+ <Name>Emby.Drawing.ImageMagick</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Emby.Drawing.Net\Emby.Drawing.Net.csproj">
+ <Project>{c97a239e-a96c-4d64-a844-ccf8cc30aecb}</Project>
+ <Name>Emby.Drawing.Net</Name>
+ </ProjectReference>
<ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj">
<Project>{08fff49b-f175-4807-a2b5-73b0ebd9f716}</Project>
<Name>Emby.Drawing</Name>
</ProjectReference>
+ <ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj">
+ <Project>{89ab4548-770d-41fd-a891-8daff44f452c}</Project>
+ <Name>Emby.Photos</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Emby.Server.Implementations\Emby.Server.Implementations.csproj">
+ <Project>{e383961b-9356-4d5d-8233-9a1079d03055}</Project>
+ <Name>Emby.Server.Implementations</Name>
+ </ProjectReference>
<ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj">
<Project>{4fd51ac5-2c16-4308-a993-c3a84f3b4582}</Project>
<Name>MediaBrowser.Api</Name>
@@ -1105,8 +1141,23 @@
<Project>{23499896-b135-4527-8574-c26e926ea99e}</Project>
<Name>MediaBrowser.XbmcMetadata</Name>
</ProjectReference>
+ <ProjectReference Include="..\OpenSubtitlesHandler\OpenSubtitlesHandler.csproj">
+ <Project>{4a4402d4-e910-443b-b8fc-2c18286a2ca0}</Project>
+ <Name>OpenSubtitlesHandler</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\RSSDP\RSSDP.csproj">
+ <Project>{21002819-c39a-4d3e-be83-2a276a77fb1f}</Project>
+ <Name>RSSDP</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\ServiceStack\ServiceStack.csproj">
+ <Project>{680a1709-25eb-4d52-a87f-ee03ffd94baa}</Project>
+ <Name>ServiceStack</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\SocketHttpListener.Portable\SocketHttpListener.Portable.csproj">
+ <Project>{4f26d5d8-a7b0-42b3-ba42-7cb7d245934e}</Project>
+ <Name>SocketHttpListener.Portable</Name>
+ </ProjectReference>
</ItemGroup>
- <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
diff --git a/MediaBrowser.ServerApplication/Native/DbConnector.cs b/MediaBrowser.ServerApplication/Native/DbConnector.cs
index f403ce2ce4..986bc1850e 100644
--- a/MediaBrowser.ServerApplication/Native/DbConnector.cs
+++ b/MediaBrowser.ServerApplication/Native/DbConnector.cs
@@ -1,7 +1,7 @@
using System.Data;
using System.Threading.Tasks;
+using Emby.Server.Core.Data;
using MediaBrowser.Model.Logging;
-using MediaBrowser.Server.Implementations.Persistence;
namespace MediaBrowser.ServerApplication.Native
{
diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs
index 5bed8556e2..babe952d6d 100644
--- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs
+++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs
@@ -8,13 +8,12 @@ using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
+using Emby.Server.Core;
+using Emby.Server.Core.Data;
+using Emby.Server.Core.FFMpeg;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
-using MediaBrowser.Model.System;
-using MediaBrowser.Server.Implementations.Persistence;
-using MediaBrowser.Server.Startup.Common.FFMpeg;
-using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem;
namespace MediaBrowser.ServerApplication.Native
{
@@ -48,19 +47,6 @@ namespace MediaBrowser.ServerApplication.Native
ServerAuthorization.AuthorizeServer(udpPort, httpServerPort, httpsPort, applicationPath, tempDirectory);
}
- public NativeEnvironment Environment
- {
- get
- {
- return new NativeEnvironment
- {
- OperatingSystem = OperatingSystem.Windows,
- SystemArchitecture = System.Environment.Is64BitOperatingSystem ? Architecture.X64 : Architecture.X86,
- OperatingSystemVersionString = System.Environment.OSVersion.VersionString
- };
- }
- }
-
public bool SupportsLibraryMonitor
{
get { return true; }
diff --git a/MediaBrowser.ServerApplication/Networking/NetworkManager.cs b/MediaBrowser.ServerApplication/Networking/NetworkManager.cs
index 7b4379abf0..ed99dcc061 100644
--- a/MediaBrowser.ServerApplication/Networking/NetworkManager.cs
+++ b/MediaBrowser.ServerApplication/Networking/NetworkManager.cs
@@ -13,7 +13,7 @@ namespace MediaBrowser.ServerApplication.Networking
/// <summary>
/// Class NetUtils
/// </summary>
- public class NetworkManager : Server.Startup.Common.Networking.NetworkManager
+ public class NetworkManager : Emby.Common.Implementations.Networking.NetworkManager
{
public NetworkManager(ILogger logger)
: base(logger)
diff --git a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs
index bbf2b785c7..139961e6f3 100644
--- a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs
+++ b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs
@@ -1,10 +1,10 @@
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Logging;
-using MediaBrowser.Server.Startup.Common.Browser;
using System;
using System.ComponentModel;
using System.Windows.Forms;
+using Emby.Server.Core.Browser;
using MediaBrowser.Model.Globalization;
namespace MediaBrowser.ServerApplication
diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config
index 8dbcaa2b98..e93f13bee7 100644
--- a/MediaBrowser.ServerApplication/packages.config
+++ b/MediaBrowser.ServerApplication/packages.config
@@ -2,6 +2,8 @@
<packages>
<package id="ImageMagickSharp" version="1.0.0.18" targetFramework="net45" />
<package id="NLog" version="4.4.0-betaV15" targetFramework="net462" />
- <package id="Patterns.Logging" version="1.0.0.6" targetFramework="net462" />
+ <package id="ServiceStack.Text" version="4.5.4" targetFramework="net462" />
+ <package id="SharpCompress" version="0.14.0" targetFramework="net462" />
+ <package id="SimpleInjector" version="3.2.4" targetFramework="net462" />
<package id="System.Data.SQLite.Core" version="1.0.103" targetFramework="net462" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config
index 0a650254ec..6b8deb9c96 100644
--- a/MediaBrowser.WebDashboard/packages.config
+++ b/MediaBrowser.WebDashboard/packages.config
@@ -1,5 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
- <package id="WebMarkupMin.Core" version="2.1.0" targetFramework="net45" requireReinstallation="true" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.sln b/MediaBrowser.sln
index 7e0e10b7a4..292d0345cf 100644
--- a/MediaBrowser.sln
+++ b/MediaBrowser.sln
@@ -72,6 +72,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RSSDP", "RSSDP\RSSDP.csproj
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Dlna", "Emby.Dlna\Emby.Dlna.csproj", "{805844AB-E92F-45E6-9D99-4F6D48D129A5}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Emby.Server.Core", "Emby.Server.Core\Emby.Server.Core.xproj", "{65AA7D67-8059-40CD-91F1-16D02687226C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing.ImageMagick", "Emby.Drawing.ImageMagick\Emby.Drawing.ImageMagick.csproj", "{6CFEE013-6E7C-432B-AC37-CABF0880C69A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing.Net", "Emby.Drawing.Net\Emby.Drawing.Net.csproj", "{C97A239E-A96C-4D64-A844-CCF8CC30AECB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack", "ServiceStack\ServiceStack.csproj", "{680A1709-25EB-4D52-A87F-EE03FFD94BAA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SocketHttpListener.Portable", "SocketHttpListener.Portable\SocketHttpListener.Portable.csproj", "{4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -89,6 +99,11 @@ Global
Release|Win32 = Release|Win32
Release|x64 = Release|x64
Release|x86 = Release|x86
+ Signed|Any CPU = Signed|Any CPU
+ Signed|Mixed Platforms = Signed|Mixed Platforms
+ Signed|Win32 = Signed|Win32
+ Signed|x64 = Signed|x64
+ Signed|x86 = Signed|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -114,6 +129,16 @@ Global
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x64.ActiveCfg = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.ActiveCfg = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.Build.0 = Release|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|Any CPU.ActiveCfg = Release Mono|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|Any CPU.Build.0 = Release Mono|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|Mixed Platforms.Build.0 = Release Mono|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|Win32.ActiveCfg = Release Mono|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|Win32.Build.0 = Release Mono|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|x64.ActiveCfg = Release Mono|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|x64.Build.0 = Release Mono|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|x86.ActiveCfg = Release Mono|Any CPU
+ {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Signed|x86.Build.0 = Release Mono|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -137,6 +162,16 @@ Global
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|x64.ActiveCfg = Release|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|x86.ActiveCfg = Release|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|x86.Build.0 = Release|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|Any CPU.ActiveCfg = Release Mono|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|Any CPU.Build.0 = Release Mono|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|Mixed Platforms.Build.0 = Release Mono|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|Win32.ActiveCfg = Release Mono|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|Win32.Build.0 = Release Mono|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|x64.ActiveCfg = Release Mono|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|x64.Build.0 = Release Mono|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|x86.ActiveCfg = Release Mono|Any CPU
+ {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|x86.Build.0 = Release Mono|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -160,6 +195,16 @@ Global
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x64.ActiveCfg = Release|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.ActiveCfg = Release|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.Build.0 = Release|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|Any CPU.ActiveCfg = Release Mono|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|Any CPU.Build.0 = Release Mono|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|Mixed Platforms.Build.0 = Release Mono|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|Win32.ActiveCfg = Release Mono|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|Win32.Build.0 = Release Mono|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|x64.ActiveCfg = Release Mono|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|x64.Build.0 = Release Mono|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|x86.ActiveCfg = Release Mono|Any CPU
+ {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Signed|x86.Build.0 = Release Mono|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -186,6 +231,16 @@ Global
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x64.ActiveCfg = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x86.ActiveCfg = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x86.Build.0 = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|Win32.Build.0 = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|x64.ActiveCfg = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|x64.Build.0 = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|x86.ActiveCfg = Release|Any CPU
+ {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Signed|x86.Build.0 = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -209,6 +264,16 @@ Global
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x64.ActiveCfg = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.ActiveCfg = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.Build.0 = Release|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|Any CPU.ActiveCfg = Release Mono|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|Any CPU.Build.0 = Release Mono|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|Mixed Platforms.Build.0 = Release Mono|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|Win32.ActiveCfg = Release Mono|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|Win32.Build.0 = Release Mono|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|x64.ActiveCfg = Release Mono|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|x64.Build.0 = Release Mono|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|x86.ActiveCfg = Release Mono|Any CPU
+ {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Signed|x86.Build.0 = Release Mono|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -230,6 +295,16 @@ Global
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|Win32.ActiveCfg = Release|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|x64.ActiveCfg = Release|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|x86.ActiveCfg = Release|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|Any CPU.ActiveCfg = Release Mono|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|Any CPU.Build.0 = Release Mono|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|Mixed Platforms.Build.0 = Release Mono|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|Win32.ActiveCfg = Release Mono|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|Win32.Build.0 = Release Mono|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|x64.ActiveCfg = Release Mono|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|x64.Build.0 = Release Mono|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|x86.ActiveCfg = Release Mono|Any CPU
+ {2E781478-814D-4A48-9D80-BFF206441A65}.Signed|x86.Build.0 = Release Mono|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -251,6 +326,16 @@ Global
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release|Win32.ActiveCfg = Release|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release|x64.ActiveCfg = Release|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release|x86.ActiveCfg = Release|Any CPU
+ {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Signed|Win32.Build.0 = Release|Any CPU
+ {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Signed|x64.ActiveCfg = Release|Any CPU
+ {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Signed|x64.Build.0 = Release|Any CPU
+ {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Signed|x86.ActiveCfg = Release|Any CPU
+ {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Signed|x86.Build.0 = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -272,6 +357,16 @@ Global
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Win32.ActiveCfg = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|x64.ActiveCfg = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|x86.ActiveCfg = Release|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|Any CPU.ActiveCfg = Release Mono|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|Any CPU.Build.0 = Release Mono|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|Mixed Platforms.Build.0 = Release Mono|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|Win32.ActiveCfg = Release Mono|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|Win32.Build.0 = Release Mono|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|x64.ActiveCfg = Release Mono|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|x64.Build.0 = Release Mono|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|x86.ActiveCfg = Release Mono|Any CPU
+ {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Signed|x86.Build.0 = Release Mono|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -294,6 +389,16 @@ Global
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|Win32.ActiveCfg = Release|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|x64.ActiveCfg = Release|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|x86.ActiveCfg = Release|Any CPU
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Signed|Mixed Platforms.ActiveCfg = Debug|x86
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Signed|Mixed Platforms.Build.0 = Debug|x86
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Signed|Win32.ActiveCfg = Debug|x86
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Signed|Win32.Build.0 = Debug|x86
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Signed|x64.ActiveCfg = Release|Any CPU
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Signed|x64.Build.0 = Release|Any CPU
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Signed|x86.ActiveCfg = Debug|x86
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Signed|x86.Build.0 = Debug|x86
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -315,6 +420,16 @@ Global
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Win32.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x64.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x86.ActiveCfg = Release|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|Any CPU.ActiveCfg = Release Mono|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|Any CPU.Build.0 = Release Mono|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|Mixed Platforms.Build.0 = Release Mono|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|Win32.ActiveCfg = Release Mono|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|Win32.Build.0 = Release Mono|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|x64.ActiveCfg = Release Mono|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|x64.Build.0 = Release Mono|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|x86.ActiveCfg = Release Mono|Any CPU
+ {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Signed|x86.Build.0 = Release Mono|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -336,6 +451,16 @@ Global
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Win32.ActiveCfg = Release|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|x64.ActiveCfg = Release|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|x86.ActiveCfg = Release|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|Any CPU.ActiveCfg = Release Mono|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|Any CPU.Build.0 = Release Mono|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|Mixed Platforms.Build.0 = Release Mono|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|Win32.ActiveCfg = Release Mono|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|Win32.Build.0 = Release Mono|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|x64.ActiveCfg = Release Mono|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|x64.Build.0 = Release Mono|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|x86.ActiveCfg = Release Mono|Any CPU
+ {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Signed|x86.Build.0 = Release Mono|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -357,6 +482,16 @@ Global
{23499896-B135-4527-8574-C26E926EA99E}.Release|Win32.ActiveCfg = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release|x64.ActiveCfg = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release|x86.ActiveCfg = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|Win32.Build.0 = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|x64.ActiveCfg = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|x64.Build.0 = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|x86.ActiveCfg = Release|Any CPU
+ {23499896-B135-4527-8574-C26E926EA99E}.Signed|x86.Build.0 = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -378,6 +513,16 @@ Global
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Win32.ActiveCfg = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|x64.ActiveCfg = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|x86.ActiveCfg = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|Win32.Build.0 = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|x64.ActiveCfg = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|x64.Build.0 = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|x86.ActiveCfg = Release|Any CPU
+ {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Signed|x86.Build.0 = Release|Any CPU
{175A9388-F352-4586-A6B4-070DED62B644}.Debug|Any CPU.ActiveCfg = Debug|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Debug|Any CPU.Build.0 = Debug|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
@@ -404,6 +549,16 @@ Global
{175A9388-F352-4586-A6B4-070DED62B644}.Release|x64.ActiveCfg = Release|Any CPU
{175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.ActiveCfg = Release|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.Build.0 = Release|x86
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|Mixed Platforms.ActiveCfg = Release|x86
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|Mixed Platforms.Build.0 = Release|x86
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|Win32.ActiveCfg = Release|x86
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|Win32.Build.0 = Release|x86
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|x64.ActiveCfg = Release|Any CPU
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|x64.Build.0 = Release|Any CPU
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|x86.ActiveCfg = Release|x86
+ {175A9388-F352-4586-A6B4-070DED62B644}.Signed|x86.Build.0 = Release|x86
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -425,6 +580,16 @@ Global
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release|Win32.ActiveCfg = Release|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release|x64.ActiveCfg = Release|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release|x86.ActiveCfg = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|Win32.Build.0 = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|x64.ActiveCfg = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|x64.Build.0 = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|x86.ActiveCfg = Release|Any CPU
+ {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Signed|x86.Build.0 = Release|Any CPU
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -446,6 +611,16 @@ Global
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|Win32.ActiveCfg = Release|Any CPU
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|x64.ActiveCfg = Release|Any CPU
{08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Release|x86.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|Win32.Build.0 = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|x64.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|x64.Build.0 = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|x86.ActiveCfg = Release|Any CPU
+ {08FFF49B-F175-4807-A2B5-73B0EBD9F716}.Signed|x86.Build.0 = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -476,6 +651,16 @@ Global
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|x64.Build.0 = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|x86.ActiveCfg = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|x86.Build.0 = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|Win32.Build.0 = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|x64.ActiveCfg = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|x64.Build.0 = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|x86.ActiveCfg = Release|Any CPU
+ {89AB4548-770D-41FD-A891-8DAFF44F452C}.Signed|x86.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -506,6 +691,16 @@ Global
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|x64.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|x86.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|x86.Build.0 = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|Win32.Build.0 = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|x64.ActiveCfg = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|x64.Build.0 = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|x86.ActiveCfg = Release|Any CPU
+ {713F42B5-878E-499D-A878-E4C652B1D5E8}.Signed|x86.Build.0 = Release|Any CPU
{5A27010A-09C6-4E86-93EA-437484C10917}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A27010A-09C6-4E86-93EA-437484C10917}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A27010A-09C6-4E86-93EA-437484C10917}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -536,6 +731,16 @@ Global
{5A27010A-09C6-4E86-93EA-437484C10917}.Release|x64.Build.0 = Release|Any CPU
{5A27010A-09C6-4E86-93EA-437484C10917}.Release|x86.ActiveCfg = Release|Any CPU
{5A27010A-09C6-4E86-93EA-437484C10917}.Release|x86.Build.0 = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|Win32.Build.0 = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|x64.ActiveCfg = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|x64.Build.0 = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|x86.ActiveCfg = Release|Any CPU
+ {5A27010A-09C6-4E86-93EA-437484C10917}.Signed|x86.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -566,6 +771,16 @@ Global
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|x64.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|x86.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|x86.Build.0 = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|Win32.Build.0 = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|x64.ActiveCfg = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|x64.Build.0 = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|x86.ActiveCfg = Release|Any CPU
+ {88AE38DF-19D7-406F-A6A9-09527719A21E}.Signed|x86.Build.0 = Release|Any CPU
{E383961B-9356-4D5D-8233-9A1079D03055}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E383961B-9356-4D5D-8233-9A1079D03055}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E383961B-9356-4D5D-8233-9A1079D03055}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -596,6 +811,16 @@ Global
{E383961B-9356-4D5D-8233-9A1079D03055}.Release|x64.Build.0 = Release|Any CPU
{E383961B-9356-4D5D-8233-9A1079D03055}.Release|x86.ActiveCfg = Release|Any CPU
{E383961B-9356-4D5D-8233-9A1079D03055}.Release|x86.Build.0 = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|Win32.Build.0 = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|x64.ActiveCfg = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|x64.Build.0 = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|x86.ActiveCfg = Release|Any CPU
+ {E383961B-9356-4D5D-8233-9A1079D03055}.Signed|x86.Build.0 = Release|Any CPU
{4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -626,6 +851,16 @@ Global
{4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Release|x64.Build.0 = Release|Any CPU
{4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Release|x86.ActiveCfg = Release|Any CPU
{4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Release|x86.Build.0 = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|Win32.Build.0 = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|x64.ActiveCfg = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|x64.Build.0 = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|x86.ActiveCfg = Release|Any CPU
+ {4ACAB6A2-AC9A-4B50-BAEC-1FE4A1F3B8BC}.Signed|x86.Build.0 = Release|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -656,6 +891,16 @@ Global
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|x64.Build.0 = Release|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|x86.ActiveCfg = Release|Any CPU
{21002819-C39A-4D3E-BE83-2A276A77FB1F}.Release|x86.Build.0 = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|Win32.Build.0 = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|x64.ActiveCfg = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|x64.Build.0 = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|x86.ActiveCfg = Release|Any CPU
+ {21002819-C39A-4D3E-BE83-2A276A77FB1F}.Signed|x86.Build.0 = Release|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -686,6 +931,216 @@ Global
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|x64.Build.0 = Release|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|x86.ActiveCfg = Release|Any CPU
{805844AB-E92F-45E6-9D99-4F6D48D129A5}.Release|x86.Build.0 = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|Win32.Build.0 = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|x64.ActiveCfg = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|x64.Build.0 = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|x86.ActiveCfg = Release|Any CPU
+ {805844AB-E92F-45E6-9D99-4F6D48D129A5}.Signed|x86.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|Win32.Build.0 = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|x64.Build.0 = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Debug|x86.Build.0 = Debug|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|Mixed Platforms.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|Win32.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|Win32.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|x64.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|x64.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|x86.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release Mono|x86.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|Win32.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|Win32.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|x64.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|x64.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|x86.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Release|x86.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|Win32.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|x64.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|x64.Build.0 = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|x86.ActiveCfg = Release|Any CPU
+ {65AA7D67-8059-40CD-91F1-16D02687226C}.Signed|x86.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|Win32.Build.0 = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|x64.Build.0 = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Debug|x86.Build.0 = Debug|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|Mixed Platforms.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|Win32.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|Win32.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|x64.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|x64.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|x86.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release Mono|x86.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|Win32.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|Win32.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|x64.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|x64.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|x86.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Release|x86.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|Win32.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|x64.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|x64.Build.0 = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|x86.ActiveCfg = Release|Any CPU
+ {6CFEE013-6E7C-432B-AC37-CABF0880C69A}.Signed|x86.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|Win32.Build.0 = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|x64.Build.0 = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Debug|x86.Build.0 = Debug|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|Mixed Platforms.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|Win32.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|Win32.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|x64.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|x64.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|x86.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release Mono|x86.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|Win32.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|Win32.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|x64.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|x64.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|x86.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Release|x86.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|Win32.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|x64.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|x64.Build.0 = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|x86.ActiveCfg = Release|Any CPU
+ {C97A239E-A96C-4D64-A844-CCF8CC30AECB}.Signed|x86.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|Win32.Build.0 = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|x64.Build.0 = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Debug|x86.Build.0 = Debug|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|Mixed Platforms.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|Win32.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|Win32.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|x64.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|x64.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|x86.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release Mono|x86.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|Win32.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|Win32.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|x64.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|x64.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|x86.ActiveCfg = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Release|x86.Build.0 = Release|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|Any CPU.ActiveCfg = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|Any CPU.Build.0 = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|Win32.ActiveCfg = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|Win32.Build.0 = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|x64.ActiveCfg = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|x64.Build.0 = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|x86.ActiveCfg = Signed|Any CPU
+ {680A1709-25EB-4D52-A87F-EE03FFD94BAA}.Signed|x86.Build.0 = Signed|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|Win32.Build.0 = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|x64.Build.0 = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Debug|x86.Build.0 = Debug|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|Any CPU.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|Mixed Platforms.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|Win32.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|Win32.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|x64.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|x64.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|x86.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release Mono|x86.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|Win32.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|Win32.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|x64.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|x64.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|x86.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Release|x86.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|Any CPU.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|Any CPU.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|Mixed Platforms.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|Win32.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|Win32.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|x64.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|x64.Build.0 = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|x86.ActiveCfg = Release|Any CPU
+ {4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}.Signed|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/RSSDP/project.json b/RSSDP/project.json
new file mode 100644
index 0000000000..fbbe9eaf32
--- /dev/null
+++ b/RSSDP/project.json
@@ -0,0 +1,17 @@
+{
+ "frameworks":{
+ "netstandard1.6":{
+ "dependencies":{
+ "NETStandard.Library":"1.6.0",
+ }
+ },
+ ".NETPortable,Version=v4.5,Profile=Profile7":{
+ "buildOptions": {
+ "define": [ ]
+ },
+ "frameworkAssemblies":{
+
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/ServiceStack/FilterAttributeCache.cs b/ServiceStack/FilterAttributeCache.cs
new file mode 100644
index 0000000000..378433addd
--- /dev/null
+++ b/ServiceStack/FilterAttributeCache.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using ServiceStack;
+
+namespace ServiceStack.Support.WebHost
+{
+ public static class FilterAttributeCache
+ {
+ public static MediaBrowser.Model.Services.IHasRequestFilter[] GetRequestFilterAttributes(Type requestDtoType)
+ {
+ var attributes = requestDtoType.AllAttributes().OfType<MediaBrowser.Model.Services.IHasRequestFilter>().ToList();
+
+ var serviceType = ServiceStackHost.Instance.Metadata.GetServiceTypeByRequest(requestDtoType);
+ if (serviceType != null)
+ {
+ attributes.AddRange(serviceType.AllAttributes().OfType<MediaBrowser.Model.Services.IHasRequestFilter>());
+ }
+
+ attributes.Sort((x,y) => x.Priority - y.Priority);
+
+ return attributes.ToArray();
+ }
+ }
+}
diff --git a/ServiceStack/Host/ActionContext.cs b/ServiceStack/Host/ActionContext.cs
new file mode 100644
index 0000000000..9f165cff15
--- /dev/null
+++ b/ServiceStack/Host/ActionContext.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace ServiceStack.Host
+{
+ /// <summary>
+ /// Context to capture IService action
+ /// </summary>
+ public class ActionContext
+ {
+ public const string AnyAction = "ANY";
+
+ public string Id { get; set; }
+
+ public ActionInvokerFn ServiceAction { get; set; }
+ public MediaBrowser.Model.Services.IHasRequestFilter[] RequestFilters { get; set; }
+
+ public static string Key(Type serviceType, string method, string requestDtoName)
+ {
+ return serviceType.FullName + " " + method.ToUpper() + " " + requestDtoName;
+ }
+
+ public static string AnyKey(Type serviceType, string requestDtoName)
+ {
+ return Key(serviceType, AnyAction, requestDtoName);
+ }
+ }
+} \ No newline at end of file
diff --git a/ServiceStack/Host/ContentTypes.cs b/ServiceStack/Host/ContentTypes.cs
new file mode 100644
index 0000000000..22fdc3e507
--- /dev/null
+++ b/ServiceStack/Host/ContentTypes.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using MediaBrowser.Model.Services;
+
+namespace ServiceStack.Host
+{
+ public class ContentTypes
+ {
+ public static ContentTypes Instance = new ContentTypes();
+
+ public void SerializeToStream(IRequest req, object response, Stream responseStream)
+ {
+ var contentType = req.ResponseContentType;
+ var serializer = GetResponseSerializer(contentType);
+ if (serializer == null)
+ throw new NotSupportedException("ContentType not supported: " + contentType);
+
+ var httpRes = new HttpResponseStreamWrapper(responseStream, req)
+ {
+ Dto = req.Response.Dto
+ };
+ serializer(req, response, httpRes);
+ }
+
+ public Action<IRequest, object, IResponse> GetResponseSerializer(string contentType)
+ {
+ var serializer = GetStreamSerializer(contentType);
+ if (serializer == null) return null;
+
+ return (httpReq, dto, httpRes) => serializer(httpReq, dto, httpRes.OutputStream);
+ }
+
+ public Action<IRequest, object, Stream> GetStreamSerializer(string contentType)
+ {
+ switch (GetRealContentType(contentType))
+ {
+ case "application/xml":
+ case "text/xml":
+ case "text/xml; charset=utf-8": //"text/xml; charset=utf-8" also matches xml
+ return (r, o, s) => ServiceStackHost.Instance.SerializeToXml(o, s);
+
+ case "application/json":
+ case "text/json":
+ return (r, o, s) => ServiceStackHost.Instance.SerializeToJson(o, s);
+ }
+
+ return null;
+ }
+
+ public Func<Type, Stream, object> GetStreamDeserializer(string contentType)
+ {
+ switch (GetRealContentType(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;
+
+ case "application/json":
+ case "text/json":
+ return ServiceStackHost.Instance.DeserializeJson;
+ }
+
+ return null;
+ }
+
+ private static string GetRealContentType(string contentType)
+ {
+ return contentType == null
+ ? null
+ : contentType.Split(';')[0].ToLower().Trim();
+ }
+
+ }
+} \ No newline at end of file
diff --git a/ServiceStack/Host/HttpResponseStreamWrapper.cs b/ServiceStack/Host/HttpResponseStreamWrapper.cs
new file mode 100644
index 0000000000..33038da722
--- /dev/null
+++ b/ServiceStack/Host/HttpResponseStreamWrapper.cs
@@ -0,0 +1,95 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Text;
+using MediaBrowser.Model.Services;
+
+namespace ServiceStack.Host
+{
+ public class HttpResponseStreamWrapper : IHttpResponse
+ {
+ private static readonly UTF8Encoding UTF8EncodingWithoutBom = new UTF8Encoding(false);
+
+ public HttpResponseStreamWrapper(Stream stream, IRequest request)
+ {
+ this.OutputStream = stream;
+ this.Request = request;
+ this.Headers = new Dictionary<string, string>();
+ this.Items = new Dictionary<string, object>();
+ }
+
+ public Dictionary<string, string> Headers { get; set; }
+
+ public object OriginalResponse
+ {
+ get { return null; }
+ }
+
+ public IRequest Request { get; private set; }
+
+ public int StatusCode { set; get; }
+ public string StatusDescription { set; get; }
+ public string ContentType { get; set; }
+
+ public void AddHeader(string name, string value)
+ {
+ this.Headers[name] = value;
+ }
+
+ public string GetHeader(string name)
+ {
+ return this.Headers[name];
+ }
+
+ public void Redirect(string url)
+ {
+ this.Headers["Location"] = url;
+ }
+
+ public Stream OutputStream { get; private set; }
+
+ public object Dto { get; set; }
+
+ public void Write(string text)
+ {
+ var bytes = UTF8EncodingWithoutBom.GetBytes(text);
+ OutputStream.Write(bytes, 0, bytes.Length);
+ }
+
+ public bool UseBufferedStream { get; set; }
+
+ public void Close()
+ {
+ if (IsClosed) return;
+
+ OutputStream.Dispose();
+ IsClosed = true;
+ }
+
+ public void End()
+ {
+ Close();
+ }
+
+ public void Flush()
+ {
+ OutputStream.Flush();
+ }
+
+ public bool IsClosed { get; private set; }
+
+ public void SetContentLength(long contentLength) {}
+
+ public bool KeepAlive { get; set; }
+
+ public Dictionary<string, object> Items { get; private set; }
+
+ public void SetCookie(Cookie cookie)
+ {
+ }
+
+ public void ClearCookies()
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/ServiceStack/Host/RestHandler.cs b/ServiceStack/Host/RestHandler.cs
new file mode 100644
index 0000000000..5c360d1503
--- /dev/null
+++ b/ServiceStack/Host/RestHandler.cs
@@ -0,0 +1,200 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Services;
+
+namespace ServiceStack.Host
+{
+ public class RestHandler
+ {
+ public string RequestName { get; set; }
+
+ public async Task<object> HandleResponseAsync(object response)
+ {
+ var taskResponse = response as Task;
+
+ if (taskResponse == null)
+ {
+ return response;
+ }
+
+ await taskResponse.ConfigureAwait(false);
+
+ var taskResult = ServiceStackHost.Instance.GetTaskResult(taskResponse, RequestName);
+
+ var taskResults = taskResult as Task[];
+
+ if (taskResults == null)
+ {
+ var subTask = taskResult as Task;
+ if (subTask != null)
+ taskResult = ServiceStackHost.Instance.GetTaskResult(subTask, RequestName);
+
+ return taskResult;
+ }
+
+ if (taskResults.Length == 0)
+ {
+ return new object[] { };
+ }
+
+ var firstResponse = ServiceStackHost.Instance.GetTaskResult(taskResults[0], RequestName);
+ var batchedResponses = firstResponse != null
+ ? (object[])Array.CreateInstance(firstResponse.GetType(), taskResults.Length)
+ : new object[taskResults.Length];
+ batchedResponses[0] = firstResponse;
+ for (var i = 1; i < taskResults.Length; i++)
+ {
+ batchedResponses[i] = ServiceStackHost.Instance.GetTaskResult(taskResults[i], RequestName);
+ }
+ return batchedResponses;
+ }
+
+ protected static object CreateContentTypeRequest(IRequest httpReq, Type requestType, string contentType)
+ {
+ if (!string.IsNullOrEmpty(contentType) && httpReq.ContentLength > 0)
+ {
+ var deserializer = ContentTypes.Instance.GetStreamDeserializer(contentType);
+ if (deserializer != null)
+ {
+ return deserializer(requestType, httpReq.InputStream);
+ }
+ }
+ return ServiceStackHost.Instance.CreateInstance(requestType); //Return an empty DTO, even for empty request bodies
+ }
+
+ protected static object GetCustomRequestFromBinder(IRequest httpReq, Type requestType)
+ {
+ Func<IRequest, object> requestFactoryFn;
+ ServiceStackHost.Instance.ServiceController.RequestTypeFactoryMap.TryGetValue(
+ requestType, out requestFactoryFn);
+
+ return requestFactoryFn != null ? requestFactoryFn(httpReq) : null;
+ }
+
+ public static RestPath FindMatchingRestPath(string httpMethod, string pathInfo, out string contentType)
+ {
+ pathInfo = GetSanitizedPathInfo(pathInfo, out contentType);
+
+ return ServiceStackHost.Instance.ServiceController.GetRestPathForRequest(httpMethod, pathInfo);
+ }
+
+ public static string GetSanitizedPathInfo(string pathInfo, out string contentType)
+ {
+ contentType = null;
+ var pos = pathInfo.LastIndexOf('.');
+ if (pos >= 0)
+ {
+ var format = pathInfo.Substring(pos + 1);
+ contentType = GetFormatContentType(format);
+ if (contentType != null)
+ {
+ pathInfo = pathInfo.Substring(0, pos);
+ }
+ }
+ return pathInfo;
+ }
+
+ private static string GetFormatContentType(string format)
+ {
+ //built-in formats
+ if (format == "json")
+ return "application/json";
+ if (format == "xml")
+ return "application/xml";
+
+ return null;
+ }
+
+ public RestPath GetRestPath(string httpMethod, string pathInfo)
+ {
+ if (this.RestPath == null)
+ {
+ string contentType;
+ this.RestPath = FindMatchingRestPath(httpMethod, pathInfo, out contentType);
+
+ if (contentType != null)
+ ResponseContentType = contentType;
+ }
+ return this.RestPath;
+ }
+
+ public RestPath RestPath { get; set; }
+
+ // Set from SSHHF.GetHandlerForPathInfo()
+ public string ResponseContentType { get; set; }
+
+ public async Task ProcessRequestAsync(IRequest httpReq, IResponse httpRes, string operationName)
+ {
+ var appHost = ServiceStackHost.Instance;
+
+ var restPath = GetRestPath(httpReq.Verb, httpReq.PathInfo);
+ if (restPath == null)
+ {
+ throw new NotSupportedException("No RestPath found for: " + httpReq.Verb + " " + httpReq.PathInfo);
+ }
+ httpReq.SetRoute(restPath);
+
+ if (ResponseContentType != null)
+ httpReq.ResponseContentType = ResponseContentType;
+
+ var request = httpReq.Dto = CreateRequest(httpReq, restPath);
+
+ if (appHost.ApplyRequestFilters(httpReq, httpRes, request))
+ return;
+
+ var rawResponse = await ServiceStackHost.Instance.ServiceController.Execute(request, httpReq).ConfigureAwait(false);
+
+ if (httpRes.IsClosed)
+ return;
+
+ var response = await HandleResponseAsync(rawResponse).ConfigureAwait(false);
+
+ if (appHost.ApplyResponseFilters(httpReq, httpRes, response))
+ return;
+
+ await httpRes.WriteToResponse(httpReq, response).ConfigureAwait(false);
+ }
+
+ public static object CreateRequest(IRequest httpReq, RestPath restPath)
+ {
+ var dtoFromBinder = GetCustomRequestFromBinder(httpReq, restPath.RequestType);
+ if (dtoFromBinder != null)
+ return dtoFromBinder;
+
+ var requestParams = httpReq.GetFlattenedRequestParams();
+ return CreateRequest(httpReq, restPath, requestParams);
+ }
+
+ public static object CreateRequest(IRequest httpReq, RestPath restPath, Dictionary<string, string> requestParams)
+ {
+ var requestDto = CreateContentTypeRequest(httpReq, restPath.RequestType, httpReq.ContentType);
+
+ return CreateRequest(httpReq, restPath, requestParams, requestDto);
+ }
+
+ public static object CreateRequest(IRequest httpReq, RestPath restPath, Dictionary<string, string> requestParams, object requestDto)
+ {
+ string contentType;
+ var pathInfo = !restPath.IsWildCardPath
+ ? GetSanitizedPathInfo(httpReq.PathInfo, out contentType)
+ : httpReq.PathInfo;
+
+ return restPath.CreateRequest(pathInfo, requestParams, requestDto);
+ }
+
+ /// <summary>
+ /// Used in Unit tests
+ /// </summary>
+ /// <returns></returns>
+ public object CreateRequest(IRequest httpReq, string operationName)
+ {
+ if (this.RestPath == null)
+ throw new ArgumentNullException("No RestPath found");
+
+ return CreateRequest(httpReq, this.RestPath);
+ }
+ }
+
+}
diff --git a/ServiceStack/Host/RestPath.cs b/ServiceStack/Host/RestPath.cs
new file mode 100644
index 0000000000..7222578a98
--- /dev/null
+++ b/ServiceStack/Host/RestPath.cs
@@ -0,0 +1,443 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using ServiceStack.Serialization;
+
+namespace ServiceStack.Host
+{
+ public class RestPath
+ {
+ private const string WildCard = "*";
+ private const char WildCardChar = '*';
+ private const string PathSeperator = "/";
+ private const char PathSeperatorChar = '/';
+ private const char ComponentSeperator = '.';
+ private const string VariablePrefix = "{";
+
+ 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;
+
+ private readonly string[] variablesNames;
+
+ private readonly bool[] isWildcard;
+ private readonly int wildcardCount = 0;
+
+ public int VariableArgsCount { get; set; }
+
+ /// <summary>
+ /// The number of segments separated by '/' determinable by path.Split('/').Length
+ /// e.g. /path/to/here.ext == 3
+ /// </summary>
+ public int PathComponentsCount { get; set; }
+
+ /// <summary>
+ /// The total number of segments after subparts have been exploded ('.')
+ /// e.g. /path/to/here.ext == 4
+ /// </summary>
+ public int TotalComponentsCount { get; set; }
+
+ public string[] Verbs
+ {
+ get
+ {
+ return allowsAllVerbs
+ ? new[] { ActionContext.AnyAction }
+ : AllowedVerbs.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
+ }
+ }
+
+ public Type RequestType { get; private set; }
+
+ public string Path { get { return this.restPath; } }
+
+ 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;
+ }
+
+ public static IEnumerable<string> GetFirstMatchHashKeys(string[] pathPartsForMatching)
+ {
+ var hashPrefix = pathPartsForMatching.Length + PathSeperator;
+ return GetPotentialMatchesWithPrefix(hashPrefix, pathPartsForMatching);
+ }
+
+ public static IEnumerable<string> GetFirstMatchWildCardHashKeys(string[] pathPartsForMatching)
+ {
+ const string hashPrefix = WildCard + PathSeperator;
+ return GetPotentialMatchesWithPrefix(hashPrefix, pathPartsForMatching);
+ }
+
+ private static IEnumerable<string> GetPotentialMatchesWithPrefix(string hashPrefix, string[] pathPartsForMatching)
+ {
+ foreach (var part in pathPartsForMatching)
+ {
+ yield return hashPrefix + part;
+ var subParts = part.Split(ComponentSeperator);
+ if (subParts.Length == 1) continue;
+
+ foreach (var subPart in subParts)
+ {
+ yield return hashPrefix + subPart;
+ }
+ }
+ }
+
+ public RestPath(Type requestType, string path, string verbs, string summary = null, string notes = null)
+ {
+ this.RequestType = requestType;
+ this.Summary = summary;
+ this.Notes = notes;
+ this.restPath = path;
+
+ this.allowsAllVerbs = verbs == null || verbs == WildCard;
+ if (!this.allowsAllVerbs)
+ {
+ this.allowedVerbs = verbs.ToUpper();
+ }
+
+ var componentsList = new List<string>();
+
+ //We only split on '.' if the restPath has them. Allows for /{action}.{type}
+ var hasSeparators = new List<bool>();
+ foreach (var component in this.restPath.Split(PathSeperatorChar))
+ {
+ if (string.IsNullOrEmpty(component)) continue;
+
+ if (component.Contains(VariablePrefix)
+ && component.IndexOf(ComponentSeperator) != -1)
+ {
+ hasSeparators.Add(true);
+ componentsList.AddRange(component.Split(ComponentSeperator));
+ }
+ else
+ {
+ hasSeparators.Add(false);
+ componentsList.Add(component);
+ }
+ }
+
+ var components = componentsList.ToArray();
+ this.TotalComponentsCount = components.Length;
+
+ this.literalsToMatch = new string[this.TotalComponentsCount];
+ this.variablesNames = new string[this.TotalComponentsCount];
+ this.isWildcard = new bool[this.TotalComponentsCount];
+ this.componentsWithSeparators = hasSeparators.ToArray();
+ this.PathComponentsCount = this.componentsWithSeparators.Length;
+ string firstLiteralMatch = null;
+
+ var sbHashKey = new StringBuilder();
+ for (var i = 0; i < components.Length; i++)
+ {
+ var component = components[i];
+
+ if (component.StartsWith(VariablePrefix))
+ {
+ var variableName = component.Substring(1, component.Length - 2);
+ if (variableName[variableName.Length - 1] == WildCardChar)
+ {
+ this.isWildcard[i] = true;
+ variableName = variableName.Substring(0, variableName.Length - 1);
+ }
+ this.variablesNames[i] = variableName;
+ this.VariableArgsCount++;
+ }
+ else
+ {
+ this.literalsToMatch[i] = component.ToLower();
+ sbHashKey.Append(i + PathSeperatorChar.ToString() + this.literalsToMatch);
+
+ if (firstLiteralMatch == null)
+ {
+ firstLiteralMatch = this.literalsToMatch[i];
+ }
+ }
+ }
+
+ for (var i = 0; i < components.Length - 1; i++)
+ {
+ if (!this.isWildcard[i]) continue;
+ if (this.literalsToMatch[i + 1] == null)
+ {
+ throw new ArgumentException(
+ "A wildcard path component must be at the end of the path or followed by a literal path component.");
+ }
+ }
+
+ this.wildcardCount = this.isWildcard.Count(x => x);
+ this.IsWildCardPath = this.wildcardCount > 0;
+
+ this.FirstMatchHashKey = !this.IsWildCardPath
+ ? this.PathComponentsCount + PathSeperator + firstLiteralMatch
+ : WildCardChar + PathSeperator + firstLiteralMatch;
+
+ this.IsValid = sbHashKey.Length > 0;
+ this.UniqueMatchHashKey = sbHashKey.ToString();
+
+ this.typeDeserializer = new StringMapTypeDeserializer(this.RequestType);
+ RegisterCaseInsenstivePropertyNameMappings();
+ }
+
+ private void RegisterCaseInsenstivePropertyNameMappings()
+ {
+ foreach (var propertyInfo in RequestType.GetSerializableProperties())
+ {
+ var propertyName = propertyInfo.Name;
+ propertyNamesMap.Add(propertyName.ToLower(), propertyName);
+ }
+ }
+
+ 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>();
+
+ public static Func<RestPath, string, string[], int> CalculateMatchScore { get; set; }
+
+ public int MatchScore(string httpMethod, string[] withPathInfoParts)
+ {
+ if (CalculateMatchScore != null)
+ return CalculateMatchScore(this, httpMethod, withPathInfoParts);
+
+ int wildcardMatchCount;
+ var isMatch = IsMatch(httpMethod, withPathInfoParts, out wildcardMatchCount);
+ if (!isMatch) return -1;
+
+ var score = 0;
+
+ //Routes with least wildcard matches get the highest score
+ score += Math.Max((100 - wildcardMatchCount), 1) * 1000;
+
+ //Routes with less variable (and more literal) matches
+ score += Math.Max((10 - VariableArgsCount), 1) * 100;
+
+ //Exact verb match is better than ANY
+ var exactVerb = httpMethod == AllowedVerbs;
+ score += exactVerb ? 10 : 1;
+
+ return score;
+ }
+
+ /// <summary>
+ /// For performance withPathInfoParts should already be a lower case string
+ /// to minimize redundant matching operations.
+ /// </summary>
+ /// <param name="httpMethod"></param>
+ /// <param name="withPathInfoParts"></param>
+ /// <param name="wildcardMatchCount"></param>
+ /// <returns></returns>
+ public bool IsMatch(string httpMethod, string[] withPathInfoParts, out int wildcardMatchCount)
+ {
+ wildcardMatchCount = 0;
+
+ if (withPathInfoParts.Length != this.PathComponentsCount && !this.IsWildCardPath) return false;
+ if (!this.allowsAllVerbs && !this.allowedVerbs.Contains(httpMethod.ToUpper())) return false;
+
+ if (!ExplodeComponents(ref withPathInfoParts)) return false;
+ if (this.TotalComponentsCount != withPathInfoParts.Length && !this.IsWildCardPath) return false;
+
+ int pathIx = 0;
+ for (var i = 0; i < this.TotalComponentsCount; i++)
+ {
+ if (this.isWildcard[i])
+ {
+ if (i < this.TotalComponentsCount - 1)
+ {
+ // Continue to consume up until a match with the next literal
+ while (pathIx < withPathInfoParts.Length && withPathInfoParts[pathIx] != this.literalsToMatch[i + 1])
+ {
+ pathIx++;
+ wildcardMatchCount++;
+ }
+
+ // Ensure there are still enough parts left to match the remainder
+ if ((withPathInfoParts.Length - pathIx) < (this.TotalComponentsCount - i - 1))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ // A wildcard at the end matches the remainder of path
+ wildcardMatchCount += withPathInfoParts.Length - pathIx;
+ pathIx = withPathInfoParts.Length;
+ }
+ }
+ else
+ {
+ var literalToMatch = this.literalsToMatch[i];
+ if (literalToMatch == null)
+ {
+ // Matching an ordinary (non-wildcard) variable consumes a single part
+ pathIx++;
+ continue;
+ }
+
+ if (withPathInfoParts.Length <= pathIx || withPathInfoParts[pathIx] != literalToMatch) return false;
+ pathIx++;
+ }
+ }
+
+ return pathIx == withPathInfoParts.Length;
+ }
+
+ private bool ExplodeComponents(ref string[] withPathInfoParts)
+ {
+ var totalComponents = new List<string>();
+ for (var i = 0; i < withPathInfoParts.Length; i++)
+ {
+ var component = withPathInfoParts[i];
+ if (string.IsNullOrEmpty(component)) continue;
+
+ if (this.PathComponentsCount != this.TotalComponentsCount
+ && this.componentsWithSeparators[i])
+ {
+ var subComponents = component.Split(ComponentSeperator);
+ if (subComponents.Length < 2) return false;
+ totalComponents.AddRange(subComponents);
+ }
+ else
+ {
+ totalComponents.Add(component);
+ }
+ }
+
+ withPathInfoParts = totalComponents.ToArray();
+ return true;
+ }
+
+ public object CreateRequest(string pathInfo, Dictionary<string, string> queryStringAndFormData, object fromInstance)
+ {
+ var requestComponents = pathInfo.Split(PathSeperatorChar)
+ .Where(x => !string.IsNullOrEmpty(x)).ToArray();
+
+ ExplodeComponents(ref requestComponents);
+
+ if (requestComponents.Length != this.TotalComponentsCount)
+ {
+ var isValidWildCardPath = this.IsWildCardPath
+ && requestComponents.Length >= this.TotalComponentsCount - this.wildcardCount;
+
+ if (!isValidWildCardPath)
+ throw new ArgumentException(string.Format(
+ "Path Mismatch: Request Path '{0}' has invalid number of components compared to: '{1}'",
+ pathInfo, this.restPath));
+ }
+
+ var requestKeyValuesMap = new Dictionary<string, string>();
+ var pathIx = 0;
+ for (var i = 0; i < this.TotalComponentsCount; i++)
+ {
+ var variableName = this.variablesNames[i];
+ if (variableName == null)
+ {
+ pathIx++;
+ continue;
+ }
+
+ string propertyNameOnRequest;
+ if (!this.propertyNamesMap.TryGetValue(variableName.ToLower(), out propertyNameOnRequest))
+ {
+ if (string.Equals("ignore", variableName, StringComparison.OrdinalIgnoreCase))
+ {
+ pathIx++;
+ continue;
+ }
+
+ throw new ArgumentException("Could not find property "
+ + variableName + " on " + RequestType.GetOperationName());
+ }
+
+ var value = requestComponents.Length > pathIx ? requestComponents[pathIx] : null; //wildcard has arg mismatch
+ if (value != null && this.isWildcard[i])
+ {
+ if (i == this.TotalComponentsCount - 1)
+ {
+ // Wildcard at end of path definition consumes all the rest
+ var sb = new StringBuilder();
+ sb.Append(value);
+ for (var j = pathIx + 1; j < requestComponents.Length; j++)
+ {
+ sb.Append(PathSeperatorChar + requestComponents[j]);
+ }
+ value = sb.ToString();
+ }
+ else
+ {
+ // Wildcard in middle of path definition consumes up until it
+ // hits a match for the next element in the definition (which must be a literal)
+ // It may consume 0 or more path parts
+ var stopLiteral = i == this.TotalComponentsCount - 1 ? null : this.literalsToMatch[i + 1];
+ if (!string.Equals(requestComponents[pathIx], stopLiteral, StringComparison.OrdinalIgnoreCase))
+ {
+ var sb = new StringBuilder();
+ sb.Append(value);
+ pathIx++;
+ while (!string.Equals(requestComponents[pathIx], stopLiteral, StringComparison.OrdinalIgnoreCase))
+ {
+ sb.Append(PathSeperatorChar + requestComponents[pathIx++]);
+ }
+ value = sb.ToString();
+ }
+ else
+ {
+ value = null;
+ }
+ }
+ }
+ else
+ {
+ // Variable consumes single path item
+ pathIx++;
+ }
+
+ requestKeyValuesMap[propertyNameOnRequest] = value;
+ }
+
+ if (queryStringAndFormData != null)
+ {
+ //Query String and form data can override variable path matches
+ //path variables < query string < form data
+ foreach (var name in queryStringAndFormData)
+ {
+ requestKeyValuesMap[name.Key] = name.Value;
+ }
+ }
+
+ return this.typeDeserializer.PopulateFromMap(fromInstance, requestKeyValuesMap);
+ }
+
+ public override int GetHashCode()
+ {
+ return UniqueMatchHashKey.GetHashCode();
+ }
+ }
+} \ No newline at end of file
diff --git a/ServiceStack/Host/ServiceController.cs b/ServiceStack/Host/ServiceController.cs
new file mode 100644
index 0000000000..703f06365a
--- /dev/null
+++ b/ServiceStack/Host/ServiceController.cs
@@ -0,0 +1,220 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Services;
+
+namespace ServiceStack.Host
+{
+ public delegate Task<object> InstanceExecFn(IRequest requestContext, object intance, object request);
+ public delegate object ActionInvokerFn(object intance, object request);
+ public delegate void VoidActionInvokerFn(object intance, object request);
+
+ public class ServiceController
+ {
+ private readonly Func<IEnumerable<Type>> _resolveServicesFn;
+
+ public ServiceController(Func<IEnumerable<Type>> resolveServicesFn)
+ {
+ _resolveServicesFn = resolveServicesFn;
+ this.RequestTypeFactoryMap = new Dictionary<Type, Func<IRequest, object>>();
+ }
+
+ public Dictionary<Type, Func<IRequest, object>> RequestTypeFactoryMap { get; set; }
+
+ public void Init()
+ {
+ foreach (var serviceType in _resolveServicesFn())
+ {
+ RegisterService(serviceType);
+ }
+ }
+
+ private Type[] GetGenericArguments(Type type)
+ {
+ return type.GetTypeInfo().IsGenericTypeDefinition
+ ? type.GetTypeInfo().GenericTypeParameters
+ : type.GetTypeInfo().GenericTypeArguments;
+ }
+
+ public void RegisterService(Type serviceType)
+ {
+ var processedReqs = new HashSet<Type>();
+
+ var actions = ServiceExecGeneral.Reset(serviceType);
+
+ var requiresRequestStreamTypeInfo = typeof(IRequiresRequestStream).GetTypeInfo();
+
+ var appHost = ServiceStackHost.Instance;
+ foreach (var mi in serviceType.GetActions())
+ {
+ var requestType = mi.GetParameters()[0].ParameterType;
+ if (processedReqs.Contains(requestType)) continue;
+ processedReqs.Add(requestType);
+
+ ServiceExecGeneral.CreateServiceRunnersFor(requestType, actions);
+
+ var returnMarker = requestType.GetTypeWithGenericTypeDefinitionOf(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);
+
+ appHost.Metadata.Add(serviceType, requestType, responseType);
+
+ if (requiresRequestStreamTypeInfo.IsAssignableFrom(requestType.GetTypeInfo()))
+ {
+ this.RequestTypeFactoryMap[requestType] = req =>
+ {
+ var restPath = req.GetRoute();
+ var request = RestHandler.CreateRequest(req, restPath, req.GetRequestParams(), ServiceStackHost.Instance.CreateInstance(requestType));
+
+ var rawReq = (IRequiresRequestStream)request;
+ rawReq.RequestStream = req.InputStream;
+ return rawReq;
+ };
+ }
+ }
+ }
+
+ public readonly Dictionary<string, List<RestPath>> RestPathMap = new Dictionary<string, List<RestPath>>();
+
+ public void RegisterRestPaths(Type requestType)
+ {
+ var appHost = ServiceStackHost.Instance;
+ var attrs = appHost.GetRouteAttributes(requestType);
+ foreach (MediaBrowser.Model.Services.RouteAttribute attr in attrs)
+ {
+ var restPath = new RestPath(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.GetOperationName()));
+
+ RegisterRestPath(restPath);
+ }
+ }
+
+ private static readonly char[] InvalidRouteChars = new[] { '?', '&' };
+
+ public void RegisterRestPath(RestPath restPath)
+ {
+ if (!restPath.Path.StartsWith("/"))
+ throw new ArgumentException(string.Format("Route '{0}' on '{1}' must start with a '/'", restPath.Path, restPath.RequestType.GetOperationName()));
+ 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.GetOperationName()));
+
+ List<RestPath> pathsAtFirstMatch;
+ if (!RestPathMap.TryGetValue(restPath.FirstMatchHashKey, out pathsAtFirstMatch))
+ {
+ pathsAtFirstMatch = new List<RestPath>();
+ RestPathMap[restPath.FirstMatchHashKey] = pathsAtFirstMatch;
+ }
+ pathsAtFirstMatch.Add(restPath);
+ }
+
+ public void AfterInit()
+ {
+ var appHost = ServiceStackHost.Instance;
+
+ //Register any routes configured on Metadata.Routes
+ foreach (var restPath in appHost.RestPaths)
+ {
+ RegisterRestPath(restPath);
+ }
+
+ //Sync the RestPaths collections
+ appHost.RestPaths.Clear();
+ appHost.RestPaths.AddRange(RestPathMap.Values.SelectMany(x => x));
+ }
+
+ public RestPath GetRestPathForRequest(string httpMethod, string pathInfo)
+ {
+ var matchUsingPathParts = RestPath.GetPathPartsForMatching(pathInfo);
+
+ List<RestPath> firstMatches;
+
+ var yieldedHashMatches = RestPath.GetFirstMatchHashKeys(matchUsingPathParts);
+ foreach (var potentialHashMatch in yieldedHashMatches)
+ {
+ if (!this.RestPathMap.TryGetValue(potentialHashMatch, out firstMatches)) continue;
+
+ var bestScore = -1;
+ foreach (var restPath in firstMatches)
+ {
+ var score = restPath.MatchScore(httpMethod, matchUsingPathParts);
+ if (score > bestScore) bestScore = score;
+ }
+ if (bestScore > 0)
+ {
+ foreach (var restPath in firstMatches)
+ {
+ if (bestScore == restPath.MatchScore(httpMethod, matchUsingPathParts))
+ return restPath;
+ }
+ }
+ }
+
+ var yieldedWildcardMatches = RestPath.GetFirstMatchWildCardHashKeys(matchUsingPathParts);
+ foreach (var potentialHashMatch in yieldedWildcardMatches)
+ {
+ if (!this.RestPathMap.TryGetValue(potentialHashMatch, out firstMatches)) continue;
+
+ var bestScore = -1;
+ foreach (var restPath in firstMatches)
+ {
+ var score = restPath.MatchScore(httpMethod, matchUsingPathParts);
+ if (score > bestScore) bestScore = score;
+ }
+ if (bestScore > 0)
+ {
+ foreach (var restPath in firstMatches)
+ {
+ if (bestScore == restPath.MatchScore(httpMethod, matchUsingPathParts))
+ return restPath;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public async Task<object> Execute(object requestDto, IRequest req)
+ {
+ req.Dto = requestDto;
+ var requestType = requestDto.GetType();
+ req.OperationName = requestType.Name;
+
+ var serviceType = ServiceStackHost.Instance.Metadata.GetServiceTypeByRequest(requestType);
+
+ var service = ServiceStackHost.Instance.CreateInstance(serviceType);
+
+ //var service = typeFactory.CreateInstance(serviceType);
+
+ var serviceRequiresContext = service as IRequiresRequest;
+ if (serviceRequiresContext != null)
+ {
+ serviceRequiresContext.Request = req;
+ }
+
+ if (req.Dto == null) // Don't override existing batched DTO[]
+ req.Dto = requestDto;
+
+ //Executes the service and returns the result
+ var response = await ServiceExecGeneral.Execute(serviceType, req, service, requestDto, requestType.GetOperationName()).ConfigureAwait(false);
+
+ if (req.Response.Dto == null)
+ req.Response.Dto = response;
+
+ return response;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/ServiceStack/Host/ServiceExec.cs b/ServiceStack/Host/ServiceExec.cs
new file mode 100644
index 0000000000..cb501a3ad3
--- /dev/null
+++ b/ServiceStack/Host/ServiceExec.cs
@@ -0,0 +1,156 @@
+//Copyright (c) Service Stack LLC. All Rights Reserved.
+//License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Services;
+
+namespace ServiceStack.Host
+{
+ public static class ServiceExecExtensions
+ {
+ public static IEnumerable<MethodInfo> GetActions(this Type serviceType)
+ {
+ foreach (var mi in serviceType.GetRuntimeMethods().Where(i => i.IsPublic && !i.IsStatic))
+ {
+ if (mi.GetParameters().Length != 1)
+ continue;
+
+ var actionName = mi.Name.ToUpper();
+ if (!HttpMethods.AllVerbs.Contains(actionName) && actionName != ActionContext.AnyAction)
+ continue;
+
+ yield return mi;
+ }
+ }
+ }
+
+ internal static class ServiceExecGeneral
+ {
+ public static Dictionary<string, ActionContext> execMap = new Dictionary<string, ActionContext>();
+
+ public static void CreateServiceRunnersFor(Type requestType, List<ActionContext> actions)
+ {
+ foreach (var actionCtx in actions)
+ {
+ if (execMap.ContainsKey(actionCtx.Id)) continue;
+
+ execMap[actionCtx.Id] = actionCtx;
+ }
+ }
+
+ public static async Task<object> Execute(Type serviceType, IRequest request, object instance, object requestDto, string requestName)
+ {
+ var actionName = request.Verb
+ ?? HttpMethods.Post; //MQ Services
+
+ ActionContext actionContext;
+ if (ServiceExecGeneral.execMap.TryGetValue(ActionContext.Key(serviceType, actionName, requestName), out actionContext)
+ || ServiceExecGeneral.execMap.TryGetValue(ActionContext.AnyKey(serviceType, requestName), out actionContext))
+ {
+ if (actionContext.RequestFilters != null)
+ {
+ foreach (var requestFilter in actionContext.RequestFilters)
+ {
+ requestFilter.RequestFilter(request, request.Response, requestDto);
+ if (request.Response.IsClosed) return null;
+ }
+ }
+
+ var response = actionContext.ServiceAction(instance, requestDto);
+
+ var taskResponse = response as Task;
+ if (taskResponse != null)
+ {
+ await taskResponse.ConfigureAwait(false);
+ response = ServiceStackHost.Instance.GetTaskResult(taskResponse, requestName);
+ }
+
+ return response;
+ }
+
+ var expectedMethodName = actionName.Substring(0, 1) + actionName.Substring(1).ToLower();
+ throw new NotImplementedException(string.Format("Could not find method named {1}({0}) or Any({0}) on Service {2}", requestDto.GetType().GetOperationName(), expectedMethodName, serviceType.GetOperationName()));
+ }
+
+ public static List<ActionContext> Reset(Type serviceType)
+ {
+ var actions = new List<ActionContext>();
+
+ foreach (var mi in serviceType.GetActions())
+ {
+ var actionName = mi.Name.ToUpper();
+ var args = mi.GetParameters();
+
+ var requestType = args[0].ParameterType;
+ var actionCtx = new ActionContext
+ {
+ Id = ActionContext.Key(serviceType, actionName, requestType.GetOperationName())
+ };
+
+ try
+ {
+ actionCtx.ServiceAction = CreateExecFn(serviceType, requestType, mi);
+ }
+ catch
+ {
+ //Potential problems with MONO, using reflection for fallback
+ actionCtx.ServiceAction = (service, request) =>
+ mi.Invoke(service, new[] { request });
+ }
+
+ var reqFilters = new List<IHasRequestFilter>();
+
+ foreach (var attr in mi.GetCustomAttributes(true))
+ {
+ var hasReqFilter = attr as IHasRequestFilter;
+
+ if (hasReqFilter != null)
+ reqFilters.Add(hasReqFilter);
+ }
+
+ if (reqFilters.Count > 0)
+ actionCtx.RequestFilters = reqFilters.OrderBy(i => i.Priority).ToArray();
+
+ actions.Add(actionCtx);
+ }
+
+ return actions;
+ }
+
+ private static ActionInvokerFn CreateExecFn(Type serviceType, Type requestType, MethodInfo mi)
+ {
+ var serviceParam = Expression.Parameter(typeof(object), "serviceObj");
+ var serviceStrong = Expression.Convert(serviceParam, serviceType);
+
+ var requestDtoParam = Expression.Parameter(typeof(object), "requestDto");
+ var requestDtoStrong = Expression.Convert(requestDtoParam, requestType);
+
+ Expression callExecute = Expression.Call(
+ serviceStrong, mi, requestDtoStrong);
+
+ if (mi.ReturnType != typeof(void))
+ {
+ var executeFunc = Expression.Lambda<ActionInvokerFn>
+ (callExecute, serviceParam, requestDtoParam).Compile();
+
+ return executeFunc;
+ }
+ else
+ {
+ var executeFunc = Expression.Lambda<VoidActionInvokerFn>
+ (callExecute, serviceParam, requestDtoParam).Compile();
+
+ return (service, request) =>
+ {
+ executeFunc(service, request);
+ return null;
+ };
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/ServiceStack/Host/ServiceMetadata.cs b/ServiceStack/Host/ServiceMetadata.cs
new file mode 100644
index 0000000000..240e6f32d4
--- /dev/null
+++ b/ServiceStack/Host/ServiceMetadata.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Host
+{
+ public class ServiceMetadata
+ {
+ public ServiceMetadata()
+ {
+ this.OperationsMap = new Dictionary<Type, Type>();
+ }
+
+ public Dictionary<Type, Type> OperationsMap { get; protected set; }
+
+ public void Add(Type serviceType, Type requestType, Type responseType)
+ {
+ this.OperationsMap[requestType] = serviceType;
+ }
+
+ public Type GetServiceTypeByRequest(Type requestType)
+ {
+ Type serviceType;
+ OperationsMap.TryGetValue(requestType, out serviceType);
+ return serviceType;
+ }
+ }
+}
diff --git a/ServiceStack/HttpHandlerFactory.cs b/ServiceStack/HttpHandlerFactory.cs
new file mode 100644
index 0000000000..d48bfeb5f8
--- /dev/null
+++ b/ServiceStack/HttpHandlerFactory.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MediaBrowser.Model.Services;
+using ServiceStack.Host;
+
+namespace ServiceStack
+{
+ public class HttpHandlerFactory
+ {
+ // Entry point for HttpListener
+ public static RestHandler GetHandler(IHttpRequest httpReq)
+ {
+ var pathInfo = httpReq.PathInfo;
+
+ var pathParts = pathInfo.TrimStart('/').Split('/');
+ if (pathParts.Length == 0) return null;
+
+ string contentType;
+ var restPath = RestHandler.FindMatchingRestPath(httpReq.HttpMethod, pathInfo, out contentType);
+ if (restPath != null)
+ return new RestHandler { RestPath = restPath, RequestName = restPath.RequestType.GetOperationName(), ResponseContentType = contentType };
+
+ return null;
+ }
+ }
+} \ No newline at end of file
diff --git a/ServiceStack/HttpRequestExtensions.cs b/ServiceStack/HttpRequestExtensions.cs
new file mode 100644
index 0000000000..c34d626016
--- /dev/null
+++ b/ServiceStack/HttpRequestExtensions.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using MediaBrowser.Model.Services;
+using ServiceStack.Host;
+
+namespace ServiceStack
+{
+ public static class HttpRequestExtensions
+ {
+ /**
+ *
+ Input: http://localhost:96/Cambia3/Temp/Test.aspx/path/info?q=item#fragment
+
+ Some HttpRequest path and URL properties:
+ Request.ApplicationPath: /Cambia3
+ Request.CurrentExecutionFilePath: /Cambia3/Temp/Test.aspx
+ Request.FilePath: /Cambia3/Temp/Test.aspx
+ Request.Path: /Cambia3/Temp/Test.aspx/path/info
+ Request.PathInfo: /path/info
+ Request.PhysicalApplicationPath: D:\Inetpub\wwwroot\CambiaWeb\Cambia3\
+ Request.QueryString: /Cambia3/Temp/Test.aspx/path/info?query=arg
+ Request.Url.AbsolutePath: /Cambia3/Temp/Test.aspx/path/info
+ Request.Url.AbsoluteUri: http://localhost:96/Cambia3/Temp/Test.aspx/path/info?query=arg
+ Request.Url.Fragment:
+ Request.Url.Host: localhost
+ Request.Url.LocalPath: /Cambia3/Temp/Test.aspx/path/info
+ Request.Url.PathAndQuery: /Cambia3/Temp/Test.aspx/path/info?query=arg
+ Request.Url.Port: 96
+ Request.Url.Query: ?query=arg
+ Request.Url.Scheme: http
+ Request.Url.Segments: /
+ Cambia3/
+ Temp/
+ Test.aspx/
+ path/
+ info
+ * */
+
+ /// <summary>
+ /// Duplicate Params are given a unique key by appending a #1 suffix
+ /// </summary>
+ public static Dictionary<string, string> GetRequestParams(this IRequest request)
+ {
+ var map = new Dictionary<string, string>();
+
+ foreach (var name in request.QueryString.Keys)
+ {
+ if (name == null) continue; //thank you ASP.NET
+
+ var values = request.QueryString.GetValues(name);
+ if (values.Length == 1)
+ {
+ map[name] = values[0];
+ }
+ else
+ {
+ for (var i = 0; i < values.Length; i++)
+ {
+ map[name + (i == 0 ? "" : "#" + i)] = values[i];
+ }
+ }
+ }
+
+ if ((request.Verb == HttpMethods.Post || request.Verb == HttpMethods.Put)
+ && request.FormData != null)
+ {
+ foreach (var name in request.FormData.Keys)
+ {
+ if (name == null) continue; //thank you ASP.NET
+
+ var values = request.FormData.GetValues(name);
+ if (values.Length == 1)
+ {
+ map[name] = values[0];
+ }
+ else
+ {
+ for (var i = 0; i < values.Length; i++)
+ {
+ map[name + (i == 0 ? "" : "#" + i)] = values[i];
+ }
+ }
+ }
+ }
+
+ return map;
+ }
+
+ /// <summary>
+ /// Duplicate params have their values joined together in a comma-delimited string
+ /// </summary>
+ public static Dictionary<string, string> GetFlattenedRequestParams(this IRequest request)
+ {
+ var map = new Dictionary<string, string>();
+
+ foreach (var name in request.QueryString.Keys)
+ {
+ if (name == null) continue; //thank you ASP.NET
+ map[name] = request.QueryString[name];
+ }
+
+ if ((request.Verb == HttpMethods.Post || request.Verb == HttpMethods.Put)
+ && request.FormData != null)
+ {
+ foreach (var name in request.FormData.Keys)
+ {
+ if (name == null) continue; //thank you ASP.NET
+ map[name] = request.FormData[name];
+ }
+ }
+
+ return map;
+ }
+
+ public static void SetRoute(this IRequest req, RestPath route)
+ {
+ req.Items["__route"] = route;
+ }
+
+ public static RestPath GetRoute(this IRequest req)
+ {
+ object route;
+ req.Items.TryGetValue("__route", out route);
+ return route as RestPath;
+ }
+ }
+} \ No newline at end of file
diff --git a/ServiceStack/HttpResponseExtensionsInternal.cs b/ServiceStack/HttpResponseExtensionsInternal.cs
new file mode 100644
index 0000000000..1195f63ca2
--- /dev/null
+++ b/ServiceStack/HttpResponseExtensionsInternal.cs
@@ -0,0 +1,237 @@
+//Copyright (c) Service Stack LLC. All Rights Reserved.
+//License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt
+
+using System;
+using System.IO;
+using System.Net;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Threading;
+using MediaBrowser.Model.Services;
+using ServiceStack.Host;
+
+namespace ServiceStack
+{
+ public static class HttpResponseExtensionsInternal
+ {
+ public static async Task<bool> WriteToOutputStream(IResponse response, object result)
+ {
+ var asyncStreamWriter = result as IAsyncStreamWriter;
+ if (asyncStreamWriter != null)
+ {
+ await asyncStreamWriter.WriteToAsync(response.OutputStream, CancellationToken.None).ConfigureAwait(false);
+ return true;
+ }
+
+ var streamWriter = result as IStreamWriter;
+ if (streamWriter != null)
+ {
+ streamWriter.WriteTo(response.OutputStream);
+ return true;
+ }
+
+ var stream = result as Stream;
+ if (stream != null)
+ {
+ WriteTo(stream, response.OutputStream);
+ return true;
+ }
+
+ var bytes = result as byte[];
+ if (bytes != null)
+ {
+ response.ContentType = "application/octet-stream";
+ response.SetContentLength(bytes.Length);
+
+ response.OutputStream.Write(bytes, 0, bytes.Length);
+ return true;
+ }
+
+ return false;
+ }
+
+ public static long WriteTo(Stream inStream, Stream outStream)
+ {
+ var memoryStream = inStream as MemoryStream;
+ if (memoryStream != null)
+ {
+ memoryStream.WriteTo(outStream);
+ return memoryStream.Position;
+ }
+
+ var data = new byte[4096];
+ long total = 0;
+ int bytesRead;
+
+ while ((bytesRead = inStream.Read(data, 0, data.Length)) > 0)
+ {
+ outStream.Write(data, 0, bytesRead);
+ total += bytesRead;
+ }
+
+ return total;
+ }
+
+ /// <summary>
+ /// End a ServiceStack Request with no content
+ /// </summary>
+ public static void EndRequestWithNoContent(this IResponse httpRes)
+ {
+ if (httpRes.StatusCode == (int)HttpStatusCode.OK)
+ {
+ httpRes.StatusCode = (int)HttpStatusCode.NoContent;
+ }
+
+ httpRes.SetContentLength(0);
+ }
+
+ public static Task WriteToResponse(this IResponse httpRes, MediaBrowser.Model.Services.IRequest httpReq, object result)
+ {
+ if (result == null)
+ {
+ httpRes.EndRequestWithNoContent();
+ return Task.FromResult(true);
+ }
+
+ var httpResult = result as IHttpResult;
+ if (httpResult != null)
+ {
+ httpResult.RequestContext = httpReq;
+ httpReq.ResponseContentType = httpResult.ContentType ?? httpReq.ResponseContentType;
+ var httpResSerializer = ContentTypes.Instance.GetResponseSerializer(httpReq.ResponseContentType);
+ return httpRes.WriteToResponse(httpResult, httpResSerializer, httpReq);
+ }
+
+ var serializer = ContentTypes.Instance.GetResponseSerializer(httpReq.ResponseContentType);
+ return httpRes.WriteToResponse(result, serializer, httpReq);
+ }
+
+ private static object GetDto(object response)
+ {
+ if (response == null) return null;
+ var httpResult = response as IHttpResult;
+ return httpResult != null ? httpResult.Response : response;
+ }
+
+ /// <summary>
+ /// Writes to response.
+ /// Response headers are customizable by implementing IHasHeaders an returning Dictionary of Http headers.
+ /// </summary>
+ /// <param name="response">The response.</param>
+ /// <param name="result">Whether or not it was implicity handled by ServiceStack's built-in handlers.</param>
+ /// <param name="defaultAction">The default action.</param>
+ /// <param name="request">The serialization context.</param>
+ /// <returns></returns>
+ public static async Task WriteToResponse(this IResponse response, object result, Action<IRequest, object, IResponse> defaultAction, MediaBrowser.Model.Services.IRequest request)
+ {
+ var defaultContentType = request.ResponseContentType;
+ if (result == null)
+ {
+ response.EndRequestWithNoContent();
+ return;
+ }
+
+ var httpResult = result as IHttpResult;
+ if (httpResult != null)
+ {
+ if (httpResult.RequestContext == null)
+ httpResult.RequestContext = request;
+
+ response.Dto = response.Dto ?? GetDto(httpResult);
+
+ response.StatusCode = httpResult.Status;
+ response.StatusDescription = httpResult.StatusDescription ?? httpResult.StatusCode.ToString();
+ if (string.IsNullOrEmpty(httpResult.ContentType))
+ {
+ httpResult.ContentType = defaultContentType;
+ }
+ response.ContentType = httpResult.ContentType;
+
+ if (httpResult.Cookies != null)
+ {
+ var httpRes = response as IHttpResponse;
+ if (httpRes != null)
+ {
+ foreach (var cookie in httpResult.Cookies)
+ {
+ httpRes.SetCookie(cookie);
+ }
+ }
+ }
+ }
+ else
+ {
+ response.Dto = result;
+ }
+
+ /* Mono Error: Exception: Method not found: 'System.Web.HttpResponse.get_Headers' */
+ var responseOptions = result as IHasHeaders;
+ if (responseOptions != null)
+ {
+ //Reserving options with keys in the format 'xx.xxx' (No Http headers contain a '.' so its a safe restriction)
+ const string reservedOptions = ".";
+
+ foreach (var responseHeaders in responseOptions.Headers)
+ {
+ if (responseHeaders.Key.Contains(reservedOptions)) continue;
+ if (responseHeaders.Key == "Content-Length")
+ {
+ response.SetContentLength(long.Parse(responseHeaders.Value));
+ continue;
+ }
+
+ response.AddHeader(responseHeaders.Key, responseHeaders.Value);
+ }
+ }
+
+ //ContentType='text/html' is the default for a HttpResponse
+ //Do not override if another has been set
+ if (response.ContentType == null || response.ContentType == "text/html")
+ {
+ response.ContentType = defaultContentType;
+ }
+
+ if (new HashSet<string> { "application/json", }.Contains(response.ContentType))
+ {
+ response.ContentType += "; charset=utf-8";
+ }
+
+ var disposableResult = result as IDisposable;
+ var writeToOutputStreamResult = await WriteToOutputStream(response, result).ConfigureAwait(false);
+ if (writeToOutputStreamResult)
+ {
+ response.Flush(); //required for Compression
+ if (disposableResult != null) disposableResult.Dispose();
+ return;
+ }
+
+ if (httpResult != null)
+ result = httpResult.Response;
+
+ var responseText = result as string;
+ if (responseText != null)
+ {
+ if (response.ContentType == null || response.ContentType == "text/html")
+ response.ContentType = defaultContentType;
+ response.Write(responseText);
+
+ return;
+ }
+
+ if (defaultAction == null)
+ {
+ throw new ArgumentNullException("defaultAction", String.Format(
+ "As result '{0}' is not a supported responseType, a defaultAction must be supplied",
+ (result != null ? result.GetType().GetOperationName() : "")));
+ }
+
+
+ if (result != null)
+ defaultAction(request, result, response);
+
+ if (disposableResult != null)
+ disposableResult.Dispose();
+ }
+
+ }
+}
diff --git a/ServiceStack/HttpResult.cs b/ServiceStack/HttpResult.cs
new file mode 100644
index 0000000000..23a5cdffbb
--- /dev/null
+++ b/ServiceStack/HttpResult.cs
@@ -0,0 +1,250 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Services;
+using ServiceStack.Host;
+
+namespace ServiceStack
+{
+ public class HttpResult
+ : IHttpResult, IAsyncStreamWriter
+ {
+ public HttpResult()
+ : this((object)null, null)
+ {
+ }
+
+ public HttpResult(object response)
+ : this(response, null)
+ {
+ }
+
+ public HttpResult(object response, string contentType)
+ : this(response, contentType, HttpStatusCode.OK)
+ {
+ }
+
+ public HttpResult(HttpStatusCode statusCode, string statusDescription)
+ : this()
+ {
+ StatusCode = statusCode;
+ StatusDescription = statusDescription;
+ }
+
+ public HttpResult(object response, HttpStatusCode statusCode)
+ : this(response, null, statusCode)
+ { }
+
+ public HttpResult(object response, string contentType, HttpStatusCode statusCode)
+ {
+ this.Headers = new Dictionary<string, string>();
+ this.Cookies = new List<Cookie>();
+
+ this.Response = response;
+ this.ContentType = contentType;
+ this.StatusCode = statusCode;
+ }
+
+ public HttpResult(Stream responseStream, string contentType)
+ : this(null, contentType, HttpStatusCode.OK)
+ {
+ this.ResponseStream = responseStream;
+ }
+
+ public HttpResult(string responseText, string contentType)
+ : this(null, contentType, HttpStatusCode.OK)
+ {
+ this.ResponseText = responseText;
+ }
+
+ public HttpResult(byte[] responseBytes, string contentType)
+ : this(null, contentType, HttpStatusCode.OK)
+ {
+ this.ResponseStream = new MemoryStream(responseBytes);
+ }
+
+ public string ResponseText { get; private set; }
+
+ public Stream ResponseStream { get; private set; }
+
+ public string ContentType { get; set; }
+
+ public IDictionary<string, string> Headers { get; private set; }
+
+ public List<Cookie> Cookies { get; private set; }
+
+ public string ETag { get; set; }
+
+ public TimeSpan? Age { get; set; }
+
+ public TimeSpan? MaxAge { get; set; }
+
+ public DateTime? Expires { get; set; }
+
+ public DateTime? LastModified { get; set; }
+
+ public Func<IDisposable> ResultScope { get; set; }
+
+ public string Location
+ {
+ set
+ {
+ if (StatusCode == HttpStatusCode.OK)
+ StatusCode = HttpStatusCode.Redirect;
+
+ this.Headers["Location"] = value;
+ }
+ }
+
+ public void SetPermanentCookie(string name, string value)
+ {
+ SetCookie(name, value, DateTime.UtcNow.AddYears(20), null);
+ }
+
+ public void SetPermanentCookie(string name, string value, string path)
+ {
+ SetCookie(name, value, DateTime.UtcNow.AddYears(20), path);
+ }
+
+ public void SetSessionCookie(string name, string value)
+ {
+ SetSessionCookie(name, value, null);
+ }
+
+ public void SetSessionCookie(string name, string value, string path)
+ {
+ path = path ?? "/";
+ this.Headers["Set-Cookie"] = string.Format("{0}={1};path=" + path, name, value);
+ }
+
+ public void SetCookie(string name, string value, TimeSpan expiresIn, string path)
+ {
+ var expiresAt = DateTime.UtcNow.Add(expiresIn);
+ SetCookie(name, value, expiresAt, path);
+ }
+
+ public void SetCookie(string name, string value, DateTime expiresAt, string path, bool secure = false, bool httpOnly = false)
+ {
+ path = path ?? "/";
+ var cookie = string.Format("{0}={1};expires={2};path={3}", name, value, expiresAt.ToString("R"), path);
+ if (secure)
+ cookie += ";Secure";
+ if (httpOnly)
+ cookie += ";HttpOnly";
+
+ this.Headers["Set-Cookie"] = cookie;
+ }
+
+ public void DeleteCookie(string name)
+ {
+ var cookie = string.Format("{0}=;expires={1};path=/", name, DateTime.UtcNow.AddDays(-1).ToString("R"));
+ this.Headers["Set-Cookie"] = cookie;
+ }
+
+ public int Status { get; set; }
+
+ public HttpStatusCode StatusCode
+ {
+ get { return (HttpStatusCode)Status; }
+ set { Status = (int)value; }
+ }
+
+ public string StatusDescription { get; set; }
+
+ public object Response { get; set; }
+
+ public MediaBrowser.Model.Services.IRequest RequestContext { get; set; }
+
+ public string View { get; set; }
+
+ public string Template { get; set; }
+
+ public int PaddingLength { get; set; }
+
+ public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken)
+ {
+ try
+ {
+ await WriteToInternalAsync(responseStream, cancellationToken).ConfigureAwait(false);
+ responseStream.Flush();
+ }
+ finally
+ {
+ DisposeStream();
+ }
+ }
+
+ public static Task WriteTo(Stream inStream, Stream outStream, CancellationToken cancellationToken)
+ {
+ var memoryStream = inStream as MemoryStream;
+ if (memoryStream != null)
+ {
+ memoryStream.WriteTo(outStream);
+ return Task.FromResult(true);
+ }
+
+ return inStream.CopyToAsync(outStream, 81920, cancellationToken);
+ }
+
+ public async Task WriteToInternalAsync(Stream responseStream, CancellationToken cancellationToken)
+ {
+ var response = RequestContext != null ? RequestContext.Response : null;
+
+ if (this.ResponseStream != null)
+ {
+ if (response != null)
+ {
+ var ms = ResponseStream as MemoryStream;
+ if (ms != null)
+ {
+ response.SetContentLength(ms.Length);
+
+ await ms.CopyToAsync(responseStream, 81920, cancellationToken).ConfigureAwait(false);
+ return;
+ }
+ }
+
+ await WriteTo(this.ResponseStream, responseStream, cancellationToken).ConfigureAwait(false);
+ return;
+ }
+
+ if (this.ResponseText != null)
+ {
+ var bytes = Encoding.UTF8.GetBytes(this.ResponseText);
+ if (response != null)
+ response.SetContentLength(bytes.Length);
+
+ await responseStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
+ return;
+ }
+
+ var bytesResponse = this.Response as byte[];
+ if (bytesResponse != null)
+ {
+ if (response != null)
+ response.SetContentLength(bytesResponse.Length);
+
+ await responseStream.WriteAsync(bytesResponse, 0, bytesResponse.Length).ConfigureAwait(false);
+ return;
+ }
+
+ ContentTypes.Instance.SerializeToStream(this.RequestContext, this.Response, responseStream);
+ }
+
+ private void DisposeStream()
+ {
+ try
+ {
+ if (ResponseStream != null)
+ {
+ this.ResponseStream.Dispose();
+ }
+ }
+ catch { /*ignore*/ }
+ }
+ }
+}
diff --git a/ServiceStack/HttpUtils.cs b/ServiceStack/HttpUtils.cs
new file mode 100644
index 0000000000..41d191d613
--- /dev/null
+++ b/ServiceStack/HttpUtils.cs
@@ -0,0 +1,34 @@
+//Copyright (c) Service Stack LLC. All Rights Reserved.
+//License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt
+
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack
+{
+ internal static class HttpMethods
+ {
+ static readonly 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",
+ "MKWORKSPACE", "UPDATE", "LABEL", "MERGE", "BASELINE-CONTROL", "MKACTIVITY", // RFC 3253
+ "ORDERPATCH", // RFC 3648
+ "ACL", // RFC 3744
+ "PATCH", // https://datatracker.ietf.org/doc/draft-dusseault-http-patch/
+ "SEARCH", // https://datatracker.ietf.org/doc/draft-reschke-webdav-search/
+ "BCOPY", "BDELETE", "BMOVE", "BPROPFIND", "BPROPPATCH", "NOTIFY",
+ "POLL", "SUBSCRIBE", "UNSUBSCRIBE" //MS Exchange WebDav: http://msdn.microsoft.com/en-us/library/aa142917.aspx
+ };
+
+ public static HashSet<string> AllVerbs = new HashSet<string>(allVerbs);
+
+ public const string Get = "GET";
+ public const string Put = "PUT";
+ public const string Post = "POST";
+ public const string Delete = "DELETE";
+ public const string Options = "OPTIONS";
+ public const string Head = "HEAD";
+ public const string Patch = "PATCH";
+ }
+}
diff --git a/ServiceStack/Properties/AssemblyInfo.cs b/ServiceStack/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..6073dc0b44
--- /dev/null
+++ b/ServiceStack/Properties/AssemblyInfo.cs
@@ -0,0 +1,25 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ServiceStack")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Service Stack LLC")]
+[assembly: AssemblyProduct("ServiceStack")]
+[assembly: AssemblyCopyright("Copyright (c) ServiceStack 2016")]
+[assembly: AssemblyTrademark("Service Stack")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("06704d66-af8e-411f-8260-8d05de5ce6ad")]
+
+[assembly: AssemblyVersion("4.0.0.0")]
+[assembly: AssemblyFileVersion("4.0.0.0")]
diff --git a/ServiceStack/ReflectionExtensions.cs b/ServiceStack/ReflectionExtensions.cs
new file mode 100644
index 0000000000..bbabd0dd74
--- /dev/null
+++ b/ServiceStack/ReflectionExtensions.cs
@@ -0,0 +1,270 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ServiceStack
+{
+ public static class ReflectionExtensions
+ {
+ public static bool IsInstanceOf(this Type type, Type thisOrBaseType)
+ {
+ while (type != null)
+ {
+ if (type == thisOrBaseType)
+ return true;
+
+ type = type.BaseType();
+ }
+ return false;
+ }
+
+ public static Type FirstGenericType(this Type type)
+ {
+ while (type != null)
+ {
+ if (type.IsGeneric())
+ return type;
+
+ type = type.BaseType();
+ }
+ return null;
+ }
+
+ public static Type GetTypeWithGenericTypeDefinitionOf(this Type type, Type genericTypeDefinition)
+ {
+ foreach (var t in type.GetTypeInterfaces())
+ {
+ if (t.IsGeneric() && t.GetGenericTypeDefinition() == genericTypeDefinition)
+ {
+ return t;
+ }
+ }
+
+ var genericType = type.FirstGenericType();
+ if (genericType != null && genericType.GetGenericTypeDefinition() == genericTypeDefinition)
+ {
+ return genericType;
+ }
+
+ return null;
+ }
+
+ public static PropertyInfo[] GetAllProperties(this Type type)
+ {
+ if (type.IsInterface())
+ {
+ var propertyInfos = new List<PropertyInfo>();
+
+ var considered = new List<Type>();
+ var queue = new Queue<Type>();
+ considered.Add(type);
+ queue.Enqueue(type);
+
+ while (queue.Count > 0)
+ {
+ var subType = queue.Dequeue();
+ foreach (var subInterface in subType.GetTypeInterfaces())
+ {
+ if (considered.Contains(subInterface)) continue;
+
+ considered.Add(subInterface);
+ queue.Enqueue(subInterface);
+ }
+
+ var typeProperties = subType.GetTypesProperties();
+
+ var newPropertyInfos = typeProperties
+ .Where(x => !propertyInfos.Contains(x));
+
+ propertyInfos.InsertRange(0, newPropertyInfos);
+ }
+
+ return propertyInfos.ToArray();
+ }
+
+ return type.GetTypesProperties()
+ .Where(t => t.GetIndexParameters().Length == 0) // ignore indexed properties
+ .ToArray();
+ }
+
+ public static PropertyInfo[] GetPublicProperties(this Type type)
+ {
+ if (type.IsInterface())
+ {
+ var propertyInfos = new List<PropertyInfo>();
+
+ var considered = new List<Type>();
+ var queue = new Queue<Type>();
+ considered.Add(type);
+ queue.Enqueue(type);
+
+ while (queue.Count > 0)
+ {
+ var subType = queue.Dequeue();
+ foreach (var subInterface in subType.GetTypeInterfaces())
+ {
+ if (considered.Contains(subInterface)) continue;
+
+ considered.Add(subInterface);
+ queue.Enqueue(subInterface);
+ }
+
+ var typeProperties = subType.GetTypesPublicProperties();
+
+ var newPropertyInfos = typeProperties
+ .Where(x => !propertyInfos.Contains(x));
+
+ propertyInfos.InsertRange(0, newPropertyInfos);
+ }
+
+ return propertyInfos.ToArray();
+ }
+
+ return type.GetTypesPublicProperties()
+ .Where(t => t.GetIndexParameters().Length == 0) // ignore indexed properties
+ .ToArray();
+ }
+
+ public const string DataMember = "DataMemberAttribute";
+
+ internal static string[] IgnoreAttributesNamed = new[] {
+ "IgnoreDataMemberAttribute",
+ "JsonIgnoreAttribute"
+ };
+
+ public static PropertyInfo[] GetSerializableProperties(this Type type)
+ {
+ var properties = type.IsDto()
+ ? type.GetAllProperties()
+ : type.GetPublicProperties();
+ return properties.OnlySerializableProperties(type);
+ }
+
+
+ private static List<Type> _excludeTypes = new List<Type> { typeof(Stream) };
+
+ public static PropertyInfo[] OnlySerializableProperties(this PropertyInfo[] properties, Type type = null)
+ {
+ var isDto = type.IsDto();
+ var readableProperties = properties.Where(x => x.PropertyGetMethod(nonPublic: isDto) != null);
+
+ if (isDto)
+ {
+ return readableProperties.Where(attr =>
+ attr.HasAttribute<DataMemberAttribute>()).ToArray();
+ }
+
+ // else return those properties that are not decorated with IgnoreDataMember
+ return readableProperties
+ .Where(prop => prop.AllAttributes()
+ .All(attr =>
+ {
+ var name = attr.GetType().Name;
+ return !IgnoreAttributesNamed.Contains(name);
+ }))
+ .Where(prop => !_excludeTypes.Contains(prop.PropertyType))
+ .ToArray();
+ }
+ }
+
+ public static class PlatformExtensions //Because WinRT is a POS
+ {
+ public static bool IsInterface(this Type type)
+ {
+ return type.GetTypeInfo().IsInterface;
+ }
+
+ public static bool IsGeneric(this Type type)
+ {
+ return type.GetTypeInfo().IsGenericType;
+ }
+
+ public static Type BaseType(this Type type)
+ {
+ return type.GetTypeInfo().BaseType;
+ }
+
+ public static Type[] GetTypeInterfaces(this Type type)
+ {
+ return type.GetTypeInfo().ImplementedInterfaces.ToArray();
+ }
+
+ internal static PropertyInfo[] GetTypesPublicProperties(this Type subType)
+ {
+ var pis = new List<PropertyInfo>();
+ foreach (var pi in subType.GetRuntimeProperties())
+ {
+ var mi = pi.GetMethod ?? pi.SetMethod;
+ if (mi != null && mi.IsStatic) continue;
+ pis.Add(pi);
+ }
+ return pis.ToArray();
+ }
+
+ internal static PropertyInfo[] GetTypesProperties(this Type subType)
+ {
+ var pis = new List<PropertyInfo>();
+ foreach (var pi in subType.GetRuntimeProperties())
+ {
+ var mi = pi.GetMethod ?? pi.SetMethod;
+ if (mi != null && mi.IsStatic) continue;
+ pis.Add(pi);
+ }
+ return pis.ToArray();
+ }
+
+ public static bool HasAttribute<T>(this Type type)
+ {
+ return type.AllAttributes().Any(x => x.GetType() == typeof(T));
+ }
+
+ public static bool HasAttribute<T>(this PropertyInfo pi)
+ {
+ return pi.AllAttributes().Any(x => x.GetType() == typeof(T));
+ }
+
+ public static bool IsDto(this Type type)
+ {
+ if (type == null)
+ return false;
+
+ return type.HasAttribute<DataContractAttribute>();
+ }
+
+ public static MethodInfo PropertyGetMethod(this PropertyInfo pi, bool nonPublic = false)
+ {
+ return pi.GetMethod;
+ }
+
+ public static object[] AllAttributes(this PropertyInfo propertyInfo)
+ {
+ return propertyInfo.GetCustomAttributes(true).ToArray();
+ }
+
+ public static object[] AllAttributes(this PropertyInfo propertyInfo, Type attrType)
+ {
+ return propertyInfo.GetCustomAttributes(true).Where(x => attrType.IsInstanceOf(x.GetType())).ToArray();
+ }
+
+ public static object[] AllAttributes(this Type type)
+ {
+ return type.GetTypeInfo().GetCustomAttributes(true).ToArray();
+ }
+
+ public static TAttr[] AllAttributes<TAttr>(this PropertyInfo pi)
+ {
+ return pi.AllAttributes(typeof(TAttr)).Cast<TAttr>().ToArray();
+ }
+
+ public static TAttr[] AllAttributes<TAttr>(this Type type)
+ where TAttr : Attribute
+ {
+ return type.GetTypeInfo().GetCustomAttributes<TAttr>(true).ToArray();
+ }
+ }
+}
diff --git a/ServiceStack/ServiceStack.csproj b/ServiceStack/ServiceStack.csproj
new file mode 100644
index 0000000000..3402339a6c
--- /dev/null
+++ b/ServiceStack/ServiceStack.csproj
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{680A1709-25EB-4D52-A87F-EE03FFD94BAA}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ServiceStack</RootNamespace>
+ <AssemblyName>ServiceStack</AssemblyName>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>True</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>False</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;MONO</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <Prefer32Bit>false</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>True</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <DocumentationFile>
+ </DocumentationFile>
+ <Prefer32Bit>false</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Signed|AnyCPU'">
+ <OutputPath>bin\Signed\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <DocumentationFile>bin\Release\ServiceStack.XML</DocumentationFile>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <Prefer32Bit>false</Prefer32Bit>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="HttpUtils.cs" />
+ <Compile Include="Host\ContentTypes.cs" />
+ <Compile Include="ReflectionExtensions.cs" />
+ <Compile Include="StringMapTypeDeserializer.cs" />
+ <Compile Include="Host\HttpResponseStreamWrapper.cs" />
+ <Compile Include="HttpResult.cs" />
+ <Compile Include="ServiceStackHost.cs" />
+ <Compile Include="ServiceStackHost.Runtime.cs" />
+ <Compile Include="Host\ServiceExec.cs" />
+ <Compile Include="UrlExtensions.cs" />
+ <Compile Include="Host\ActionContext.cs" />
+ <Compile Include="HttpRequestExtensions.cs" />
+ <Compile Include="Host\RestPath.cs" />
+ <Compile Include="Host\ServiceController.cs" />
+ <Compile Include="Host\ServiceMetadata.cs" />
+ <Compile Include="Host\RestHandler.cs" />
+ <Compile Include="HttpResponseExtensionsInternal.cs" />
+ <Compile Include="HttpHandlerFactory.cs" />
+ <Compile Include="FilterAttributeCache.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <ItemGroup>
+ <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
+ <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
+ <Name>MediaBrowser.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
+ <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
+ <Name>MediaBrowser.Model</Name>
+ </ProjectReference>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.nuget.targets b/ServiceStack/ServiceStack.nuget.targets
index e69ce0e64f..e69ce0e64f 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.nuget.targets
+++ b/ServiceStack/ServiceStack.nuget.targets
diff --git a/ServiceStack/ServiceStackHost.Runtime.cs b/ServiceStack/ServiceStackHost.Runtime.cs
new file mode 100644
index 0000000000..1a1656a0ec
--- /dev/null
+++ b/ServiceStack/ServiceStackHost.Runtime.cs
@@ -0,0 +1,74 @@
+// Copyright (c) Service Stack LLC. All Rights Reserved.
+// License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt
+
+
+using MediaBrowser.Model.Services;
+using ServiceStack.Support.WebHost;
+
+namespace ServiceStack
+{
+ public abstract partial class ServiceStackHost
+ {
+ /// <summary>
+ /// Applies the request filters. Returns whether or not the request has been handled
+ /// and no more processing should be done.
+ /// </summary>
+ /// <returns></returns>
+ public virtual bool ApplyRequestFilters(IRequest req, IResponse res, object requestDto)
+ {
+ if (res.IsClosed) return res.IsClosed;
+
+ //Exec all RequestFilter attributes with Priority < 0
+ var attributes = FilterAttributeCache.GetRequestFilterAttributes(requestDto.GetType());
+ var i = 0;
+ for (; i < attributes.Length && attributes[i].Priority < 0; i++)
+ {
+ var attribute = attributes[i];
+ attribute.RequestFilter(req, res, requestDto);
+ if (res.IsClosed) return res.IsClosed;
+ }
+
+ if (res.IsClosed) return res.IsClosed;
+
+ //Exec global filters
+ foreach (var requestFilter in GlobalRequestFilters)
+ {
+ requestFilter(req, res, requestDto);
+ if (res.IsClosed) return res.IsClosed;
+ }
+
+ //Exec remaining RequestFilter attributes with Priority >= 0
+ for (; i < attributes.Length && attributes[i].Priority >= 0; i++)
+ {
+ var attribute = attributes[i];
+ attribute.RequestFilter(req, res, requestDto);
+ if (res.IsClosed) return res.IsClosed;
+ }
+
+ return res.IsClosed;
+ }
+
+ /// <summary>
+ /// Applies the response filters. Returns whether or not the request has been handled
+ /// and no more processing should be done.
+ /// </summary>
+ /// <returns></returns>
+ public virtual bool ApplyResponseFilters(IRequest req, IResponse res, object response)
+ {
+ if (response != null)
+ {
+ if (res.IsClosed) return res.IsClosed;
+ }
+
+ //Exec global filters
+ foreach (var responseFilter in GlobalResponseFilters)
+ {
+ responseFilter(req, res, response);
+ if (res.IsClosed) return res.IsClosed;
+ }
+
+ return res.IsClosed;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/ServiceStack/ServiceStackHost.cs b/ServiceStack/ServiceStackHost.cs
new file mode 100644
index 0000000000..8a1db25e48
--- /dev/null
+++ b/ServiceStack/ServiceStackHost.cs
@@ -0,0 +1,104 @@
+// Copyright (c) Service Stack LLC. All Rights Reserved.
+// License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt
+
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Services;
+using ServiceStack.Host;
+
+namespace ServiceStack
+{
+ public abstract partial class ServiceStackHost : IDisposable
+ {
+ public static ServiceStackHost Instance { get; protected set; }
+
+ protected ServiceStackHost(string serviceName)
+ {
+ ServiceName = serviceName;
+ ServiceController = CreateServiceController();
+
+ RestPaths = new List<RestPath>();
+ Metadata = new ServiceMetadata();
+ GlobalRequestFilters = new List<Action<IRequest, IResponse, object>>();
+ GlobalResponseFilters = new List<Action<IRequest, IResponse, object>>();
+ }
+
+ public abstract void Configure();
+
+ public abstract object CreateInstance(Type type);
+
+ protected abstract ServiceController CreateServiceController();
+
+ public virtual ServiceStackHost Init()
+ {
+ Instance = this;
+
+ ServiceController.Init();
+ Configure();
+
+ ServiceController.AfterInit();
+
+ return this;
+ }
+
+ public virtual ServiceStackHost Start(string urlBase)
+ {
+ throw new NotImplementedException("Start(listeningAtUrlBase) is not supported by this AppHost");
+ }
+
+ public string ServiceName { get; set; }
+
+ public ServiceMetadata Metadata { get; set; }
+
+ public ServiceController ServiceController { get; set; }
+
+ public List<RestPath> RestPaths = new List<RestPath>();
+
+ public List<Action<IRequest, IResponse, object>> GlobalRequestFilters { get; set; }
+
+ public List<Action<IRequest, IResponse, object>> GlobalResponseFilters { get; set; }
+
+ public abstract T TryResolve<T>();
+ public abstract T Resolve<T>();
+
+ public virtual MediaBrowser.Model.Services.RouteAttribute[] GetRouteAttributes(Type requestType)
+ {
+ return requestType.AllAttributes<MediaBrowser.Model.Services.RouteAttribute>();
+ }
+
+ public abstract object GetTaskResult(Task task, string requestName);
+
+ public abstract Func<string, object> GetParseFn(Type propertyType);
+
+ public abstract void SerializeToJson(object o, Stream stream);
+ public abstract void SerializeToXml(object o, Stream stream);
+ public abstract object DeserializeXml(Type type, Stream stream);
+ public abstract object DeserializeJson(Type type, Stream stream);
+
+ public virtual void Dispose()
+ {
+ //JsConfig.Reset(); //Clears Runtime Attributes
+
+ Instance = null;
+ }
+
+ protected abstract ILogger Logger
+ {
+ get;
+ }
+
+ public void OnLogError(Type type, string message)
+ {
+ Logger.Error(message);
+ }
+
+ public void OnLogError(Type type, string message, Exception ex)
+ {
+ Logger.ErrorException(message, ex);
+ }
+ }
+}
diff --git a/ServiceStack/StringMapTypeDeserializer.cs b/ServiceStack/StringMapTypeDeserializer.cs
new file mode 100644
index 0000000000..762e8aafff
--- /dev/null
+++ b/ServiceStack/StringMapTypeDeserializer.cs
@@ -0,0 +1,126 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Linq;
+using System.Reflection;
+
+namespace ServiceStack.Serialization
+{
+ /// <summary>
+ /// Serializer cache of delegates required to create a type from a string map (e.g. for REST urls)
+ /// </summary>
+ public class StringMapTypeDeserializer
+ {
+ internal class PropertySerializerEntry
+ {
+ public PropertySerializerEntry(Action<object,object> propertySetFn, Func<string, object> propertyParseStringFn)
+ {
+ PropertySetFn = propertySetFn;
+ PropertyParseStringFn = propertyParseStringFn;
+ }
+
+ public Action<object, object> PropertySetFn;
+ public Func<string,object> PropertyParseStringFn;
+ public Type PropertyType;
+ }
+
+ private readonly Type type;
+ private readonly Dictionary<string, PropertySerializerEntry> propertySetterMap
+ = new Dictionary<string, PropertySerializerEntry>(StringComparer.OrdinalIgnoreCase);
+
+ public Func<string, object> GetParseFn(Type propertyType)
+ {
+ //Don't JSV-decode string values for string properties
+ if (propertyType == typeof(string))
+ return s => s;
+
+ return ServiceStackHost.Instance.GetParseFn(propertyType);
+ }
+
+ public StringMapTypeDeserializer(Type type)
+ {
+ this.type = type;
+
+ foreach (var propertyInfo in type.GetSerializableProperties())
+ {
+ var propertySetFn = TypeAccessor.GetSetPropertyMethod(type, propertyInfo);
+ var propertyType = propertyInfo.PropertyType;
+ var propertyParseStringFn = GetParseFn(propertyType);
+ var propertySerializer = new PropertySerializerEntry(propertySetFn, propertyParseStringFn) { PropertyType = propertyType };
+
+ var attr = propertyInfo.AllAttributes<DataMemberAttribute>().FirstOrDefault();
+ if (attr != null && attr.Name != null)
+ {
+ propertySetterMap[attr.Name] = propertySerializer;
+ }
+ propertySetterMap[propertyInfo.Name] = propertySerializer;
+ }
+ }
+
+ public object PopulateFromMap(object instance, IDictionary<string, string> keyValuePairs)
+ {
+ string propertyName = null;
+ string propertyTextValue = null;
+ PropertySerializerEntry propertySerializerEntry = null;
+
+ if (instance == null)
+ instance = ServiceStackHost.Instance.CreateInstance(type);
+
+ foreach (var pair in keyValuePairs.Where(x => !string.IsNullOrEmpty(x.Value)))
+ {
+ propertyName = pair.Key;
+ propertyTextValue = pair.Value;
+
+ if (!propertySetterMap.TryGetValue(propertyName, out propertySerializerEntry))
+ {
+ if (propertyName == "v")
+ {
+ continue;
+ }
+
+ continue;
+ }
+
+ if (propertySerializerEntry.PropertySetFn == null)
+ {
+ continue;
+ }
+
+ if (propertySerializerEntry.PropertyType == typeof(bool))
+ {
+ //InputExtensions.cs#530 MVC Checkbox helper emits extra hidden input field, generating 2 values, first is the real value
+ propertyTextValue = LeftPart(propertyTextValue, ',');
+ }
+
+ var value = propertySerializerEntry.PropertyParseStringFn(propertyTextValue);
+ if (value == null)
+ {
+ continue;
+ }
+ propertySerializerEntry.PropertySetFn(instance, value);
+ }
+
+ return instance;
+ }
+
+ public static string LeftPart(string strVal, char needle)
+ {
+ if (strVal == null) return null;
+ var pos = strVal.IndexOf(needle);
+ return pos == -1
+ ? strVal
+ : strVal.Substring(0, pos);
+ }
+ }
+
+ internal class TypeAccessor
+ {
+ public static Action<object, object> GetSetPropertyMethod(Type type, PropertyInfo propertyInfo)
+ {
+ if (!propertyInfo.CanWrite || propertyInfo.GetIndexParameters().Any()) return null;
+
+ var setMethodInfo = propertyInfo.SetMethod;
+ return (instance, value) => setMethodInfo.Invoke(instance, new[] { value });
+ }
+ }
+}
diff --git a/ServiceStack/UrlExtensions.cs b/ServiceStack/UrlExtensions.cs
new file mode 100644
index 0000000000..7b5a50ef17
--- /dev/null
+++ b/ServiceStack/UrlExtensions.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace ServiceStack
+{
+ /// <summary>
+ /// Donated by Ivan Korneliuk from his post:
+ /// http://korneliuk.blogspot.com/2012/08/servicestack-reusing-dtos.html
+ ///
+ /// Modified to only allow using routes matching the supplied HTTP Verb
+ /// </summary>
+ public static class UrlExtensions
+ {
+ public static string GetOperationName(this Type type)
+ {
+ var typeName = type.FullName != null //can be null, e.g. generic types
+ ? LeftPart(type.FullName, "[[") //Generic Fullname
+ .Replace(type.Namespace + ".", "") //Trim Namespaces
+ .Replace("+", ".") //Convert nested into normal type
+ : type.Name;
+
+ return type.IsGenericParameter ? "'" + typeName : typeName;
+ }
+
+ public static string LeftPart(string strVal, string needle)
+ {
+ if (strVal == null) return null;
+ var pos = strVal.IndexOf(needle, StringComparison.OrdinalIgnoreCase);
+ return pos == -1
+ ? strVal
+ : strVal.Substring(0, pos);
+ }
+ }
+} \ No newline at end of file
diff --git a/ServiceStack/packages.config b/ServiceStack/packages.config
new file mode 100644
index 0000000000..6b8deb9c96
--- /dev/null
+++ b/ServiceStack/packages.config
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+</packages> \ No newline at end of file
diff --git a/ServiceStack/project.json b/ServiceStack/project.json
new file mode 100644
index 0000000000..fbbe9eaf32
--- /dev/null
+++ b/ServiceStack/project.json
@@ -0,0 +1,17 @@
+{
+ "frameworks":{
+ "netstandard1.6":{
+ "dependencies":{
+ "NETStandard.Library":"1.6.0",
+ }
+ },
+ ".NETPortable,Version=v4.5,Profile=Profile7":{
+ "buildOptions": {
+ "define": [ ]
+ },
+ "frameworkAssemblies":{
+
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/SocketHttpListener.Portable/ByteOrder.cs b/SocketHttpListener.Portable/ByteOrder.cs
new file mode 100644
index 0000000000..f5db52fd72
--- /dev/null
+++ b/SocketHttpListener.Portable/ByteOrder.cs
@@ -0,0 +1,17 @@
+namespace SocketHttpListener
+{
+ /// <summary>
+ /// Contains the values that indicate whether the byte order is a Little-endian or Big-endian.
+ /// </summary>
+ public enum ByteOrder : byte
+ {
+ /// <summary>
+ /// Indicates a Little-endian.
+ /// </summary>
+ Little,
+ /// <summary>
+ /// Indicates a Big-endian.
+ /// </summary>
+ Big
+ }
+}
diff --git a/SocketHttpListener.Portable/CloseEventArgs.cs b/SocketHttpListener.Portable/CloseEventArgs.cs
new file mode 100644
index 0000000000..b1bb4b1960
--- /dev/null
+++ b/SocketHttpListener.Portable/CloseEventArgs.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Text;
+
+namespace SocketHttpListener
+{
+ /// <summary>
+ /// Contains the event data associated with a <see cref="WebSocket.OnClose"/> event.
+ /// </summary>
+ /// <remarks>
+ /// A <see cref="WebSocket.OnClose"/> event occurs when the WebSocket connection has been closed.
+ /// If you would like to get the reason for the close, you should access the <see cref="Code"/> or
+ /// <see cref="Reason"/> property.
+ /// </remarks>
+ public class CloseEventArgs : EventArgs
+ {
+ #region Private Fields
+
+ private bool _clean;
+ private ushort _code;
+ private string _reason;
+
+ #endregion
+
+ #region Internal Constructors
+
+ internal CloseEventArgs (PayloadData payload)
+ {
+ var data = payload.ApplicationData;
+ var len = data.Length;
+ _code = len > 1
+ ? data.SubArray (0, 2).ToUInt16 (ByteOrder.Big)
+ : (ushort) CloseStatusCode.NoStatusCode;
+
+ _reason = len > 2
+ ? GetUtf8String(data.SubArray (2, len - 2))
+ : String.Empty;
+ }
+
+ private string GetUtf8String(byte[] bytes)
+ {
+ return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the status code for the close.
+ /// </summary>
+ /// <value>
+ /// A <see cref="ushort"/> that represents the status code for the close if any.
+ /// </value>
+ public ushort Code {
+ get {
+ return _code;
+ }
+ }
+
+ /// <summary>
+ /// Gets the reason for the close.
+ /// </summary>
+ /// <value>
+ /// A <see cref="string"/> that represents the reason for the close if any.
+ /// </value>
+ public string Reason {
+ get {
+ return _reason;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the WebSocket connection has been closed cleanly.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if the WebSocket connection has been closed cleanly; otherwise, <c>false</c>.
+ /// </value>
+ public bool WasClean {
+ get {
+ return _clean;
+ }
+
+ internal set {
+ _clean = value;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/SocketHttpListener.Portable/CloseStatusCode.cs b/SocketHttpListener.Portable/CloseStatusCode.cs
new file mode 100644
index 0000000000..62a268bce1
--- /dev/null
+++ b/SocketHttpListener.Portable/CloseStatusCode.cs
@@ -0,0 +1,94 @@
+namespace SocketHttpListener
+{
+ /// <summary>
+ /// Contains the values of the status code for the WebSocket connection close.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// The values of the status code are defined in
+ /// <see href="http://tools.ietf.org/html/rfc6455#section-7.4">Section 7.4</see>
+ /// of RFC 6455.
+ /// </para>
+ /// <para>
+ /// "Reserved value" must not be set as a status code in a close control frame
+ /// by an endpoint. It's designated for use in applications expecting a status
+ /// code to indicate that the connection was closed due to the system grounds.
+ /// </para>
+ /// </remarks>
+ public enum CloseStatusCode : ushort
+ {
+ /// <summary>
+ /// Equivalent to close status 1000.
+ /// Indicates a normal close.
+ /// </summary>
+ Normal = 1000,
+ /// <summary>
+ /// Equivalent to close status 1001.
+ /// Indicates that an endpoint is going away.
+ /// </summary>
+ Away = 1001,
+ /// <summary>
+ /// Equivalent to close status 1002.
+ /// Indicates that an endpoint is terminating the connection due to a protocol error.
+ /// </summary>
+ ProtocolError = 1002,
+ /// <summary>
+ /// Equivalent to close status 1003.
+ /// Indicates that an endpoint is terminating the connection because it has received
+ /// an unacceptable type message.
+ /// </summary>
+ IncorrectData = 1003,
+ /// <summary>
+ /// Equivalent to close status 1004.
+ /// Still undefined. Reserved value.
+ /// </summary>
+ Undefined = 1004,
+ /// <summary>
+ /// Equivalent to close status 1005.
+ /// Indicates that no status code was actually present. Reserved value.
+ /// </summary>
+ NoStatusCode = 1005,
+ /// <summary>
+ /// Equivalent to close status 1006.
+ /// Indicates that the connection was closed abnormally. Reserved value.
+ /// </summary>
+ Abnormal = 1006,
+ /// <summary>
+ /// Equivalent to close status 1007.
+ /// Indicates that an endpoint is terminating the connection because it has received
+ /// a message that contains a data that isn't consistent with the type of the message.
+ /// </summary>
+ InconsistentData = 1007,
+ /// <summary>
+ /// Equivalent to close status 1008.
+ /// Indicates that an endpoint is terminating the connection because it has received
+ /// a message that violates its policy.
+ /// </summary>
+ PolicyViolation = 1008,
+ /// <summary>
+ /// Equivalent to close status 1009.
+ /// Indicates that an endpoint is terminating the connection because it has received
+ /// a message that is too big to process.
+ /// </summary>
+ TooBig = 1009,
+ /// <summary>
+ /// Equivalent to close status 1010.
+ /// Indicates that the client is terminating the connection because it has expected
+ /// the server to negotiate one or more extension, but the server didn't return them
+ /// in the handshake response.
+ /// </summary>
+ IgnoreExtension = 1010,
+ /// <summary>
+ /// Equivalent to close status 1011.
+ /// Indicates that the server is terminating the connection because it has encountered
+ /// an unexpected condition that prevented it from fulfilling the request.
+ /// </summary>
+ ServerError = 1011,
+ /// <summary>
+ /// Equivalent to close status 1015.
+ /// Indicates that the connection was closed due to a failure to perform a TLS handshake.
+ /// Reserved value.
+ /// </summary>
+ TlsHandshakeFailure = 1015
+ }
+}
diff --git a/SocketHttpListener.Portable/CompressionMethod.cs b/SocketHttpListener.Portable/CompressionMethod.cs
new file mode 100644
index 0000000000..36a48d94cb
--- /dev/null
+++ b/SocketHttpListener.Portable/CompressionMethod.cs
@@ -0,0 +1,23 @@
+namespace SocketHttpListener
+{
+ /// <summary>
+ /// Contains the values of the compression method used to compress the message on the WebSocket
+ /// connection.
+ /// </summary>
+ /// <remarks>
+ /// The values of the compression method are defined in
+ /// <see href="http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09">Compression
+ /// Extensions for WebSocket</see>.
+ /// </remarks>
+ public enum CompressionMethod : byte
+ {
+ /// <summary>
+ /// Indicates non compression.
+ /// </summary>
+ None,
+ /// <summary>
+ /// Indicates using DEFLATE.
+ /// </summary>
+ Deflate
+ }
+}
diff --git a/SocketHttpListener.Portable/ErrorEventArgs.cs b/SocketHttpListener.Portable/ErrorEventArgs.cs
new file mode 100644
index 0000000000..bf1d6fc95f
--- /dev/null
+++ b/SocketHttpListener.Portable/ErrorEventArgs.cs
@@ -0,0 +1,46 @@
+using System;
+
+namespace SocketHttpListener
+{
+ /// <summary>
+ /// Contains the event data associated with a <see cref="WebSocket.OnError"/> event.
+ /// </summary>
+ /// <remarks>
+ /// A <see cref="WebSocket.OnError"/> event occurs when the <see cref="WebSocket"/> gets an error.
+ /// If you would like to get the error message, you should access the <see cref="Message"/>
+ /// property.
+ /// </remarks>
+ public class ErrorEventArgs : EventArgs
+ {
+ #region Private Fields
+
+ private string _message;
+
+ #endregion
+
+ #region Internal Constructors
+
+ internal ErrorEventArgs (string message)
+ {
+ _message = message;
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the error message.
+ /// </summary>
+ /// <value>
+ /// A <see cref="string"/> that represents the error message.
+ /// </value>
+ public string Message {
+ get {
+ return _message;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/SocketHttpListener.Portable/Ext.cs b/SocketHttpListener.Portable/Ext.cs
new file mode 100644
index 0000000000..303263d0b9
--- /dev/null
+++ b/SocketHttpListener.Portable/Ext.cs
@@ -0,0 +1,1089 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+using System.IO.Compression;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Services;
+using SocketHttpListener.Net;
+using HttpListenerResponse = SocketHttpListener.Net.HttpListenerResponse;
+using HttpStatusCode = SocketHttpListener.Net.HttpStatusCode;
+
+namespace SocketHttpListener
+{
+ /// <summary>
+ /// Provides a set of static methods for the websocket-sharp.
+ /// </summary>
+ public static class Ext
+ {
+ #region Private Const Fields
+
+ private const string _tspecials = "()<>@,;:\\\"/[]?={} \t";
+
+ #endregion
+
+ #region Private Methods
+
+ private static MemoryStream compress(this Stream stream)
+ {
+ var output = new MemoryStream();
+ if (stream.Length == 0)
+ return output;
+
+ stream.Position = 0;
+ using (var ds = new DeflateStream(output, CompressionMode.Compress, true))
+ {
+ stream.CopyTo(ds);
+ //ds.Close(); // "BFINAL" set to 1.
+ output.Position = 0;
+
+ return output;
+ }
+ }
+
+ private static byte[] decompress(this byte[] value)
+ {
+ if (value.Length == 0)
+ return value;
+
+ using (var input = new MemoryStream(value))
+ {
+ return input.decompressToArray();
+ }
+ }
+
+ private static MemoryStream decompress(this Stream stream)
+ {
+ var output = new MemoryStream();
+ if (stream.Length == 0)
+ return output;
+
+ stream.Position = 0;
+ using (var ds = new DeflateStream(stream, CompressionMode.Decompress, true))
+ {
+ ds.CopyTo(output, true);
+ return output;
+ }
+ }
+
+ private static byte[] decompressToArray(this Stream stream)
+ {
+ using (var decomp = stream.decompress())
+ {
+ return decomp.ToArray();
+ }
+ }
+
+ private static byte[] readBytes(this Stream stream, byte[] buffer, int offset, int length)
+ {
+ var len = stream.Read(buffer, offset, length);
+ if (len < 1)
+ return buffer.SubArray(0, offset);
+
+ var tmp = 0;
+ while (len < length)
+ {
+ tmp = stream.Read(buffer, offset + len, length - len);
+ if (tmp < 1)
+ break;
+
+ len += tmp;
+ }
+
+ return len < length
+ ? buffer.SubArray(0, offset + len)
+ : buffer;
+ }
+
+ private static bool readBytes(
+ this Stream stream, byte[] buffer, int offset, int length, Stream dest)
+ {
+ var bytes = stream.readBytes(buffer, offset, length);
+ var len = bytes.Length;
+ dest.Write(bytes, 0, len);
+
+ return len == offset + length;
+ }
+
+ #endregion
+
+ #region Internal Methods
+
+ internal static byte[] Append(this ushort code, string reason)
+ {
+ using (var buffer = new MemoryStream())
+ {
+ var tmp = code.ToByteArrayInternally(ByteOrder.Big);
+ buffer.Write(tmp, 0, 2);
+ if (reason != null && reason.Length > 0)
+ {
+ tmp = Encoding.UTF8.GetBytes(reason);
+ buffer.Write(tmp, 0, tmp.Length);
+ }
+
+ return buffer.ToArray();
+ }
+ }
+
+ internal static string CheckIfClosable(this WebSocketState state)
+ {
+ return state == WebSocketState.Closing
+ ? "While closing the WebSocket connection."
+ : state == WebSocketState.Closed
+ ? "The WebSocket connection has already been closed."
+ : null;
+ }
+
+ internal static string CheckIfOpen(this WebSocketState state)
+ {
+ return state == WebSocketState.Connecting
+ ? "A WebSocket connection isn't established."
+ : state == WebSocketState.Closing
+ ? "While closing the WebSocket connection."
+ : state == WebSocketState.Closed
+ ? "The WebSocket connection has already been closed."
+ : null;
+ }
+
+ internal static string CheckIfValidControlData(this byte[] data, string paramName)
+ {
+ return data.Length > 125
+ ? String.Format("'{0}' length must be less.", paramName)
+ : null;
+ }
+
+ internal static string CheckIfValidSendData(this byte[] data)
+ {
+ return data == null
+ ? "'data' must not be null."
+ : null;
+ }
+
+ internal static string CheckIfValidSendData(this string data)
+ {
+ return data == null
+ ? "'data' must not be null."
+ : null;
+ }
+
+ internal static void Close(this HttpListenerResponse response, HttpStatusCode code)
+ {
+ response.StatusCode = (int)code;
+ response.OutputStream.Dispose();
+ }
+
+ internal static Stream Compress(this Stream stream, CompressionMethod method)
+ {
+ return method == CompressionMethod.Deflate
+ ? stream.compress()
+ : stream;
+ }
+
+ internal static bool Contains<T>(this IEnumerable<T> source, Func<T, bool> condition)
+ {
+ foreach (T elm in source)
+ if (condition(elm))
+ return true;
+
+ return false;
+ }
+
+ internal static void CopyTo(this Stream src, Stream dest, bool setDefaultPosition)
+ {
+ var readLen = 0;
+ var bufferLen = 256;
+ var buffer = new byte[bufferLen];
+ while ((readLen = src.Read(buffer, 0, bufferLen)) > 0)
+ {
+ dest.Write(buffer, 0, readLen);
+ }
+
+ if (setDefaultPosition)
+ dest.Position = 0;
+ }
+
+ internal static byte[] Decompress(this byte[] value, CompressionMethod method)
+ {
+ return method == CompressionMethod.Deflate
+ ? value.decompress()
+ : value;
+ }
+
+ internal static byte[] DecompressToArray(this Stream stream, CompressionMethod method)
+ {
+ return method == CompressionMethod.Deflate
+ ? stream.decompressToArray()
+ : stream.ToByteArray();
+ }
+
+ /// <summary>
+ /// Determines whether the specified <see cref="int"/> equals the specified <see cref="char"/>,
+ /// and invokes the specified Action&lt;int&gt; delegate at the same time.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if <paramref name="value"/> equals <paramref name="c"/>;
+ /// otherwise, <c>false</c>.
+ /// </returns>
+ /// <param name="value">
+ /// An <see cref="int"/> to compare.
+ /// </param>
+ /// <param name="c">
+ /// A <see cref="char"/> to compare.
+ /// </param>
+ /// <param name="action">
+ /// An Action&lt;int&gt; delegate that references the method(s) called at
+ /// the same time as comparing. An <see cref="int"/> parameter to pass to
+ /// the method(s) is <paramref name="value"/>.
+ /// </param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> isn't between 0 and 255.
+ /// </exception>
+ internal static bool EqualsWith(this int value, char c, Action<int> action)
+ {
+ if (value < 0 || value > 255)
+ throw new ArgumentOutOfRangeException("value");
+
+ action(value);
+ return value == c - 0;
+ }
+
+ internal static string GetMessage(this CloseStatusCode code)
+ {
+ return code == CloseStatusCode.ProtocolError
+ ? "A WebSocket protocol error has occurred."
+ : code == CloseStatusCode.IncorrectData
+ ? "An incorrect data has been received."
+ : code == CloseStatusCode.Abnormal
+ ? "An exception has occurred."
+ : code == CloseStatusCode.InconsistentData
+ ? "An inconsistent data has been received."
+ : code == CloseStatusCode.PolicyViolation
+ ? "A policy violation has occurred."
+ : code == CloseStatusCode.TooBig
+ ? "A too big data has been received."
+ : code == CloseStatusCode.IgnoreExtension
+ ? "WebSocket client did not receive expected extension(s)."
+ : code == CloseStatusCode.ServerError
+ ? "WebSocket server got an internal error."
+ : code == CloseStatusCode.TlsHandshakeFailure
+ ? "An error has occurred while handshaking."
+ : String.Empty;
+ }
+
+ internal static string GetNameInternal(this string nameAndValue, string separator)
+ {
+ var i = nameAndValue.IndexOf(separator);
+ return i > 0
+ ? nameAndValue.Substring(0, i).Trim()
+ : null;
+ }
+
+ internal static string GetValueInternal(this string nameAndValue, string separator)
+ {
+ var i = nameAndValue.IndexOf(separator);
+ return i >= 0 && i < nameAndValue.Length - 1
+ ? nameAndValue.Substring(i + 1).Trim()
+ : null;
+ }
+
+ internal static bool IsCompressionExtension(this string value, CompressionMethod method)
+ {
+ return value.StartsWith(method.ToExtensionString());
+ }
+
+ internal static bool IsPortNumber(this int value)
+ {
+ return value > 0 && value < 65536;
+ }
+
+ internal static bool IsReserved(this ushort code)
+ {
+ return code == (ushort)CloseStatusCode.Undefined ||
+ code == (ushort)CloseStatusCode.NoStatusCode ||
+ code == (ushort)CloseStatusCode.Abnormal ||
+ code == (ushort)CloseStatusCode.TlsHandshakeFailure;
+ }
+
+ internal static bool IsReserved(this CloseStatusCode code)
+ {
+ return code == CloseStatusCode.Undefined ||
+ code == CloseStatusCode.NoStatusCode ||
+ code == CloseStatusCode.Abnormal ||
+ code == CloseStatusCode.TlsHandshakeFailure;
+ }
+
+ internal static bool IsText(this string value)
+ {
+ var len = value.Length;
+ for (var i = 0; i < len; i++)
+ {
+ char c = value[i];
+ if (c < 0x20 && !"\r\n\t".Contains(c))
+ return false;
+
+ if (c == 0x7f)
+ return false;
+
+ if (c == '\n' && ++i < len)
+ {
+ c = value[i];
+ if (!" \t".Contains(c))
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ internal static bool IsToken(this string value)
+ {
+ foreach (char c in value)
+ if (c < 0x20 || c >= 0x7f || _tspecials.Contains(c))
+ return false;
+
+ return true;
+ }
+
+ internal static string Quote(this string value)
+ {
+ return value.IsToken()
+ ? value
+ : String.Format("\"{0}\"", value.Replace("\"", "\\\""));
+ }
+
+ internal static byte[] ReadBytes(this Stream stream, int length)
+ {
+ return stream.readBytes(new byte[length], 0, length);
+ }
+
+ internal static byte[] ReadBytes(this Stream stream, long length, int bufferLength)
+ {
+ using (var result = new MemoryStream())
+ {
+ var count = length / bufferLength;
+ var rem = (int)(length % bufferLength);
+
+ var buffer = new byte[bufferLength];
+ var end = false;
+ for (long i = 0; i < count; i++)
+ {
+ if (!stream.readBytes(buffer, 0, bufferLength, result))
+ {
+ end = true;
+ break;
+ }
+ }
+
+ if (!end && rem > 0)
+ stream.readBytes(new byte[rem], 0, rem, result);
+
+ return result.ToArray();
+ }
+ }
+
+ internal static async Task<byte[]> ReadBytesAsync(this Stream stream, int length)
+ {
+ var buffer = new byte[length];
+
+ var len = await stream.ReadAsync(buffer, 0, length).ConfigureAwait(false);
+ var bytes = len < 1
+ ? new byte[0]
+ : len < length
+ ? stream.readBytes(buffer, len, length - len)
+ : buffer;
+
+ return bytes;
+ }
+
+ internal static string RemovePrefix(this string value, params string[] prefixes)
+ {
+ var i = 0;
+ foreach (var prefix in prefixes)
+ {
+ if (value.StartsWith(prefix))
+ {
+ i = prefix.Length;
+ break;
+ }
+ }
+
+ return i > 0
+ ? value.Substring(i)
+ : value;
+ }
+
+ internal static T[] Reverse<T>(this T[] array)
+ {
+ var len = array.Length;
+ T[] reverse = new T[len];
+
+ var end = len - 1;
+ for (var i = 0; i <= end; i++)
+ reverse[i] = array[end - i];
+
+ return reverse;
+ }
+
+ internal static IEnumerable<string> SplitHeaderValue(
+ this string value, params char[] separator)
+ {
+ var len = value.Length;
+ var separators = new string(separator);
+
+ var buffer = new StringBuilder(32);
+ var quoted = false;
+ var escaped = false;
+
+ char c;
+ for (var i = 0; i < len; i++)
+ {
+ c = value[i];
+ if (c == '"')
+ {
+ if (escaped)
+ escaped = !escaped;
+ else
+ quoted = !quoted;
+ }
+ else if (c == '\\')
+ {
+ if (i < len - 1 && value[i + 1] == '"')
+ escaped = true;
+ }
+ else if (separators.Contains(c))
+ {
+ if (!quoted)
+ {
+ yield return buffer.ToString();
+ buffer.Length = 0;
+
+ continue;
+ }
+ }
+ else {
+ }
+
+ buffer.Append(c);
+ }
+
+ if (buffer.Length > 0)
+ yield return buffer.ToString();
+ }
+
+ internal static byte[] ToByteArray(this Stream stream)
+ {
+ using (var output = new MemoryStream())
+ {
+ stream.Position = 0;
+ stream.CopyTo(output);
+
+ return output.ToArray();
+ }
+ }
+
+ internal static byte[] ToByteArrayInternally(this ushort value, ByteOrder order)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ if (!order.IsHostOrder())
+ Array.Reverse(bytes);
+
+ return bytes;
+ }
+
+ internal static byte[] ToByteArrayInternally(this ulong value, ByteOrder order)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ if (!order.IsHostOrder())
+ Array.Reverse(bytes);
+
+ return bytes;
+ }
+
+ internal static string ToExtensionString(
+ this CompressionMethod method, params string[] parameters)
+ {
+ if (method == CompressionMethod.None)
+ return String.Empty;
+
+ var m = String.Format("permessage-{0}", method.ToString().ToLower());
+ if (parameters == null || parameters.Length == 0)
+ return m;
+
+ return String.Format("{0}; {1}", m, parameters.ToString("; "));
+ }
+
+ internal static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
+ {
+ return new List<TSource>(source);
+ }
+
+ internal static ushort ToUInt16(this byte[] src, ByteOrder srcOrder)
+ {
+ return BitConverter.ToUInt16(src.ToHostOrder(srcOrder), 0);
+ }
+
+ internal static ulong ToUInt64(this byte[] src, ByteOrder srcOrder)
+ {
+ return BitConverter.ToUInt64(src.ToHostOrder(srcOrder), 0);
+ }
+
+ internal static string TrimEndSlash(this string value)
+ {
+ value = value.TrimEnd('/');
+ return value.Length > 0
+ ? value
+ : "/";
+ }
+
+ internal static string Unquote(this string value)
+ {
+ var start = value.IndexOf('\"');
+ var end = value.LastIndexOf('\"');
+ if (start < end)
+ value = value.Substring(start + 1, end - start - 1).Replace("\\\"", "\"");
+
+ return value.Trim();
+ }
+
+ internal static void WriteBytes(this Stream stream, byte[] value)
+ {
+ using (var src = new MemoryStream(value))
+ {
+ src.CopyTo(stream);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Determines whether the specified <see cref="string"/> contains any of characters
+ /// in the specified array of <see cref="char"/>.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if <paramref name="value"/> contains any of <paramref name="chars"/>;
+ /// otherwise, <c>false</c>.
+ /// </returns>
+ /// <param name="value">
+ /// A <see cref="string"/> to test.
+ /// </param>
+ /// <param name="chars">
+ /// An array of <see cref="char"/> that contains characters to find.
+ /// </param>
+ public static bool Contains(this string value, params char[] chars)
+ {
+ return chars == null || chars.Length == 0
+ ? true
+ : value == null || value.Length == 0
+ ? false
+ : value.IndexOfAny(chars) != -1;
+ }
+
+ /// <summary>
+ /// Determines whether the specified <see cref="QueryParamCollection"/> contains the entry
+ /// with the specified <paramref name="name"/>.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if <paramref name="collection"/> contains the entry
+ /// with <paramref name="name"/>; otherwise, <c>false</c>.
+ /// </returns>
+ /// <param name="collection">
+ /// A <see cref="QueryParamCollection"/> to test.
+ /// </param>
+ /// <param name="name">
+ /// A <see cref="string"/> that represents the key of the entry to find.
+ /// </param>
+ public static bool Contains(this QueryParamCollection collection, string name)
+ {
+ return collection == null || collection.Count == 0
+ ? false
+ : collection[name] != null;
+ }
+
+ /// <summary>
+ /// Determines whether the specified <see cref="QueryParamCollection"/> contains the entry
+ /// with the specified both <paramref name="name"/> and <paramref name="value"/>.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if <paramref name="collection"/> contains the entry
+ /// with both <paramref name="name"/> and <paramref name="value"/>;
+ /// otherwise, <c>false</c>.
+ /// </returns>
+ /// <param name="collection">
+ /// A <see cref="QueryParamCollection"/> to test.
+ /// </param>
+ /// <param name="name">
+ /// A <see cref="string"/> that represents the key of the entry to find.
+ /// </param>
+ /// <param name="value">
+ /// A <see cref="string"/> that represents the value of the entry to find.
+ /// </param>
+ public static bool Contains(this QueryParamCollection collection, string name, string value)
+ {
+ if (collection == null || collection.Count == 0)
+ return false;
+
+ var values = collection[name];
+ if (values == null)
+ return false;
+
+ foreach (var v in values.Split(','))
+ if (v.Trim().Equals(value, StringComparison.OrdinalIgnoreCase))
+ return true;
+
+ return false;
+ }
+
+ /// <summary>
+ /// Emits the specified <see cref="EventHandler"/> delegate if it isn't <see langword="null"/>.
+ /// </summary>
+ /// <param name="eventHandler">
+ /// A <see cref="EventHandler"/> to emit.
+ /// </param>
+ /// <param name="sender">
+ /// An <see cref="object"/> from which emits this <paramref name="eventHandler"/>.
+ /// </param>
+ /// <param name="e">
+ /// A <see cref="EventArgs"/> that contains no event data.
+ /// </param>
+ public static void Emit(this EventHandler eventHandler, object sender, EventArgs e)
+ {
+ if (eventHandler != null)
+ eventHandler(sender, e);
+ }
+
+ /// <summary>
+ /// Emits the specified <c>EventHandler&lt;TEventArgs&gt;</c> delegate
+ /// if it isn't <see langword="null"/>.
+ /// </summary>
+ /// <param name="eventHandler">
+ /// An <c>EventHandler&lt;TEventArgs&gt;</c> to emit.
+ /// </param>
+ /// <param name="sender">
+ /// An <see cref="object"/> from which emits this <paramref name="eventHandler"/>.
+ /// </param>
+ /// <param name="e">
+ /// A <c>TEventArgs</c> that represents the event data.
+ /// </param>
+ /// <typeparam name="TEventArgs">
+ /// The type of the event data generated by the event.
+ /// </typeparam>
+ public static void Emit<TEventArgs>(
+ this EventHandler<TEventArgs> eventHandler, object sender, TEventArgs e)
+ where TEventArgs : EventArgs
+ {
+ if (eventHandler != null)
+ eventHandler(sender, e);
+ }
+
+ /// <summary>
+ /// Gets the collection of the HTTP cookies from the specified HTTP <paramref name="headers"/>.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="CookieCollection"/> that receives a collection of the HTTP cookies.
+ /// </returns>
+ /// <param name="headers">
+ /// A <see cref="QueryParamCollection"/> that contains a collection of the HTTP headers.
+ /// </param>
+ /// <param name="response">
+ /// <c>true</c> if <paramref name="headers"/> is a collection of the response headers;
+ /// otherwise, <c>false</c>.
+ /// </param>
+ public static CookieCollection GetCookies(this QueryParamCollection headers, bool response)
+ {
+ var name = response ? "Set-Cookie" : "Cookie";
+ return headers == null || !headers.Contains(name)
+ ? new CookieCollection()
+ : CookieHelper.Parse(headers[name], response);
+ }
+
+ /// <summary>
+ /// Gets the description of the specified HTTP status <paramref name="code"/>.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="string"/> that represents the description of the HTTP status code.
+ /// </returns>
+ /// <param name="code">
+ /// One of <see cref="HttpStatusCode"/> enum values, indicates the HTTP status codes.
+ /// </param>
+ public static string GetDescription(this HttpStatusCode code)
+ {
+ return ((int)code).GetStatusDescription();
+ }
+
+ /// <summary>
+ /// Gets the name from the specified <see cref="string"/> that contains a pair of name and
+ /// value separated by a separator string.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="string"/> that represents the name if any; otherwise, <c>null</c>.
+ /// </returns>
+ /// <param name="nameAndValue">
+ /// A <see cref="string"/> that contains a pair of name and value separated by a separator
+ /// string.
+ /// </param>
+ /// <param name="separator">
+ /// A <see cref="string"/> that represents a separator string.
+ /// </param>
+ public static string GetName(this string nameAndValue, string separator)
+ {
+ return (nameAndValue != null && nameAndValue.Length > 0) &&
+ (separator != null && separator.Length > 0)
+ ? nameAndValue.GetNameInternal(separator)
+ : null;
+ }
+
+ /// <summary>
+ /// Gets the name and value from the specified <see cref="string"/> that contains a pair of
+ /// name and value separated by a separator string.
+ /// </summary>
+ /// <returns>
+ /// A <c>KeyValuePair&lt;string, string&gt;</c> that represents the name and value if any.
+ /// </returns>
+ /// <param name="nameAndValue">
+ /// A <see cref="string"/> that contains a pair of name and value separated by a separator
+ /// string.
+ /// </param>
+ /// <param name="separator">
+ /// A <see cref="string"/> that represents a separator string.
+ /// </param>
+ public static KeyValuePair<string, string> GetNameAndValue(
+ this string nameAndValue, string separator)
+ {
+ var name = nameAndValue.GetName(separator);
+ var value = nameAndValue.GetValue(separator);
+ return name != null
+ ? new KeyValuePair<string, string>(name, value)
+ : new KeyValuePair<string, string>(null, null);
+ }
+
+ /// <summary>
+ /// Gets the description of the specified HTTP status <paramref name="code"/>.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="string"/> that represents the description of the HTTP status code.
+ /// </returns>
+ /// <param name="code">
+ /// An <see cref="int"/> that represents the HTTP status code.
+ /// </param>
+ public static string GetStatusDescription(this int code)
+ {
+ switch (code)
+ {
+ case 100: return "Continue";
+ case 101: return "Switching Protocols";
+ case 102: return "Processing";
+ case 200: return "OK";
+ case 201: return "Created";
+ case 202: return "Accepted";
+ case 203: return "Non-Authoritative Information";
+ case 204: return "No Content";
+ case 205: return "Reset Content";
+ case 206: return "Partial Content";
+ case 207: return "Multi-Status";
+ case 300: return "Multiple Choices";
+ case 301: return "Moved Permanently";
+ case 302: return "Found";
+ case 303: return "See Other";
+ case 304: return "Not Modified";
+ case 305: return "Use Proxy";
+ case 307: return "Temporary Redirect";
+ case 400: return "Bad Request";
+ case 401: return "Unauthorized";
+ case 402: return "Payment Required";
+ case 403: return "Forbidden";
+ case 404: return "Not Found";
+ case 405: return "Method Not Allowed";
+ case 406: return "Not Acceptable";
+ case 407: return "Proxy Authentication Required";
+ case 408: return "Request Timeout";
+ case 409: return "Conflict";
+ case 410: return "Gone";
+ case 411: return "Length Required";
+ case 412: return "Precondition Failed";
+ case 413: return "Request Entity Too Large";
+ case 414: return "Request-Uri Too Long";
+ case 415: return "Unsupported Media Type";
+ case 416: return "Requested Range Not Satisfiable";
+ case 417: return "Expectation Failed";
+ case 422: return "Unprocessable Entity";
+ case 423: return "Locked";
+ case 424: return "Failed Dependency";
+ case 500: return "Internal Server Error";
+ case 501: return "Not Implemented";
+ case 502: return "Bad Gateway";
+ case 503: return "Service Unavailable";
+ case 504: return "Gateway Timeout";
+ case 505: return "Http Version Not Supported";
+ case 507: return "Insufficient Storage";
+ }
+
+ return String.Empty;
+ }
+
+ /// <summary>
+ /// Gets the value from the specified <see cref="string"/> that contains a pair of name and
+ /// value separated by a separator string.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="string"/> that represents the value if any; otherwise, <c>null</c>.
+ /// </returns>
+ /// <param name="nameAndValue">
+ /// A <see cref="string"/> that contains a pair of name and value separated by a separator
+ /// string.
+ /// </param>
+ /// <param name="separator">
+ /// A <see cref="string"/> that represents a separator string.
+ /// </param>
+ public static string GetValue(this string nameAndValue, string separator)
+ {
+ return (nameAndValue != null && nameAndValue.Length > 0) &&
+ (separator != null && separator.Length > 0)
+ ? nameAndValue.GetValueInternal(separator)
+ : null;
+ }
+
+ /// <summary>
+ /// Determines whether the specified <see cref="ByteOrder"/> is host
+ /// (this computer architecture) byte order.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if <paramref name="order"/> is host byte order;
+ /// otherwise, <c>false</c>.
+ /// </returns>
+ /// <param name="order">
+ /// One of the <see cref="ByteOrder"/> enum values, to test.
+ /// </param>
+ public static bool IsHostOrder(this ByteOrder order)
+ {
+ // true : !(true ^ true) or !(false ^ false)
+ // false: !(true ^ false) or !(false ^ true)
+ return !(BitConverter.IsLittleEndian ^ (order == ByteOrder.Little));
+ }
+
+ /// <summary>
+ /// Determines whether the specified <see cref="string"/> is a predefined scheme.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if <paramref name="value"/> is a predefined scheme; otherwise, <c>false</c>.
+ /// </returns>
+ /// <param name="value">
+ /// A <see cref="string"/> to test.
+ /// </param>
+ public static bool IsPredefinedScheme(this string value)
+ {
+ if (value == null || value.Length < 2)
+ return false;
+
+ var c = value[0];
+ if (c == 'h')
+ return value == "http" || value == "https";
+
+ if (c == 'w')
+ return value == "ws" || value == "wss";
+
+ if (c == 'f')
+ return value == "file" || value == "ftp";
+
+ if (c == 'n')
+ {
+ c = value[1];
+ return c == 'e'
+ ? value == "news" || value == "net.pipe" || value == "net.tcp"
+ : value == "nntp";
+ }
+
+ return (c == 'g' && value == "gopher") || (c == 'm' && value == "mailto");
+ }
+
+ /// <summary>
+ /// Determines whether the specified <see cref="string"/> is a URI string.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if <paramref name="value"/> may be a URI string; otherwise, <c>false</c>.
+ /// </returns>
+ /// <param name="value">
+ /// A <see cref="string"/> to test.
+ /// </param>
+ public static bool MaybeUri(this string value)
+ {
+ if (value == null || value.Length == 0)
+ return false;
+
+ var i = value.IndexOf(':');
+ if (i == -1)
+ return false;
+
+ if (i >= 10)
+ return false;
+
+ return value.Substring(0, i).IsPredefinedScheme();
+ }
+
+ /// <summary>
+ /// Retrieves a sub-array from the specified <paramref name="array"/>.
+ /// A sub-array starts at the specified element position.
+ /// </summary>
+ /// <returns>
+ /// An array of T that receives a sub-array, or an empty array of T if any problems
+ /// with the parameters.
+ /// </returns>
+ /// <param name="array">
+ /// An array of T that contains the data to retrieve a sub-array.
+ /// </param>
+ /// <param name="startIndex">
+ /// An <see cref="int"/> that contains the zero-based starting position of a sub-array
+ /// in <paramref name="array"/>.
+ /// </param>
+ /// <param name="length">
+ /// An <see cref="int"/> that contains the number of elements to retrieve a sub-array.
+ /// </param>
+ /// <typeparam name="T">
+ /// The type of elements in the <paramref name="array"/>.
+ /// </typeparam>
+ public static T[] SubArray<T>(this T[] array, int startIndex, int length)
+ {
+ if (array == null || array.Length == 0)
+ return new T[0];
+
+ if (startIndex < 0 || length <= 0)
+ return new T[0];
+
+ if (startIndex + length > array.Length)
+ return new T[0];
+
+ if (startIndex == 0 && array.Length == length)
+ return array;
+
+ T[] subArray = new T[length];
+ Array.Copy(array, startIndex, subArray, 0, length);
+
+ return subArray;
+ }
+
+ /// <summary>
+ /// Converts the order of the specified array of <see cref="byte"/> to the host byte order.
+ /// </summary>
+ /// <returns>
+ /// An array of <see cref="byte"/> converted from <paramref name="src"/>.
+ /// </returns>
+ /// <param name="src">
+ /// An array of <see cref="byte"/> to convert.
+ /// </param>
+ /// <param name="srcOrder">
+ /// One of the <see cref="ByteOrder"/> enum values, indicates the byte order of
+ /// <paramref name="src"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="src"/> is <see langword="null"/>.
+ /// </exception>
+ public static byte[] ToHostOrder(this byte[] src, ByteOrder srcOrder)
+ {
+ if (src == null)
+ throw new ArgumentNullException("src");
+
+ return src.Length > 1 && !srcOrder.IsHostOrder()
+ ? src.Reverse()
+ : src;
+ }
+
+ /// <summary>
+ /// Converts the specified <paramref name="array"/> to a <see cref="string"/> that
+ /// concatenates the each element of <paramref name="array"/> across the specified
+ /// <paramref name="separator"/>.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="string"/> converted from <paramref name="array"/>,
+ /// or <see cref="String.Empty"/> if <paramref name="array"/> is empty.
+ /// </returns>
+ /// <param name="array">
+ /// An array of T to convert.
+ /// </param>
+ /// <param name="separator">
+ /// A <see cref="string"/> that represents the separator string.
+ /// </param>
+ /// <typeparam name="T">
+ /// The type of elements in <paramref name="array"/>.
+ /// </typeparam>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="array"/> is <see langword="null"/>.
+ /// </exception>
+ public static string ToString<T>(this T[] array, string separator)
+ {
+ if (array == null)
+ throw new ArgumentNullException("array");
+
+ var len = array.Length;
+ if (len == 0)
+ return String.Empty;
+
+ if (separator == null)
+ separator = String.Empty;
+
+ var buff = new StringBuilder(64);
+ (len - 1).Times(i => buff.AppendFormat("{0}{1}", array[i].ToString(), separator));
+
+ buff.Append(array[len - 1].ToString());
+ return buff.ToString();
+ }
+
+ /// <summary>
+ /// Executes the specified <c>Action&lt;int&gt;</c> delegate <paramref name="n"/> times.
+ /// </summary>
+ /// <param name="n">
+ /// An <see cref="int"/> is the number of times to execute.
+ /// </param>
+ /// <param name="action">
+ /// An <c>Action&lt;int&gt;</c> delegate that references the method(s) to execute.
+ /// An <see cref="int"/> parameter to pass to the method(s) is the zero-based count of
+ /// iteration.
+ /// </param>
+ public static void Times(this int n, Action<int> action)
+ {
+ if (n > 0 && action != null)
+ for (int i = 0; i < n; i++)
+ action(i);
+ }
+
+ /// <summary>
+ /// Converts the specified <see cref="string"/> to a <see cref="Uri"/>.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="Uri"/> converted from <paramref name="uriString"/>, or <see langword="null"/>
+ /// if <paramref name="uriString"/> isn't successfully converted.
+ /// </returns>
+ /// <param name="uriString">
+ /// A <see cref="string"/> to convert.
+ /// </param>
+ public static Uri ToUri(this string uriString)
+ {
+ Uri res;
+ return Uri.TryCreate(
+ uriString, uriString.MaybeUri() ? UriKind.Absolute : UriKind.Relative, out res)
+ ? res
+ : null;
+ }
+
+ /// <summary>
+ /// URL-decodes the specified <see cref="string"/>.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="string"/> that receives the decoded string, or the <paramref name="value"/>
+ /// if it's <see langword="null"/> or empty.
+ /// </returns>
+ /// <param name="value">
+ /// A <see cref="string"/> to decode.
+ /// </param>
+ public static string UrlDecode(this string value)
+ {
+ return value == null || value.Length == 0
+ ? value
+ : WebUtility.UrlDecode(value);
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/SocketHttpListener.Portable/Fin.cs b/SocketHttpListener.Portable/Fin.cs
new file mode 100644
index 0000000000..f91401b995
--- /dev/null
+++ b/SocketHttpListener.Portable/Fin.cs
@@ -0,0 +1,8 @@
+namespace SocketHttpListener
+{
+ internal enum Fin : byte
+ {
+ More = 0x0,
+ Final = 0x1
+ }
+}
diff --git a/SocketHttpListener.Portable/HttpBase.cs b/SocketHttpListener.Portable/HttpBase.cs
new file mode 100644
index 0000000000..5172ba4975
--- /dev/null
+++ b/SocketHttpListener.Portable/HttpBase.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+using System.Text;
+using System.Threading;
+using MediaBrowser.Model.Services;
+
+namespace SocketHttpListener
+{
+ internal abstract class HttpBase
+ {
+ #region Private Fields
+
+ private QueryParamCollection _headers;
+ private Version _version;
+
+ #endregion
+
+ #region Internal Fields
+
+ internal byte[] EntityBodyData;
+
+ #endregion
+
+ #region Protected Fields
+
+ protected const string CrLf = "\r\n";
+
+ #endregion
+
+ #region Protected Constructors
+
+ protected HttpBase(Version version, QueryParamCollection headers)
+ {
+ _version = version;
+ _headers = headers;
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ public string EntityBody
+ {
+ get
+ {
+ var data = EntityBodyData;
+
+ return data != null && data.Length > 0
+ ? getEncoding(_headers["Content-Type"]).GetString(data, 0, data.Length)
+ : String.Empty;
+ }
+ }
+
+ public QueryParamCollection Headers
+ {
+ get
+ {
+ return _headers;
+ }
+ }
+
+ public Version ProtocolVersion
+ {
+ get
+ {
+ return _version;
+ }
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private static Encoding getEncoding(string contentType)
+ {
+ if (contentType == null || contentType.Length == 0)
+ return Encoding.UTF8;
+
+ var i = contentType.IndexOf("charset=", StringComparison.Ordinal);
+ if (i == -1)
+ return Encoding.UTF8;
+
+ var charset = contentType.Substring(i + 8);
+ i = charset.IndexOf(';');
+ if (i != -1)
+ charset = charset.Substring(0, i).TrimEnd();
+
+ return Encoding.GetEncoding(charset.Trim('"'));
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public byte[] ToByteArray()
+ {
+ return Encoding.UTF8.GetBytes(ToString());
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/SocketHttpListener.Portable/HttpResponse.cs b/SocketHttpListener.Portable/HttpResponse.cs
new file mode 100644
index 0000000000..5aca28c7c3
--- /dev/null
+++ b/SocketHttpListener.Portable/HttpResponse.cs
@@ -0,0 +1,161 @@
+using System;
+using System.Collections.Specialized;
+using System.IO;
+using System.Net;
+using System.Text;
+using HttpStatusCode = SocketHttpListener.Net.HttpStatusCode;
+using HttpVersion = SocketHttpListener.Net.HttpVersion;
+using System.Linq;
+using MediaBrowser.Model.Services;
+
+namespace SocketHttpListener
+{
+ internal class HttpResponse : HttpBase
+ {
+ #region Private Fields
+
+ private string _code;
+ private string _reason;
+
+ #endregion
+
+ #region Private Constructors
+
+ private HttpResponse(string code, string reason, Version version, QueryParamCollection headers)
+ : base(version, headers)
+ {
+ _code = code;
+ _reason = reason;
+ }
+
+ #endregion
+
+ #region Internal Constructors
+
+ internal HttpResponse(HttpStatusCode code)
+ : this(code, code.GetDescription())
+ {
+ }
+
+ internal HttpResponse(HttpStatusCode code, string reason)
+ : this(((int)code).ToString(), reason, HttpVersion.Version11, new QueryParamCollection())
+ {
+ Headers["Server"] = "websocket-sharp/1.0";
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ public CookieCollection Cookies
+ {
+ get
+ {
+ return Headers.GetCookies(true);
+ }
+ }
+
+ public bool IsProxyAuthenticationRequired
+ {
+ get
+ {
+ return _code == "407";
+ }
+ }
+
+ public bool IsUnauthorized
+ {
+ get
+ {
+ return _code == "401";
+ }
+ }
+
+ public bool IsWebSocketResponse
+ {
+ get
+ {
+ var headers = Headers;
+ return ProtocolVersion > HttpVersion.Version10 &&
+ _code == "101" &&
+ headers.Contains("Upgrade", "websocket") &&
+ headers.Contains("Connection", "Upgrade");
+ }
+ }
+
+ public string Reason
+ {
+ get
+ {
+ return _reason;
+ }
+ }
+
+ public string StatusCode
+ {
+ get
+ {
+ return _code;
+ }
+ }
+
+ #endregion
+
+ #region Internal Methods
+
+ internal static HttpResponse CreateCloseResponse(HttpStatusCode code)
+ {
+ var res = new HttpResponse(code);
+ res.Headers["Connection"] = "close";
+
+ return res;
+ }
+
+ internal static HttpResponse CreateWebSocketResponse()
+ {
+ var res = new HttpResponse(HttpStatusCode.SwitchingProtocols);
+
+ var headers = res.Headers;
+ headers["Upgrade"] = "websocket";
+ headers["Connection"] = "Upgrade";
+
+ return res;
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public void SetCookies(CookieCollection cookies)
+ {
+ if (cookies == null || cookies.Count == 0)
+ return;
+
+ var headers = Headers;
+ var sorted = cookies.OfType<Cookie>().OrderBy(i => i.Name).ToList();
+
+ foreach (var cookie in sorted)
+ headers.Add("Set-Cookie", cookie.ToString());
+ }
+
+ public override string ToString()
+ {
+ var output = new StringBuilder(64);
+ output.AppendFormat("HTTP/{0} {1} {2}{3}", ProtocolVersion, _code, _reason, CrLf);
+
+ var headers = Headers;
+ foreach (var key in headers.Keys)
+ output.AppendFormat("{0}: {1}{2}", key, headers[key], CrLf);
+
+ output.Append(CrLf);
+
+ var entity = EntityBody;
+ if (entity.Length > 0)
+ output.Append(entity);
+
+ return output.ToString();
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/SocketHttpListener.Portable/Mask.cs b/SocketHttpListener.Portable/Mask.cs
new file mode 100644
index 0000000000..adc2f098e9
--- /dev/null
+++ b/SocketHttpListener.Portable/Mask.cs
@@ -0,0 +1,8 @@
+namespace SocketHttpListener
+{
+ internal enum Mask : byte
+ {
+ Unmask = 0x0,
+ Mask = 0x1
+ }
+}
diff --git a/SocketHttpListener.Portable/MessageEventArgs.cs b/SocketHttpListener.Portable/MessageEventArgs.cs
new file mode 100644
index 0000000000..9dbadb9ab2
--- /dev/null
+++ b/SocketHttpListener.Portable/MessageEventArgs.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Text;
+
+namespace SocketHttpListener
+{
+ /// <summary>
+ /// Contains the event data associated with a <see cref="WebSocket.OnMessage"/> event.
+ /// </summary>
+ /// <remarks>
+ /// A <see cref="WebSocket.OnMessage"/> event occurs when the <see cref="WebSocket"/> receives
+ /// a text or binary data frame.
+ /// If you want to get the received data, you access the <see cref="MessageEventArgs.Data"/> or
+ /// <see cref="MessageEventArgs.RawData"/> property.
+ /// </remarks>
+ public class MessageEventArgs : EventArgs
+ {
+ #region Private Fields
+
+ private string _data;
+ private Opcode _opcode;
+ private byte[] _rawData;
+
+ #endregion
+
+ #region Internal Constructors
+
+ internal MessageEventArgs (Opcode opcode, byte[] data)
+ {
+ _opcode = opcode;
+ _rawData = data;
+ _data = convertToString (opcode, data);
+ }
+
+ internal MessageEventArgs (Opcode opcode, PayloadData payload)
+ {
+ _opcode = opcode;
+ _rawData = payload.ApplicationData;
+ _data = convertToString (opcode, _rawData);
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the received data as a <see cref="string"/>.
+ /// </summary>
+ /// <value>
+ /// A <see cref="string"/> that contains the received data.
+ /// </value>
+ public string Data {
+ get {
+ return _data;
+ }
+ }
+
+ /// <summary>
+ /// Gets the received data as an array of <see cref="byte"/>.
+ /// </summary>
+ /// <value>
+ /// An array of <see cref="byte"/> that contains the received data.
+ /// </value>
+ public byte [] RawData {
+ get {
+ return _rawData;
+ }
+ }
+
+ /// <summary>
+ /// Gets the type of the received data.
+ /// </summary>
+ /// <value>
+ /// One of the <see cref="Opcode"/> values, indicates the type of the received data.
+ /// </value>
+ public Opcode Type {
+ get {
+ return _opcode;
+ }
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private static string convertToString (Opcode opcode, byte [] data)
+ {
+ return data.Length == 0
+ ? String.Empty
+ : opcode == Opcode.Text
+ ? Encoding.UTF8.GetString (data, 0, data.Length)
+ : opcode.ToString ();
+ }
+
+ #endregion
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/AuthenticationSchemeSelector.cs b/SocketHttpListener.Portable/Net/AuthenticationSchemeSelector.cs
new file mode 100644
index 0000000000..c6e7e538ec
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/AuthenticationSchemeSelector.cs
@@ -0,0 +1,6 @@
+using System.Net;
+
+namespace SocketHttpListener.Net
+{
+ public delegate AuthenticationSchemes AuthenticationSchemeSelector(HttpListenerRequest httpRequest);
+}
diff --git a/SocketHttpListener.Portable/Net/ChunkStream.cs b/SocketHttpListener.Portable/Net/ChunkStream.cs
new file mode 100644
index 0000000000..3f3b4a667a
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/ChunkStream.cs
@@ -0,0 +1,371 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Net;
+using System.Text;
+
+namespace SocketHttpListener.Net
+{
+ class ChunkStream
+ {
+ enum State
+ {
+ None,
+ PartialSize,
+ Body,
+ BodyFinished,
+ Trailer
+ }
+
+ class Chunk
+ {
+ public byte[] Bytes;
+ public int Offset;
+
+ public Chunk(byte[] chunk)
+ {
+ this.Bytes = chunk;
+ }
+
+ public int Read(byte[] buffer, int offset, int size)
+ {
+ int nread = (size > Bytes.Length - Offset) ? Bytes.Length - Offset : size;
+ Buffer.BlockCopy(Bytes, Offset, buffer, offset, nread);
+ Offset += nread;
+ return nread;
+ }
+ }
+
+ internal WebHeaderCollection headers;
+ int chunkSize;
+ int chunkRead;
+ int totalWritten;
+ State state;
+ //byte [] waitBuffer;
+ StringBuilder saved;
+ bool sawCR;
+ bool gotit;
+ int trailerState;
+ List<Chunk> chunks;
+
+ public ChunkStream(WebHeaderCollection headers)
+ {
+ this.headers = headers;
+ saved = new StringBuilder();
+ chunks = new List<Chunk>();
+ chunkSize = -1;
+ totalWritten = 0;
+ }
+
+ public void ResetBuffer()
+ {
+ chunkSize = -1;
+ chunkRead = 0;
+ totalWritten = 0;
+ chunks.Clear();
+ }
+
+ public void WriteAndReadBack(byte[] buffer, int offset, int size, ref int read)
+ {
+ if (offset + read > 0)
+ Write(buffer, offset, offset + read);
+ read = Read(buffer, offset, size);
+ }
+
+ public int Read(byte[] buffer, int offset, int size)
+ {
+ return ReadFromChunks(buffer, offset, size);
+ }
+
+ int ReadFromChunks(byte[] buffer, int offset, int size)
+ {
+ int count = chunks.Count;
+ int nread = 0;
+
+ var chunksForRemoving = new List<Chunk>(count);
+ for (int i = 0; i < count; i++)
+ {
+ Chunk chunk = (Chunk)chunks[i];
+
+ if (chunk.Offset == chunk.Bytes.Length)
+ {
+ chunksForRemoving.Add(chunk);
+ continue;
+ }
+
+ nread += chunk.Read(buffer, offset + nread, size - nread);
+ if (nread == size)
+ break;
+ }
+
+ foreach (var chunk in chunksForRemoving)
+ chunks.Remove(chunk);
+
+ return nread;
+ }
+
+ public void Write(byte[] buffer, int offset, int size)
+ {
+ if (offset < size)
+ InternalWrite(buffer, ref offset, size);
+ }
+
+ void InternalWrite(byte[] buffer, ref int offset, int size)
+ {
+ if (state == State.None || state == State.PartialSize)
+ {
+ state = GetChunkSize(buffer, ref offset, size);
+ if (state == State.PartialSize)
+ return;
+
+ saved.Length = 0;
+ sawCR = false;
+ gotit = false;
+ }
+
+ if (state == State.Body && offset < size)
+ {
+ state = ReadBody(buffer, ref offset, size);
+ if (state == State.Body)
+ return;
+ }
+
+ if (state == State.BodyFinished && offset < size)
+ {
+ state = ReadCRLF(buffer, ref offset, size);
+ if (state == State.BodyFinished)
+ return;
+
+ sawCR = false;
+ }
+
+ if (state == State.Trailer && offset < size)
+ {
+ state = ReadTrailer(buffer, ref offset, size);
+ if (state == State.Trailer)
+ return;
+
+ saved.Length = 0;
+ sawCR = false;
+ gotit = false;
+ }
+
+ if (offset < size)
+ InternalWrite(buffer, ref offset, size);
+ }
+
+ public bool WantMore
+ {
+ get { return (chunkRead != chunkSize || chunkSize != 0 || state != State.None); }
+ }
+
+ public bool DataAvailable
+ {
+ get
+ {
+ int count = chunks.Count;
+ for (int i = 0; i < count; i++)
+ {
+ Chunk ch = (Chunk)chunks[i];
+ if (ch == null || ch.Bytes == null)
+ continue;
+ if (ch.Bytes.Length > 0 && ch.Offset < ch.Bytes.Length)
+ return (state != State.Body);
+ }
+ return false;
+ }
+ }
+
+ public int TotalDataSize
+ {
+ get { return totalWritten; }
+ }
+
+ public int ChunkLeft
+ {
+ get { return chunkSize - chunkRead; }
+ }
+
+ State ReadBody(byte[] buffer, ref int offset, int size)
+ {
+ if (chunkSize == 0)
+ return State.BodyFinished;
+
+ int diff = size - offset;
+ if (diff + chunkRead > chunkSize)
+ diff = chunkSize - chunkRead;
+
+ byte[] chunk = new byte[diff];
+ Buffer.BlockCopy(buffer, offset, chunk, 0, diff);
+ chunks.Add(new Chunk(chunk));
+ offset += diff;
+ chunkRead += diff;
+ totalWritten += diff;
+ return (chunkRead == chunkSize) ? State.BodyFinished : State.Body;
+
+ }
+
+ State GetChunkSize(byte[] buffer, ref int offset, int size)
+ {
+ chunkRead = 0;
+ chunkSize = 0;
+ char c = '\0';
+ while (offset < size)
+ {
+ c = (char)buffer[offset++];
+ if (c == '\r')
+ {
+ if (sawCR)
+ ThrowProtocolViolation("2 CR found");
+
+ sawCR = true;
+ continue;
+ }
+
+ if (sawCR && c == '\n')
+ break;
+
+ if (c == ' ')
+ gotit = true;
+
+ if (!gotit)
+ saved.Append(c);
+
+ if (saved.Length > 20)
+ ThrowProtocolViolation("chunk size too long.");
+ }
+
+ if (!sawCR || c != '\n')
+ {
+ if (offset < size)
+ ThrowProtocolViolation("Missing \\n");
+
+ try
+ {
+ if (saved.Length > 0)
+ {
+ chunkSize = Int32.Parse(RemoveChunkExtension(saved.ToString()), NumberStyles.HexNumber);
+ }
+ }
+ catch (Exception)
+ {
+ ThrowProtocolViolation("Cannot parse chunk size.");
+ }
+
+ return State.PartialSize;
+ }
+
+ chunkRead = 0;
+ try
+ {
+ chunkSize = Int32.Parse(RemoveChunkExtension(saved.ToString()), NumberStyles.HexNumber);
+ }
+ catch (Exception)
+ {
+ ThrowProtocolViolation("Cannot parse chunk size.");
+ }
+
+ if (chunkSize == 0)
+ {
+ trailerState = 2;
+ return State.Trailer;
+ }
+
+ return State.Body;
+ }
+
+ static string RemoveChunkExtension(string input)
+ {
+ int idx = input.IndexOf(';');
+ if (idx == -1)
+ return input;
+ return input.Substring(0, idx);
+ }
+
+ State ReadCRLF(byte[] buffer, ref int offset, int size)
+ {
+ if (!sawCR)
+ {
+ if ((char)buffer[offset++] != '\r')
+ ThrowProtocolViolation("Expecting \\r");
+
+ sawCR = true;
+ if (offset == size)
+ return State.BodyFinished;
+ }
+
+ if (sawCR && (char)buffer[offset++] != '\n')
+ ThrowProtocolViolation("Expecting \\n");
+
+ return State.None;
+ }
+
+ State ReadTrailer(byte[] buffer, ref int offset, int size)
+ {
+ char c = '\0';
+
+ // short path
+ if (trailerState == 2 && (char)buffer[offset] == '\r' && saved.Length == 0)
+ {
+ offset++;
+ if (offset < size && (char)buffer[offset] == '\n')
+ {
+ offset++;
+ return State.None;
+ }
+ offset--;
+ }
+
+ int st = trailerState;
+ string stString = "\r\n\r";
+ while (offset < size && st < 4)
+ {
+ c = (char)buffer[offset++];
+ if ((st == 0 || st == 2) && c == '\r')
+ {
+ st++;
+ continue;
+ }
+
+ if ((st == 1 || st == 3) && c == '\n')
+ {
+ st++;
+ continue;
+ }
+
+ if (st > 0)
+ {
+ saved.Append(stString.Substring(0, saved.Length == 0 ? st - 2 : st));
+ st = 0;
+ if (saved.Length > 4196)
+ ThrowProtocolViolation("Error reading trailer (too long).");
+ }
+ }
+
+ if (st < 4)
+ {
+ trailerState = st;
+ if (offset < size)
+ ThrowProtocolViolation("Error reading trailer.");
+
+ return State.Trailer;
+ }
+
+ StringReader reader = new StringReader(saved.ToString());
+ string line;
+ while ((line = reader.ReadLine()) != null && line != "")
+ headers.Add(line);
+
+ return State.None;
+ }
+
+ static void ThrowProtocolViolation(string message)
+ {
+ WebException we = new WebException(message, null, WebExceptionStatus.UnknownError, null);
+ //WebException we = new WebException(message, null, WebExceptionStatus.ServerProtocolViolation, null);
+ throw we;
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/ChunkedInputStream.cs b/SocketHttpListener.Portable/Net/ChunkedInputStream.cs
new file mode 100644
index 0000000000..6dfd8d8a1d
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/ChunkedInputStream.cs
@@ -0,0 +1,160 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using SocketHttpListener.Primitives;
+
+namespace SocketHttpListener.Net
+{
+ class ChunkedInputStream : RequestStream
+ {
+ bool disposed;
+ ChunkStream decoder;
+ HttpListenerContext context;
+ bool no_more_data;
+
+ //class ReadBufferState
+ //{
+ // public byte[] Buffer;
+ // public int Offset;
+ // public int Count;
+ // public int InitialCount;
+ // public HttpStreamAsyncResult Ares;
+ // public ReadBufferState(byte[] buffer, int offset, int count,
+ // HttpStreamAsyncResult ares)
+ // {
+ // Buffer = buffer;
+ // Offset = offset;
+ // Count = count;
+ // InitialCount = count;
+ // Ares = ares;
+ // }
+ //}
+
+ public ChunkedInputStream(HttpListenerContext context, Stream stream,
+ byte[] buffer, int offset, int length)
+ : base(stream, buffer, offset, length)
+ {
+ this.context = context;
+ WebHeaderCollection coll = (WebHeaderCollection)context.Request.Headers;
+ decoder = new ChunkStream(coll);
+ }
+
+ //public ChunkStream Decoder
+ //{
+ // get { return decoder; }
+ // set { decoder = value; }
+ //}
+
+ //public override int Read([In, Out] byte[] buffer, int offset, int count)
+ //{
+ // IAsyncResult ares = BeginRead(buffer, offset, count, null, null);
+ // return EndRead(ares);
+ //}
+
+ //public override IAsyncResult BeginRead(byte[] buffer, int offset, int count,
+ // AsyncCallback cback, object state)
+ //{
+ // if (disposed)
+ // throw new ObjectDisposedException(GetType().ToString());
+
+ // if (buffer == null)
+ // throw new ArgumentNullException("buffer");
+
+ // int len = buffer.Length;
+ // if (offset < 0 || offset > len)
+ // throw new ArgumentOutOfRangeException("offset exceeds the size of buffer");
+
+ // if (count < 0 || offset > len - count)
+ // throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer");
+
+ // HttpStreamAsyncResult ares = new HttpStreamAsyncResult();
+ // ares.Callback = cback;
+ // ares.State = state;
+ // if (no_more_data)
+ // {
+ // ares.Complete();
+ // return ares;
+ // }
+ // int nread = decoder.Read(buffer, offset, count);
+ // offset += nread;
+ // count -= nread;
+ // if (count == 0)
+ // {
+ // // got all we wanted, no need to bother the decoder yet
+ // ares.Count = nread;
+ // ares.Complete();
+ // return ares;
+ // }
+ // if (!decoder.WantMore)
+ // {
+ // no_more_data = nread == 0;
+ // ares.Count = nread;
+ // ares.Complete();
+ // return ares;
+ // }
+ // ares.Buffer = new byte[8192];
+ // ares.Offset = 0;
+ // ares.Count = 8192;
+ // ReadBufferState rb = new ReadBufferState(buffer, offset, count, ares);
+ // rb.InitialCount += nread;
+ // base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb);
+ // return ares;
+ //}
+
+ //void OnRead(IAsyncResult base_ares)
+ //{
+ // ReadBufferState rb = (ReadBufferState)base_ares.AsyncState;
+ // HttpStreamAsyncResult ares = rb.Ares;
+ // try
+ // {
+ // int nread = base.EndRead(base_ares);
+ // decoder.Write(ares.Buffer, ares.Offset, nread);
+ // nread = decoder.Read(rb.Buffer, rb.Offset, rb.Count);
+ // rb.Offset += nread;
+ // rb.Count -= nread;
+ // if (rb.Count == 0 || !decoder.WantMore || nread == 0)
+ // {
+ // no_more_data = !decoder.WantMore && nread == 0;
+ // ares.Count = rb.InitialCount - rb.Count;
+ // ares.Complete();
+ // return;
+ // }
+ // ares.Offset = 0;
+ // ares.Count = Math.Min(8192, decoder.ChunkLeft + 6);
+ // base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb);
+ // }
+ // catch (Exception e)
+ // {
+ // context.Connection.SendError(e.Message, 400);
+ // ares.Complete(e);
+ // }
+ //}
+
+ //public override int EndRead(IAsyncResult ares)
+ //{
+ // if (disposed)
+ // throw new ObjectDisposedException(GetType().ToString());
+
+ // HttpStreamAsyncResult my_ares = ares as HttpStreamAsyncResult;
+ // if (ares == null)
+ // throw new ArgumentException("Invalid IAsyncResult", "ares");
+
+ // if (!ares.IsCompleted)
+ // ares.AsyncWaitHandle.WaitOne();
+
+ // if (my_ares.Error != null)
+ // throw new HttpListenerException(400, "I/O operation aborted: " + my_ares.Error.Message);
+
+ // return my_ares.Count;
+ //}
+
+ //protected override void Dispose(bool disposing)
+ //{
+ // if (!disposed)
+ // {
+ // disposed = true;
+ // base.Dispose(disposing);
+ // }
+ //}
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/CookieHelper.cs b/SocketHttpListener.Portable/Net/CookieHelper.cs
new file mode 100644
index 0000000000..470507d6b7
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/CookieHelper.cs
@@ -0,0 +1,144 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SocketHttpListener.Net
+{
+ public static class CookieHelper
+ {
+ internal static CookieCollection Parse(string value, bool response)
+ {
+ return response
+ ? parseResponse(value)
+ : null;
+ }
+
+ private static string[] splitCookieHeaderValue(string value)
+ {
+ return new List<string>(value.SplitHeaderValue(',', ';')).ToArray();
+ }
+
+ private static CookieCollection parseResponse(string value)
+ {
+ var cookies = new CookieCollection();
+
+ Cookie cookie = null;
+ var pairs = splitCookieHeaderValue(value);
+ for (int i = 0; i < pairs.Length; i++)
+ {
+ var pair = pairs[i].Trim();
+ if (pair.Length == 0)
+ continue;
+
+ if (pair.StartsWith("version", StringComparison.OrdinalIgnoreCase))
+ {
+ if (cookie != null)
+ cookie.Version = Int32.Parse(pair.GetValueInternal("=").Trim('"'));
+ }
+ else if (pair.StartsWith("expires", StringComparison.OrdinalIgnoreCase))
+ {
+ var buffer = new StringBuilder(pair.GetValueInternal("="), 32);
+ if (i < pairs.Length - 1)
+ buffer.AppendFormat(", {0}", pairs[++i].Trim());
+
+ DateTime expires;
+ if (!DateTime.TryParseExact(
+ buffer.ToString(),
+ new[] { "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'", "r" },
+ new CultureInfo("en-US"),
+ DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal,
+ out expires))
+ expires = DateTime.Now;
+
+ if (cookie != null && cookie.Expires == DateTime.MinValue)
+ cookie.Expires = expires.ToLocalTime();
+ }
+ else if (pair.StartsWith("max-age", StringComparison.OrdinalIgnoreCase))
+ {
+ var max = Int32.Parse(pair.GetValueInternal("=").Trim('"'));
+ var expires = DateTime.Now.AddSeconds((double)max);
+ if (cookie != null)
+ cookie.Expires = expires;
+ }
+ else if (pair.StartsWith("path", StringComparison.OrdinalIgnoreCase))
+ {
+ if (cookie != null)
+ cookie.Path = pair.GetValueInternal("=");
+ }
+ else if (pair.StartsWith("domain", StringComparison.OrdinalIgnoreCase))
+ {
+ if (cookie != null)
+ cookie.Domain = pair.GetValueInternal("=");
+ }
+ else if (pair.StartsWith("port", StringComparison.OrdinalIgnoreCase))
+ {
+ var port = pair.Equals("port", StringComparison.OrdinalIgnoreCase)
+ ? "\"\""
+ : pair.GetValueInternal("=");
+
+ if (cookie != null)
+ cookie.Port = port;
+ }
+ else if (pair.StartsWith("comment", StringComparison.OrdinalIgnoreCase))
+ {
+ if (cookie != null)
+ cookie.Comment = pair.GetValueInternal("=").UrlDecode();
+ }
+ else if (pair.StartsWith("commenturl", StringComparison.OrdinalIgnoreCase))
+ {
+ if (cookie != null)
+ cookie.CommentUri = pair.GetValueInternal("=").Trim('"').ToUri();
+ }
+ else if (pair.StartsWith("discard", StringComparison.OrdinalIgnoreCase))
+ {
+ if (cookie != null)
+ cookie.Discard = true;
+ }
+ else if (pair.StartsWith("secure", StringComparison.OrdinalIgnoreCase))
+ {
+ if (cookie != null)
+ cookie.Secure = true;
+ }
+ else if (pair.StartsWith("httponly", StringComparison.OrdinalIgnoreCase))
+ {
+ if (cookie != null)
+ cookie.HttpOnly = true;
+ }
+ else
+ {
+ if (cookie != null)
+ cookies.Add(cookie);
+
+ string name;
+ string val = String.Empty;
+
+ var pos = pair.IndexOf('=');
+ if (pos == -1)
+ {
+ name = pair;
+ }
+ else if (pos == pair.Length - 1)
+ {
+ name = pair.Substring(0, pos).TrimEnd(' ');
+ }
+ else
+ {
+ name = pair.Substring(0, pos).TrimEnd(' ');
+ val = pair.Substring(pos + 1).TrimStart(' ');
+ }
+
+ cookie = new Cookie(name, val);
+ }
+ }
+
+ if (cookie != null)
+ cookies.Add(cookie);
+
+ return cookies;
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/EndPointListener.cs b/SocketHttpListener.Portable/Net/EndPointListener.cs
new file mode 100644
index 0000000000..b50660ad0a
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/EndPointListener.cs
@@ -0,0 +1,368 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Threading;
+using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Text;
+using SocketHttpListener.Primitives;
+
+namespace SocketHttpListener.Net
+{
+ sealed class EndPointListener
+ {
+ HttpListener listener;
+ IpEndPointInfo endpoint;
+ ISocket sock;
+ Dictionary<ListenerPrefix,HttpListener> prefixes; // Dictionary <ListenerPrefix, HttpListener>
+ List<ListenerPrefix> unhandled; // List<ListenerPrefix> unhandled; host = '*'
+ List<ListenerPrefix> all; // List<ListenerPrefix> all; host = '+'
+ ICertificate cert;
+ bool secure;
+ Dictionary<HttpConnection, HttpConnection> unregistered;
+ private readonly ILogger _logger;
+ private bool _closed;
+ private readonly bool _enableDualMode;
+ private readonly ICryptoProvider _cryptoProvider;
+ private readonly IStreamFactory _streamFactory;
+ private readonly ISocketFactory _socketFactory;
+ private readonly ITextEncoding _textEncoding;
+ private readonly IMemoryStreamFactory _memoryStreamFactory;
+
+ public EndPointListener(HttpListener listener, IpAddressInfo addr, int port, bool secure, ICertificate cert, ILogger logger, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, ISocketFactory socketFactory, IMemoryStreamFactory memoryStreamFactory, ITextEncoding textEncoding)
+ {
+ this.listener = listener;
+ _logger = logger;
+ _cryptoProvider = cryptoProvider;
+ _streamFactory = streamFactory;
+ _socketFactory = socketFactory;
+ _memoryStreamFactory = memoryStreamFactory;
+ _textEncoding = textEncoding;
+
+ this.secure = secure;
+ this.cert = cert;
+
+ _enableDualMode = addr.Equals(IpAddressInfo.IPv6Any);
+ endpoint = new IpEndPointInfo(addr, port);
+
+ prefixes = new Dictionary<ListenerPrefix, HttpListener>();
+ unregistered = new Dictionary<HttpConnection, HttpConnection>();
+
+ CreateSocket();
+ }
+
+ internal HttpListener Listener
+ {
+ get
+ {
+ return listener;
+ }
+ }
+
+ private void CreateSocket()
+ {
+ sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
+
+ sock.Bind(endpoint);
+
+ // This is the number TcpListener uses.
+ sock.Listen(2147483647);
+
+ sock.StartAccept(ProcessAccept, () => _closed);
+ _closed = false;
+ }
+
+ private async void ProcessAccept(ISocket accepted)
+ {
+ try
+ {
+ var listener = this;
+
+ if (listener.secure && listener.cert == null)
+ {
+ accepted.Close();
+ return;
+ }
+
+ HttpConnection conn = await HttpConnection.Create(_logger, accepted, listener, listener.secure, listener.cert, _cryptoProvider, _streamFactory, _memoryStreamFactory, _textEncoding).ConfigureAwait(false);
+
+ //_logger.Debug("Adding unregistered connection to {0}. Id: {1}", accepted.RemoteEndPoint, connectionId);
+ lock (listener.unregistered)
+ {
+ listener.unregistered[conn] = conn;
+ }
+ conn.BeginReadRequest();
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error in ProcessAccept", ex);
+ }
+ }
+
+ internal void RemoveConnection(HttpConnection conn)
+ {
+ lock (unregistered)
+ {
+ unregistered.Remove(conn);
+ }
+ }
+
+ public bool BindContext(HttpListenerContext context)
+ {
+ HttpListenerRequest req = context.Request;
+ ListenerPrefix prefix;
+ HttpListener listener = SearchListener(req.Url, out prefix);
+ if (listener == null)
+ return false;
+
+ context.Listener = listener;
+ context.Connection.Prefix = prefix;
+ return true;
+ }
+
+ public void UnbindContext(HttpListenerContext context)
+ {
+ if (context == null || context.Request == null)
+ return;
+
+ context.Listener.UnregisterContext(context);
+ }
+
+ HttpListener SearchListener(Uri uri, out ListenerPrefix prefix)
+ {
+ prefix = null;
+ if (uri == null)
+ return null;
+
+ string host = uri.Host;
+ int port = uri.Port;
+ string path = WebUtility.UrlDecode(uri.AbsolutePath);
+ string path_slash = path[path.Length - 1] == '/' ? path : path + "/";
+
+ HttpListener best_match = null;
+ int best_length = -1;
+
+ if (host != null && host != "")
+ {
+ var p_ro = prefixes;
+ foreach (ListenerPrefix p in p_ro.Keys)
+ {
+ string ppath = p.Path;
+ if (ppath.Length < best_length)
+ continue;
+
+ if (p.Host != host || p.Port != port)
+ continue;
+
+ if (path.StartsWith(ppath) || path_slash.StartsWith(ppath))
+ {
+ best_length = ppath.Length;
+ best_match = (HttpListener)p_ro[p];
+ prefix = p;
+ }
+ }
+ if (best_length != -1)
+ return best_match;
+ }
+
+ List<ListenerPrefix> list = unhandled;
+ best_match = MatchFromList(host, path, list, out prefix);
+ if (path != path_slash && best_match == null)
+ best_match = MatchFromList(host, path_slash, list, out prefix);
+ if (best_match != null)
+ return best_match;
+
+ list = all;
+ best_match = MatchFromList(host, path, list, out prefix);
+ if (path != path_slash && best_match == null)
+ best_match = MatchFromList(host, path_slash, list, out prefix);
+ if (best_match != null)
+ return best_match;
+
+ return null;
+ }
+
+ HttpListener MatchFromList(string host, string path, List<ListenerPrefix> list, out ListenerPrefix prefix)
+ {
+ prefix = null;
+ if (list == null)
+ return null;
+
+ HttpListener best_match = null;
+ int best_length = -1;
+
+ foreach (ListenerPrefix p in list)
+ {
+ string ppath = p.Path;
+ if (ppath.Length < best_length)
+ continue;
+
+ if (path.StartsWith(ppath))
+ {
+ best_length = ppath.Length;
+ best_match = p.Listener;
+ prefix = p;
+ }
+ }
+
+ return best_match;
+ }
+
+ void AddSpecial(List<ListenerPrefix> coll, ListenerPrefix prefix)
+ {
+ if (coll == null)
+ return;
+
+ foreach (ListenerPrefix p in coll)
+ {
+ if (p.Path == prefix.Path) //TODO: code
+ throw new HttpListenerException(400, "Prefix already in use.");
+ }
+ coll.Add(prefix);
+ }
+
+ bool RemoveSpecial(List<ListenerPrefix> coll, ListenerPrefix prefix)
+ {
+ if (coll == null)
+ return false;
+
+ int c = coll.Count;
+ for (int i = 0; i < c; i++)
+ {
+ ListenerPrefix p = (ListenerPrefix)coll[i];
+ if (p.Path == prefix.Path)
+ {
+ coll.RemoveAt(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void CheckIfRemove()
+ {
+ if (prefixes.Count > 0)
+ return;
+
+ List<ListenerPrefix> list = unhandled;
+ if (list != null && list.Count > 0)
+ return;
+
+ list = all;
+ if (list != null && list.Count > 0)
+ return;
+
+ EndPointManager.RemoveEndPoint(this, endpoint);
+ }
+
+ public void Close()
+ {
+ _closed = true;
+ sock.Close();
+ lock (unregistered)
+ {
+ //
+ // Clone the list because RemoveConnection can be called from Close
+ //
+ var connections = new List<HttpConnection>(unregistered.Keys);
+
+ foreach (HttpConnection c in connections)
+ c.Close(true);
+ unregistered.Clear();
+ }
+ }
+
+ public void AddPrefix(ListenerPrefix prefix, HttpListener listener)
+ {
+ List<ListenerPrefix> current;
+ List<ListenerPrefix> future;
+ if (prefix.Host == "*")
+ {
+ do
+ {
+ current = unhandled;
+ future = (current != null) ? current.ToList() : new List<ListenerPrefix>();
+ prefix.Listener = listener;
+ AddSpecial(future, prefix);
+ } while (Interlocked.CompareExchange(ref unhandled, future, current) != current);
+ return;
+ }
+
+ if (prefix.Host == "+")
+ {
+ do
+ {
+ current = all;
+ future = (current != null) ? current.ToList() : new List<ListenerPrefix>();
+ prefix.Listener = listener;
+ AddSpecial(future, prefix);
+ } while (Interlocked.CompareExchange(ref all, future, current) != current);
+ return;
+ }
+
+ Dictionary<ListenerPrefix, HttpListener> prefs;
+ Dictionary<ListenerPrefix, HttpListener> p2;
+ do
+ {
+ prefs = prefixes;
+ if (prefs.ContainsKey(prefix))
+ {
+ HttpListener other = (HttpListener)prefs[prefix];
+ if (other != listener) // TODO: code.
+ throw new HttpListenerException(400, "There's another listener for " + prefix);
+ return;
+ }
+ p2 = new Dictionary<ListenerPrefix, HttpListener>(prefs);
+ p2[prefix] = listener;
+ } while (Interlocked.CompareExchange(ref prefixes, p2, prefs) != prefs);
+ }
+
+ public void RemovePrefix(ListenerPrefix prefix, HttpListener listener)
+ {
+ List<ListenerPrefix> current;
+ List<ListenerPrefix> future;
+ if (prefix.Host == "*")
+ {
+ do
+ {
+ current = unhandled;
+ future = (current != null) ? current.ToList() : new List<ListenerPrefix>();
+ if (!RemoveSpecial(future, prefix))
+ break; // Prefix not found
+ } while (Interlocked.CompareExchange(ref unhandled, future, current) != current);
+ CheckIfRemove();
+ return;
+ }
+
+ if (prefix.Host == "+")
+ {
+ do
+ {
+ current = all;
+ future = (current != null) ? current.ToList() : new List<ListenerPrefix>();
+ if (!RemoveSpecial(future, prefix))
+ break; // Prefix not found
+ } while (Interlocked.CompareExchange(ref all, future, current) != current);
+ CheckIfRemove();
+ return;
+ }
+
+ Dictionary<ListenerPrefix, HttpListener> prefs;
+ Dictionary<ListenerPrefix, HttpListener> p2;
+ do
+ {
+ prefs = prefixes;
+ if (!prefs.ContainsKey(prefix))
+ break;
+
+ p2 = new Dictionary<ListenerPrefix, HttpListener>(prefs);
+ p2.Remove(prefix);
+ } while (Interlocked.CompareExchange(ref prefixes, p2, prefs) != prefs);
+ CheckIfRemove();
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/EndPointManager.cs b/SocketHttpListener.Portable/Net/EndPointManager.cs
new file mode 100644
index 0000000000..797684b3e2
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/EndPointManager.cs
@@ -0,0 +1,165 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Reflection;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
+using SocketHttpListener.Primitives;
+
+namespace SocketHttpListener.Net
+{
+ sealed class EndPointManager
+ {
+ // Dictionary<IPAddress, Dictionary<int, EndPointListener>>
+ static Dictionary<string, Dictionary<int, EndPointListener>> ip_to_endpoints = new Dictionary<string, Dictionary<int, EndPointListener>>();
+
+ private EndPointManager()
+ {
+ }
+
+ public static void AddListener(ILogger logger, HttpListener listener)
+ {
+ List<string> added = new List<string>();
+ try
+ {
+ lock (ip_to_endpoints)
+ {
+ foreach (string prefix in listener.Prefixes)
+ {
+ AddPrefixInternal(logger, prefix, listener);
+ added.Add(prefix);
+ }
+ }
+ }
+ catch
+ {
+ foreach (string prefix in added)
+ {
+ RemovePrefix(logger, prefix, listener);
+ }
+ throw;
+ }
+ }
+
+ public static void AddPrefix(ILogger logger, string prefix, HttpListener listener)
+ {
+ lock (ip_to_endpoints)
+ {
+ AddPrefixInternal(logger, prefix, listener);
+ }
+ }
+
+ static void AddPrefixInternal(ILogger logger, string p, HttpListener listener)
+ {
+ ListenerPrefix lp = new ListenerPrefix(p);
+ if (lp.Path.IndexOf('%') != -1)
+ throw new HttpListenerException(400, "Invalid path.");
+
+ if (lp.Path.IndexOf("//", StringComparison.Ordinal) != -1) // TODO: Code?
+ throw new HttpListenerException(400, "Invalid path.");
+
+ // listens on all the interfaces if host name cannot be parsed by IPAddress.
+ EndPointListener epl = GetEPListener(logger, lp.Host, lp.Port, listener, lp.Secure).Result;
+ epl.AddPrefix(lp, listener);
+ }
+
+ private static IpAddressInfo GetIpAnyAddress(HttpListener listener)
+ {
+ return listener.EnableDualMode ? IpAddressInfo.IPv6Any : IpAddressInfo.Any;
+ }
+
+ static async Task<EndPointListener> GetEPListener(ILogger logger, string host, int port, HttpListener listener, bool secure)
+ {
+ var networkManager = listener.NetworkManager;
+
+ IpAddressInfo addr;
+ if (host == "*" || host == "+")
+ addr = GetIpAnyAddress(listener);
+ else if (networkManager.TryParseIpAddress(host, out addr) == false)
+ {
+ try
+ {
+ addr = (await networkManager.GetHostAddressesAsync(host).ConfigureAwait(false)).FirstOrDefault() ??
+ GetIpAnyAddress(listener);
+ }
+ catch
+ {
+ addr = GetIpAnyAddress(listener);
+ }
+ }
+
+ Dictionary<int, EndPointListener> p = null; // Dictionary<int, EndPointListener>
+ if (!ip_to_endpoints.TryGetValue(addr.Address, out p))
+ {
+ p = new Dictionary<int, EndPointListener>();
+ ip_to_endpoints[addr.Address] = p;
+ }
+
+ EndPointListener epl = null;
+ if (p.ContainsKey(port))
+ {
+ epl = (EndPointListener)p[port];
+ }
+ else
+ {
+ epl = new EndPointListener(listener, addr, port, secure, listener.Certificate, logger, listener.CryptoProvider, listener.StreamFactory, listener.SocketFactory, listener.MemoryStreamFactory, listener.TextEncoding);
+ p[port] = epl;
+ }
+
+ return epl;
+ }
+
+ public static void RemoveEndPoint(EndPointListener epl, IpEndPointInfo ep)
+ {
+ lock (ip_to_endpoints)
+ {
+ // Dictionary<int, EndPointListener> p
+ Dictionary<int, EndPointListener> p;
+ if (ip_to_endpoints.TryGetValue(ep.IpAddress.Address, out p))
+ {
+ p.Remove(ep.Port);
+ if (p.Count == 0)
+ {
+ ip_to_endpoints.Remove(ep.IpAddress.Address);
+ }
+ }
+ epl.Close();
+ }
+ }
+
+ public static void RemoveListener(ILogger logger, HttpListener listener)
+ {
+ lock (ip_to_endpoints)
+ {
+ foreach (string prefix in listener.Prefixes)
+ {
+ RemovePrefixInternal(logger, prefix, listener);
+ }
+ }
+ }
+
+ public static void RemovePrefix(ILogger logger, string prefix, HttpListener listener)
+ {
+ lock (ip_to_endpoints)
+ {
+ RemovePrefixInternal(logger, prefix, listener);
+ }
+ }
+
+ static void RemovePrefixInternal(ILogger logger, string prefix, HttpListener listener)
+ {
+ ListenerPrefix lp = new ListenerPrefix(prefix);
+ if (lp.Path.IndexOf('%') != -1)
+ return;
+
+ if (lp.Path.IndexOf("//", StringComparison.Ordinal) != -1)
+ return;
+
+ EndPointListener epl = GetEPListener(logger, lp.Host, lp.Port, listener, lp.Secure).Result;
+ epl.RemovePrefix(lp, listener);
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/HttpConnection.cs b/SocketHttpListener.Portable/Net/HttpConnection.cs
new file mode 100644
index 0000000000..d31da41329
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/HttpConnection.cs
@@ -0,0 +1,550 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Text;
+using SocketHttpListener.Primitives;
+
+namespace SocketHttpListener.Net
+{
+ sealed class HttpConnection
+ {
+ const int BufferSize = 8192;
+ ISocket sock;
+ Stream stream;
+ EndPointListener epl;
+ MemoryStream ms;
+ byte[] buffer;
+ HttpListenerContext context;
+ StringBuilder current_line;
+ ListenerPrefix prefix;
+ RequestStream i_stream;
+ ResponseStream o_stream;
+ bool chunked;
+ int reuses;
+ bool context_bound;
+ bool secure;
+ int s_timeout = 300000; // 90k ms for first request, 15k ms from then on
+ IpEndPointInfo local_ep;
+ HttpListener last_listener;
+ int[] client_cert_errors;
+ ICertificate cert;
+ Stream ssl_stream;
+
+ private ILogger _logger;
+ private readonly ICryptoProvider _cryptoProvider;
+ private readonly IMemoryStreamFactory _memoryStreamFactory;
+ private readonly ITextEncoding _textEncoding;
+ private readonly IStreamFactory _streamFactory;
+
+ private HttpConnection(ILogger logger, ISocket sock, EndPointListener epl, bool secure, ICertificate cert, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, IMemoryStreamFactory memoryStreamFactory, ITextEncoding textEncoding)
+ {
+ _logger = logger;
+ this.sock = sock;
+ this.epl = epl;
+ this.secure = secure;
+ this.cert = cert;
+ _cryptoProvider = cryptoProvider;
+ _memoryStreamFactory = memoryStreamFactory;
+ _textEncoding = textEncoding;
+ _streamFactory = streamFactory;
+ }
+
+ private async Task InitStream()
+ {
+ if (secure == false)
+ {
+ stream = _streamFactory.CreateNetworkStream(sock, false);
+ }
+ else
+ {
+ //ssl_stream = epl.Listener.CreateSslStream(new NetworkStream(sock, false), false, (t, c, ch, e) =>
+ //{
+ // if (c == null)
+ // return true;
+ // var c2 = c as X509Certificate2;
+ // if (c2 == null)
+ // c2 = new X509Certificate2(c.GetRawCertData());
+ // client_cert = c2;
+ // client_cert_errors = new int[] { (int)e };
+ // return true;
+ //});
+ //stream = ssl_stream.AuthenticatedStream;
+
+ ssl_stream = _streamFactory.CreateSslStream(_streamFactory.CreateNetworkStream(sock, false), false);
+ await _streamFactory.AuthenticateSslStreamAsServer(ssl_stream, cert).ConfigureAwait(false);
+ stream = ssl_stream;
+ }
+ Init();
+ }
+
+ public static async Task<HttpConnection> Create(ILogger logger, ISocket sock, EndPointListener epl, bool secure, ICertificate cert, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, IMemoryStreamFactory memoryStreamFactory, ITextEncoding textEncoding)
+ {
+ var connection = new HttpConnection(logger, sock, epl, secure, cert, cryptoProvider, streamFactory, memoryStreamFactory, textEncoding);
+
+ await connection.InitStream().ConfigureAwait(false);
+
+ return connection;
+ }
+
+ public Stream Stream
+ {
+ get
+ {
+ return stream;
+ }
+ }
+
+ internal int[] ClientCertificateErrors
+ {
+ get { return client_cert_errors; }
+ }
+
+ void Init()
+ {
+ if (ssl_stream != null)
+ {
+ //ssl_stream.AuthenticateAsServer(client_cert, true, (SslProtocols)ServicePointManager.SecurityProtocol, false);
+ //_streamFactory.AuthenticateSslStreamAsServer(ssl_stream, cert);
+ }
+
+ context_bound = false;
+ i_stream = null;
+ o_stream = null;
+ prefix = null;
+ chunked = false;
+ ms = _memoryStreamFactory.CreateNew();
+ position = 0;
+ input_state = InputState.RequestLine;
+ line_state = LineState.None;
+ context = new HttpListenerContext(this, _logger, _cryptoProvider, _memoryStreamFactory, _textEncoding);
+ }
+
+ public bool IsClosed
+ {
+ get { return (sock == null); }
+ }
+
+ public int Reuses
+ {
+ get { return reuses; }
+ }
+
+ public IpEndPointInfo LocalEndPoint
+ {
+ get
+ {
+ if (local_ep != null)
+ return local_ep;
+
+ local_ep = (IpEndPointInfo)sock.LocalEndPoint;
+ return local_ep;
+ }
+ }
+
+ public IpEndPointInfo RemoteEndPoint
+ {
+ get { return (IpEndPointInfo)sock.RemoteEndPoint; }
+ }
+
+ public bool IsSecure
+ {
+ get { return secure; }
+ }
+
+ public ListenerPrefix Prefix
+ {
+ get { return prefix; }
+ set { prefix = value; }
+ }
+
+ public async Task BeginReadRequest()
+ {
+ if (buffer == null)
+ buffer = new byte[BufferSize];
+
+ try
+ {
+ //if (reuses == 1)
+ // s_timeout = 15000;
+ var nRead = await stream.ReadAsync(buffer, 0, BufferSize).ConfigureAwait(false);
+
+ OnReadInternal(nRead);
+ }
+ catch (Exception ex)
+ {
+ OnReadInternalException(ms, ex);
+ }
+ }
+
+ public RequestStream GetRequestStream(bool chunked, long contentlength)
+ {
+ if (i_stream == null)
+ {
+ byte[] buffer;
+ _memoryStreamFactory.TryGetBuffer(ms, out buffer);
+
+ int length = (int)ms.Length;
+ ms = null;
+ if (chunked)
+ {
+ this.chunked = true;
+ //context.Response.SendChunked = true;
+ i_stream = new ChunkedInputStream(context, stream, buffer, position, length - position);
+ }
+ else
+ {
+ i_stream = new RequestStream(stream, buffer, position, length - position, contentlength);
+ }
+ }
+ return i_stream;
+ }
+
+ public ResponseStream GetResponseStream()
+ {
+ // TODO: can we get this stream before reading the input?
+ if (o_stream == null)
+ {
+ HttpListener listener = context.Listener;
+
+ if (listener == null)
+ return new ResponseStream(stream, context.Response, true, _memoryStreamFactory, _textEncoding);
+
+ o_stream = new ResponseStream(stream, context.Response, listener.IgnoreWriteExceptions, _memoryStreamFactory, _textEncoding);
+ }
+ return o_stream;
+ }
+
+ void OnReadInternal(int nread)
+ {
+ ms.Write(buffer, 0, nread);
+ if (ms.Length > 32768)
+ {
+ SendError("Bad request", 400);
+ Close(true);
+ return;
+ }
+
+ if (nread == 0)
+ {
+ //if (ms.Length > 0)
+ // SendError (); // Why bother?
+ CloseSocket();
+ Unbind();
+ return;
+ }
+
+ if (ProcessInput(ms))
+ {
+ if (!context.HaveError)
+ context.Request.FinishInitialization();
+
+ if (context.HaveError)
+ {
+ SendError();
+ Close(true);
+ return;
+ }
+
+ if (!epl.BindContext(context))
+ {
+ SendError("Invalid host", 400);
+ Close(true);
+ return;
+ }
+ HttpListener listener = context.Listener;
+ if (last_listener != listener)
+ {
+ RemoveConnection();
+ listener.AddConnection(this);
+ last_listener = listener;
+ }
+
+ context_bound = true;
+ listener.RegisterContext(context);
+ return;
+ }
+
+ BeginReadRequest();
+ }
+
+ private void OnReadInternalException(MemoryStream ms, Exception ex)
+ {
+ //_logger.ErrorException("Error in HttpConnection.OnReadInternal", ex);
+
+ if (ms != null && ms.Length > 0)
+ SendError();
+ if (sock != null)
+ {
+ CloseSocket();
+ Unbind();
+ }
+ }
+
+ void RemoveConnection()
+ {
+ if (last_listener == null)
+ epl.RemoveConnection(this);
+ else
+ last_listener.RemoveConnection(this);
+ }
+
+ enum InputState
+ {
+ RequestLine,
+ Headers
+ }
+
+ enum LineState
+ {
+ None,
+ CR,
+ LF
+ }
+
+ InputState input_state = InputState.RequestLine;
+ LineState line_state = LineState.None;
+ int position;
+
+ // true -> done processing
+ // false -> need more input
+ bool ProcessInput(MemoryStream ms)
+ {
+ byte[] buffer;
+ _memoryStreamFactory.TryGetBuffer(ms, out buffer);
+
+ int len = (int)ms.Length;
+ int used = 0;
+ string line;
+
+ while (true)
+ {
+ if (context.HaveError)
+ return true;
+
+ if (position >= len)
+ break;
+
+ try
+ {
+ line = ReadLine(buffer, position, len - position, ref used);
+ position += used;
+ }
+ catch
+ {
+ context.ErrorMessage = "Bad request";
+ context.ErrorStatus = 400;
+ return true;
+ }
+
+ if (line == null)
+ break;
+
+ if (line == "")
+ {
+ if (input_state == InputState.RequestLine)
+ continue;
+ current_line = null;
+ ms = null;
+ return true;
+ }
+
+ if (input_state == InputState.RequestLine)
+ {
+ context.Request.SetRequestLine(line);
+ input_state = InputState.Headers;
+ }
+ else
+ {
+ try
+ {
+ context.Request.AddHeader(line);
+ }
+ catch (Exception e)
+ {
+ context.ErrorMessage = e.Message;
+ context.ErrorStatus = 400;
+ return true;
+ }
+ }
+ }
+
+ if (used == len)
+ {
+ ms.SetLength(0);
+ position = 0;
+ }
+ return false;
+ }
+
+ string ReadLine(byte[] buffer, int offset, int len, ref int used)
+ {
+ if (current_line == null)
+ current_line = new StringBuilder(128);
+ int last = offset + len;
+ used = 0;
+
+ for (int i = offset; i < last && line_state != LineState.LF; i++)
+ {
+ used++;
+ byte b = buffer[i];
+ if (b == 13)
+ {
+ line_state = LineState.CR;
+ }
+ else if (b == 10)
+ {
+ line_state = LineState.LF;
+ }
+ else
+ {
+ current_line.Append((char)b);
+ }
+ }
+
+ string result = null;
+ if (line_state == LineState.LF)
+ {
+ line_state = LineState.None;
+ result = current_line.ToString();
+ current_line.Length = 0;
+ }
+
+ return result;
+ }
+
+ public void SendError(string msg, int status)
+ {
+ try
+ {
+ HttpListenerResponse response = context.Response;
+ response.StatusCode = status;
+ response.ContentType = "text/html";
+ string description = HttpListenerResponse.GetStatusDescription(status);
+ string str;
+ if (msg != null)
+ str = String.Format("<h1>{0} ({1})</h1>", description, msg);
+ else
+ str = String.Format("<h1>{0}</h1>", description);
+
+ byte[] error = context.Response.ContentEncoding.GetBytes(str);
+ response.Close(error, false);
+ }
+ catch
+ {
+ // response was already closed
+ }
+ }
+
+ public void SendError()
+ {
+ SendError(context.ErrorMessage, context.ErrorStatus);
+ }
+
+ void Unbind()
+ {
+ if (context_bound)
+ {
+ epl.UnbindContext(context);
+ context_bound = false;
+ }
+ }
+
+ public void Close()
+ {
+ Close(false);
+ }
+
+ private void CloseSocket()
+ {
+ if (sock == null)
+ return;
+
+ try
+ {
+ sock.Close();
+ }
+ catch
+ {
+ }
+ finally
+ {
+ sock = null;
+ }
+ RemoveConnection();
+ }
+
+ internal void Close(bool force_close)
+ {
+ if (sock != null)
+ {
+ if (!context.Request.IsWebSocketRequest || force_close)
+ {
+ Stream st = GetResponseStream();
+ if (st != null)
+ st.Dispose();
+
+ o_stream = null;
+ }
+ }
+
+ if (sock != null)
+ {
+ force_close |= !context.Request.KeepAlive;
+ if (!force_close)
+ force_close = (context.Response.Headers["connection"] == "close");
+ /*
+ if (!force_close) {
+// bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 ||
+// status_code == 413 || status_code == 414 || status_code == 500 ||
+// status_code == 503);
+ force_close |= (context.Request.ProtocolVersion <= HttpVersion.Version10);
+ }
+ */
+
+ if (!force_close && context.Request.FlushInput())
+ {
+ if (chunked && context.Response.ForceCloseChunked == false)
+ {
+ // Don't close. Keep working.
+ reuses++;
+ Unbind();
+ Init();
+ BeginReadRequest();
+ return;
+ }
+
+ reuses++;
+ Unbind();
+ Init();
+ BeginReadRequest();
+ return;
+ }
+
+ ISocket s = sock;
+ sock = null;
+ try
+ {
+ if (s != null)
+ s.Shutdown(true);
+ }
+ catch
+ {
+ }
+ finally
+ {
+ if (s != null)
+ s.Close();
+ }
+ Unbind();
+ RemoveConnection();
+ return;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/SocketHttpListener.Portable/Net/HttpListener.cs b/SocketHttpListener.Portable/Net/HttpListener.cs
new file mode 100644
index 0000000000..83660100ae
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/HttpListener.cs
@@ -0,0 +1,299 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Text;
+using SocketHttpListener.Primitives;
+
+namespace SocketHttpListener.Net
+{
+ public sealed class HttpListener : IDisposable
+ {
+ internal ICryptoProvider CryptoProvider { get; private set; }
+ internal IStreamFactory StreamFactory { get; private set; }
+ internal ISocketFactory SocketFactory { get; private set; }
+ internal ITextEncoding TextEncoding { get; private set; }
+ internal IMemoryStreamFactory MemoryStreamFactory { get; private set; }
+ internal INetworkManager NetworkManager { get; private set; }
+
+ public bool EnableDualMode { get; set; }
+
+ AuthenticationSchemes auth_schemes;
+ HttpListenerPrefixCollection prefixes;
+ AuthenticationSchemeSelector auth_selector;
+ string realm;
+ bool ignore_write_exceptions;
+ bool unsafe_ntlm_auth;
+ bool listening;
+ bool disposed;
+
+ Dictionary<HttpListenerContext, HttpListenerContext> registry; // Dictionary<HttpListenerContext,HttpListenerContext>
+ Dictionary<HttpConnection, HttpConnection> connections;
+ private ILogger _logger;
+ private ICertificate _certificate;
+
+ public Action<HttpListenerContext> OnContext { get; set; }
+
+ public HttpListener(ILogger logger, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, ISocketFactory socketFactory, INetworkManager networkManager, ITextEncoding textEncoding, IMemoryStreamFactory memoryStreamFactory)
+ {
+ _logger = logger;
+ CryptoProvider = cryptoProvider;
+ StreamFactory = streamFactory;
+ SocketFactory = socketFactory;
+ NetworkManager = networkManager;
+ TextEncoding = textEncoding;
+ MemoryStreamFactory = memoryStreamFactory;
+ prefixes = new HttpListenerPrefixCollection(logger, this);
+ registry = new Dictionary<HttpListenerContext, HttpListenerContext>();
+ connections = new Dictionary<HttpConnection, HttpConnection>();
+ auth_schemes = AuthenticationSchemes.Anonymous;
+ }
+
+ public HttpListener(ICertificate certificate, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, ISocketFactory socketFactory, INetworkManager networkManager, ITextEncoding textEncoding, IMemoryStreamFactory memoryStreamFactory)
+ :this(new NullLogger(), certificate, cryptoProvider, streamFactory, socketFactory, networkManager, textEncoding, memoryStreamFactory)
+ {
+ }
+
+ public HttpListener(ILogger logger, ICertificate certificate, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, ISocketFactory socketFactory, INetworkManager networkManager, ITextEncoding textEncoding, IMemoryStreamFactory memoryStreamFactory)
+ : this(logger, cryptoProvider, streamFactory, socketFactory, networkManager, textEncoding, memoryStreamFactory)
+ {
+ _certificate = certificate;
+ }
+
+ public void LoadCert(ICertificate cert)
+ {
+ _certificate = cert;
+ }
+
+ // TODO: Digest, NTLM and Negotiate require ControlPrincipal
+ public AuthenticationSchemes AuthenticationSchemes
+ {
+ get { return auth_schemes; }
+ set
+ {
+ CheckDisposed();
+ auth_schemes = value;
+ }
+ }
+
+ public AuthenticationSchemeSelector AuthenticationSchemeSelectorDelegate
+ {
+ get { return auth_selector; }
+ set
+ {
+ CheckDisposed();
+ auth_selector = value;
+ }
+ }
+
+ public bool IgnoreWriteExceptions
+ {
+ get { return ignore_write_exceptions; }
+ set
+ {
+ CheckDisposed();
+ ignore_write_exceptions = value;
+ }
+ }
+
+ public bool IsListening
+ {
+ get { return listening; }
+ }
+
+ public static bool IsSupported
+ {
+ get { return true; }
+ }
+
+ public HttpListenerPrefixCollection Prefixes
+ {
+ get
+ {
+ CheckDisposed();
+ return prefixes;
+ }
+ }
+
+ // TODO: use this
+ public string Realm
+ {
+ get { return realm; }
+ set
+ {
+ CheckDisposed();
+ realm = value;
+ }
+ }
+
+ public bool UnsafeConnectionNtlmAuthentication
+ {
+ get { return unsafe_ntlm_auth; }
+ set
+ {
+ CheckDisposed();
+ unsafe_ntlm_auth = value;
+ }
+ }
+
+ //internal IMonoSslStream CreateSslStream(Stream innerStream, bool ownsStream, MSI.MonoRemoteCertificateValidationCallback callback)
+ //{
+ // lock (registry)
+ // {
+ // if (tlsProvider == null)
+ // tlsProvider = MonoTlsProviderFactory.GetProviderInternal();
+ // if (tlsSettings == null)
+ // tlsSettings = MSI.MonoTlsSettings.CopyDefaultSettings();
+ // if (tlsSettings.RemoteCertificateValidationCallback == null)
+ // tlsSettings.RemoteCertificateValidationCallback = callback;
+ // return tlsProvider.CreateSslStream(innerStream, ownsStream, tlsSettings);
+ // }
+ //}
+
+ internal ICertificate Certificate
+ {
+ get { return _certificate; }
+ }
+
+ public void Abort()
+ {
+ if (disposed)
+ return;
+
+ if (!listening)
+ {
+ return;
+ }
+
+ Close(true);
+ }
+
+ public void Close()
+ {
+ if (disposed)
+ return;
+
+ if (!listening)
+ {
+ disposed = true;
+ return;
+ }
+
+ Close(true);
+ disposed = true;
+ }
+
+ void Close(bool force)
+ {
+ CheckDisposed();
+ EndPointManager.RemoveListener(_logger, this);
+ Cleanup(force);
+ }
+
+ void Cleanup(bool close_existing)
+ {
+ lock (registry)
+ {
+ if (close_existing)
+ {
+ // Need to copy this since closing will call UnregisterContext
+ ICollection keys = registry.Keys;
+ var all = new HttpListenerContext[keys.Count];
+ keys.CopyTo(all, 0);
+ registry.Clear();
+ for (int i = all.Length - 1; i >= 0; i--)
+ all[i].Connection.Close(true);
+ }
+
+ lock (connections)
+ {
+ ICollection keys = connections.Keys;
+ var conns = new HttpConnection[keys.Count];
+ keys.CopyTo(conns, 0);
+ connections.Clear();
+ for (int i = conns.Length - 1; i >= 0; i--)
+ conns[i].Close(true);
+ }
+ }
+ }
+
+ internal AuthenticationSchemes SelectAuthenticationScheme(HttpListenerContext context)
+ {
+ if (AuthenticationSchemeSelectorDelegate != null)
+ return AuthenticationSchemeSelectorDelegate(context.Request);
+ else
+ return auth_schemes;
+ }
+
+ public void Start()
+ {
+ CheckDisposed();
+ if (listening)
+ return;
+
+ EndPointManager.AddListener(_logger, this);
+ listening = true;
+ }
+
+ public void Stop()
+ {
+ CheckDisposed();
+ listening = false;
+ Close(false);
+ }
+
+ void IDisposable.Dispose()
+ {
+ if (disposed)
+ return;
+
+ Close(true); //TODO: Should we force here or not?
+ disposed = true;
+ }
+
+ internal void CheckDisposed()
+ {
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+ }
+
+ internal void RegisterContext(HttpListenerContext context)
+ {
+ if (OnContext != null && IsListening)
+ {
+ OnContext(context);
+ }
+
+ lock (registry)
+ registry[context] = context;
+ }
+
+ internal void UnregisterContext(HttpListenerContext context)
+ {
+ lock (registry)
+ registry.Remove(context);
+ }
+
+ internal void AddConnection(HttpConnection cnc)
+ {
+ lock (connections)
+ {
+ connections[cnc] = cnc;
+ }
+ }
+
+ internal void RemoveConnection(HttpConnection cnc)
+ {
+ lock (connections)
+ {
+ connections.Remove(cnc);
+ }
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/HttpListenerBasicIdentity.cs b/SocketHttpListener.Portable/Net/HttpListenerBasicIdentity.cs
new file mode 100644
index 0000000000..faa26693d7
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/HttpListenerBasicIdentity.cs
@@ -0,0 +1,70 @@
+using System.Security.Principal;
+
+namespace SocketHttpListener.Net
+{
+ public class HttpListenerBasicIdentity : GenericIdentity
+ {
+ string password;
+
+ public HttpListenerBasicIdentity(string username, string password)
+ : base(username, "Basic")
+ {
+ this.password = password;
+ }
+
+ public virtual string Password
+ {
+ get { return password; }
+ }
+ }
+
+ public class GenericIdentity : IIdentity
+ {
+ private string m_name;
+ private string m_type;
+
+ public GenericIdentity(string name)
+ {
+ if (name == null)
+ throw new System.ArgumentNullException("name");
+
+ m_name = name;
+ m_type = "";
+ }
+
+ public GenericIdentity(string name, string type)
+ {
+ if (name == null)
+ throw new System.ArgumentNullException("name");
+ if (type == null)
+ throw new System.ArgumentNullException("type");
+
+ m_name = name;
+ m_type = type;
+ }
+
+ public virtual string Name
+ {
+ get
+ {
+ return m_name;
+ }
+ }
+
+ public virtual string AuthenticationType
+ {
+ get
+ {
+ return m_type;
+ }
+ }
+
+ public virtual bool IsAuthenticated
+ {
+ get
+ {
+ return !m_name.Equals("");
+ }
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/HttpListenerContext.cs b/SocketHttpListener.Portable/Net/HttpListenerContext.cs
new file mode 100644
index 0000000000..84c6a8c193
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/HttpListenerContext.cs
@@ -0,0 +1,201 @@
+using System;
+using System.Net;
+using System.Security.Principal;
+using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Text;
+using SocketHttpListener.Net.WebSockets;
+using SocketHttpListener.Primitives;
+
+namespace SocketHttpListener.Net
+{
+ public sealed class HttpListenerContext
+ {
+ HttpListenerRequest request;
+ HttpListenerResponse response;
+ IPrincipal user;
+ HttpConnection cnc;
+ string error;
+ int err_status = 400;
+ internal HttpListener Listener;
+ private readonly ILogger _logger;
+ private readonly ICryptoProvider _cryptoProvider;
+ private readonly IMemoryStreamFactory _memoryStreamFactory;
+ private readonly ITextEncoding _textEncoding;
+
+ internal HttpListenerContext(HttpConnection cnc, ILogger logger, ICryptoProvider cryptoProvider, IMemoryStreamFactory memoryStreamFactory, ITextEncoding textEncoding)
+ {
+ this.cnc = cnc;
+ _logger = logger;
+ _cryptoProvider = cryptoProvider;
+ _memoryStreamFactory = memoryStreamFactory;
+ _textEncoding = textEncoding;
+ request = new HttpListenerRequest(this, _textEncoding);
+ response = new HttpListenerResponse(this, _logger, _textEncoding);
+ }
+
+ internal int ErrorStatus
+ {
+ get { return err_status; }
+ set { err_status = value; }
+ }
+
+ internal string ErrorMessage
+ {
+ get { return error; }
+ set { error = value; }
+ }
+
+ internal bool HaveError
+ {
+ get { return (error != null); }
+ }
+
+ internal HttpConnection Connection
+ {
+ get { return cnc; }
+ }
+
+ public HttpListenerRequest Request
+ {
+ get { return request; }
+ }
+
+ public HttpListenerResponse Response
+ {
+ get { return response; }
+ }
+
+ public IPrincipal User
+ {
+ get { return user; }
+ }
+
+ internal void ParseAuthentication(AuthenticationSchemes expectedSchemes)
+ {
+ if (expectedSchemes == AuthenticationSchemes.Anonymous)
+ return;
+
+ // TODO: Handle NTLM/Digest modes
+ string header = request.Headers["Authorization"];
+ if (header == null || header.Length < 2)
+ return;
+
+ string[] authenticationData = header.Split(new char[] { ' ' }, 2);
+ if (string.Equals(authenticationData[0], "basic", StringComparison.OrdinalIgnoreCase))
+ {
+ user = ParseBasicAuthentication(authenticationData[1]);
+ }
+ // TODO: throw if malformed -> 400 bad request
+ }
+
+ internal IPrincipal ParseBasicAuthentication(string authData)
+ {
+ try
+ {
+ // Basic AUTH Data is a formatted Base64 String
+ //string domain = null;
+ string user = null;
+ string password = null;
+ int pos = -1;
+ var authDataBytes = Convert.FromBase64String(authData);
+ string authString = _textEncoding.GetDefaultEncoding().GetString(authDataBytes, 0, authDataBytes.Length);
+
+ // The format is DOMAIN\username:password
+ // Domain is optional
+
+ pos = authString.IndexOf(':');
+
+ // parse the password off the end
+ password = authString.Substring(pos + 1);
+
+ // discard the password
+ authString = authString.Substring(0, pos);
+
+ // check if there is a domain
+ pos = authString.IndexOf('\\');
+
+ if (pos > 0)
+ {
+ //domain = authString.Substring (0, pos);
+ user = authString.Substring(pos);
+ }
+ else
+ {
+ user = authString;
+ }
+
+ HttpListenerBasicIdentity identity = new HttpListenerBasicIdentity(user, password);
+ // TODO: What are the roles MS sets
+ return new GenericPrincipal(identity, new string[0]);
+ }
+ catch (Exception)
+ {
+ // Invalid auth data is swallowed silently
+ return null;
+ }
+ }
+
+ public HttpListenerWebSocketContext AcceptWebSocket(string protocol)
+ {
+ if (protocol != null)
+ {
+ if (protocol.Length == 0)
+ throw new ArgumentException("An empty string.", "protocol");
+
+ if (!protocol.IsToken())
+ throw new ArgumentException("Contains an invalid character.", "protocol");
+ }
+
+ return new HttpListenerWebSocketContext(this, protocol, _cryptoProvider, _memoryStreamFactory);
+ }
+ }
+
+ public class GenericPrincipal : IPrincipal
+ {
+ private IIdentity m_identity;
+ private string[] m_roles;
+
+ public GenericPrincipal(IIdentity identity, string[] roles)
+ {
+ if (identity == null)
+ throw new ArgumentNullException("identity");
+
+ m_identity = identity;
+ if (roles != null)
+ {
+ m_roles = new string[roles.Length];
+ for (int i = 0; i < roles.Length; ++i)
+ {
+ m_roles[i] = roles[i];
+ }
+ }
+ else
+ {
+ m_roles = null;
+ }
+ }
+
+ public virtual IIdentity Identity
+ {
+ get
+ {
+ return m_identity;
+ }
+ }
+
+ public virtual bool IsInRole(string role)
+ {
+ if (role == null || m_roles == null)
+ return false;
+
+ for (int i = 0; i < m_roles.Length; ++i)
+ {
+ if (m_roles[i] != null && String.Compare(m_roles[i], role, StringComparison.OrdinalIgnoreCase) == 0)
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/HttpListenerPrefixCollection.cs b/SocketHttpListener.Portable/Net/HttpListenerPrefixCollection.cs
new file mode 100644
index 0000000000..0b05539eea
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/HttpListenerPrefixCollection.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using MediaBrowser.Model.Logging;
+
+namespace SocketHttpListener.Net
+{
+ public class HttpListenerPrefixCollection : ICollection<string>, IEnumerable<string>, IEnumerable
+ {
+ List<string> prefixes = new List<string>();
+ HttpListener listener;
+
+ private ILogger _logger;
+
+ internal HttpListenerPrefixCollection(ILogger logger, HttpListener listener)
+ {
+ _logger = logger;
+ this.listener = listener;
+ }
+
+ public int Count
+ {
+ get { return prefixes.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return false; }
+ }
+
+ public bool IsSynchronized
+ {
+ get { return false; }
+ }
+
+ public void Add(string uriPrefix)
+ {
+ listener.CheckDisposed();
+ ListenerPrefix.CheckUri(uriPrefix);
+ if (prefixes.Contains(uriPrefix))
+ return;
+
+ prefixes.Add(uriPrefix);
+ if (listener.IsListening)
+ EndPointManager.AddPrefix(_logger, uriPrefix, listener);
+ }
+
+ public void Clear()
+ {
+ listener.CheckDisposed();
+ prefixes.Clear();
+ if (listener.IsListening)
+ EndPointManager.RemoveListener(_logger, listener);
+ }
+
+ public bool Contains(string uriPrefix)
+ {
+ listener.CheckDisposed();
+ return prefixes.Contains(uriPrefix);
+ }
+
+ public void CopyTo(string[] array, int offset)
+ {
+ listener.CheckDisposed();
+ prefixes.CopyTo(array, offset);
+ }
+
+ public void CopyTo(Array array, int offset)
+ {
+ listener.CheckDisposed();
+ ((ICollection)prefixes).CopyTo(array, offset);
+ }
+
+ public IEnumerator<string> GetEnumerator()
+ {
+ return prefixes.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return prefixes.GetEnumerator();
+ }
+
+ public bool Remove(string uriPrefix)
+ {
+ listener.CheckDisposed();
+ if (uriPrefix == null)
+ throw new ArgumentNullException("uriPrefix");
+
+ bool result = prefixes.Remove(uriPrefix);
+ if (result && listener.IsListening)
+ EndPointManager.RemovePrefix(_logger, uriPrefix, listener);
+
+ return result;
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/HttpListenerRequest.cs b/SocketHttpListener.Portable/Net/HttpListenerRequest.cs
new file mode 100644
index 0000000000..63d5e510d2
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/HttpListenerRequest.cs
@@ -0,0 +1,654 @@
+using System;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Services;
+using MediaBrowser.Model.Text;
+using SocketHttpListener.Primitives;
+
+namespace SocketHttpListener.Net
+{
+ public sealed class HttpListenerRequest
+ {
+ string[] accept_types;
+ Encoding content_encoding;
+ long content_length;
+ bool cl_set;
+ CookieCollection cookies;
+ WebHeaderCollection headers;
+ string method;
+ Stream input_stream;
+ Version version;
+ QueryParamCollection query_string; // check if null is ok, check if read-only, check case-sensitiveness
+ string raw_url;
+ Uri url;
+ Uri referrer;
+ string[] user_languages;
+ HttpListenerContext context;
+ bool is_chunked;
+ bool ka_set;
+ bool keep_alive;
+
+ private readonly ITextEncoding _textEncoding;
+
+ internal HttpListenerRequest(HttpListenerContext context, ITextEncoding textEncoding)
+ {
+ this.context = context;
+ _textEncoding = textEncoding;
+ headers = new WebHeaderCollection();
+ version = HttpVersion.Version10;
+ }
+
+ static char[] separators = new char[] { ' ' };
+
+ internal void SetRequestLine(string req)
+ {
+ string[] parts = req.Split(separators, 3);
+ if (parts.Length != 3)
+ {
+ context.ErrorMessage = "Invalid request line (parts).";
+ return;
+ }
+
+ method = parts[0];
+ foreach (char c in method)
+ {
+ int ic = (int)c;
+
+ if ((ic >= 'A' && ic <= 'Z') ||
+ (ic > 32 && c < 127 && c != '(' && c != ')' && c != '<' &&
+ c != '<' && c != '>' && c != '@' && c != ',' && c != ';' &&
+ c != ':' && c != '\\' && c != '"' && c != '/' && c != '[' &&
+ c != ']' && c != '?' && c != '=' && c != '{' && c != '}'))
+ continue;
+
+ context.ErrorMessage = "(Invalid verb)";
+ return;
+ }
+
+ raw_url = parts[1];
+ if (parts[2].Length != 8 || !parts[2].StartsWith("HTTP/"))
+ {
+ context.ErrorMessage = "Invalid request line (version).";
+ return;
+ }
+
+ try
+ {
+ version = new Version(parts[2].Substring(5));
+ if (version.Major < 1)
+ throw new Exception();
+ }
+ catch
+ {
+ context.ErrorMessage = "Invalid request line (version).";
+ return;
+ }
+ }
+
+ void CreateQueryString(string query)
+ {
+ if (query == null || query.Length == 0)
+ {
+ query_string = new QueryParamCollection();
+ return;
+ }
+
+ query_string = new QueryParamCollection();
+ if (query[0] == '?')
+ query = query.Substring(1);
+ string[] components = query.Split('&');
+ foreach (string kv in components)
+ {
+ int pos = kv.IndexOf('=');
+ if (pos == -1)
+ {
+ query_string.Add(null, WebUtility.UrlDecode(kv));
+ }
+ else
+ {
+ string key = WebUtility.UrlDecode(kv.Substring(0, pos));
+ string val = WebUtility.UrlDecode(kv.Substring(pos + 1));
+
+ query_string.Add(key, val);
+ }
+ }
+ }
+
+ internal void FinishInitialization()
+ {
+ string host = UserHostName;
+ if (version > HttpVersion.Version10 && (host == null || host.Length == 0))
+ {
+ context.ErrorMessage = "Invalid host name";
+ return;
+ }
+
+ string path;
+ Uri raw_uri = null;
+ if (MaybeUri(raw_url.ToLowerInvariant()) && Uri.TryCreate(raw_url, UriKind.Absolute, out raw_uri))
+ path = raw_uri.PathAndQuery;
+ else
+ path = raw_url;
+
+ if ((host == null || host.Length == 0))
+ host = UserHostAddress;
+
+ if (raw_uri != null)
+ host = raw_uri.Host;
+
+ int colon = host.LastIndexOf(':');
+ if (colon >= 0)
+ host = host.Substring(0, colon);
+
+ string base_uri = String.Format("{0}://{1}:{2}",
+ (IsSecureConnection) ? (IsWebSocketRequest ? "wss" : "https") : (IsWebSocketRequest ? "ws" : "http"),
+ host, LocalEndPoint.Port);
+
+ if (!Uri.TryCreate(base_uri + path, UriKind.Absolute, out url))
+ {
+ context.ErrorMessage = WebUtility.HtmlEncode("Invalid url: " + base_uri + path);
+ return; return;
+ }
+
+ CreateQueryString(url.Query);
+
+ if (version >= HttpVersion.Version11)
+ {
+ string t_encoding = Headers["Transfer-Encoding"];
+ is_chunked = (t_encoding != null && String.Compare(t_encoding, "chunked", StringComparison.OrdinalIgnoreCase) == 0);
+ // 'identity' is not valid!
+ if (t_encoding != null && !is_chunked)
+ {
+ context.Connection.SendError(null, 501);
+ return;
+ }
+ }
+
+ if (!is_chunked && !cl_set)
+ {
+ if (String.Compare(method, "POST", StringComparison.OrdinalIgnoreCase) == 0 ||
+ String.Compare(method, "PUT", StringComparison.OrdinalIgnoreCase) == 0)
+ {
+ context.Connection.SendError(null, 411);
+ return;
+ }
+ }
+
+ if (String.Compare(Headers["Expect"], "100-continue", StringComparison.OrdinalIgnoreCase) == 0)
+ {
+ ResponseStream output = context.Connection.GetResponseStream();
+
+ var _100continue = _textEncoding.GetASCIIEncoding().GetBytes("HTTP/1.1 100 Continue\r\n\r\n");
+
+ output.InternalWrite(_100continue, 0, _100continue.Length);
+ }
+ }
+
+ static bool MaybeUri(string s)
+ {
+ int p = s.IndexOf(':');
+ if (p == -1)
+ return false;
+
+ if (p >= 10)
+ return false;
+
+ return IsPredefinedScheme(s.Substring(0, p));
+ }
+
+ //
+ // Using a simple block of if's is twice as slow as the compiler generated
+ // switch statement. But using this tuned code is faster than the
+ // compiler generated code, with a million loops on x86-64:
+ //
+ // With "http": .10 vs .51 (first check)
+ // with "https": .16 vs .51 (second check)
+ // with "foo": .22 vs .31 (never found)
+ // with "mailto": .12 vs .51 (last check)
+ //
+ //
+ static bool IsPredefinedScheme(string scheme)
+ {
+ if (scheme == null || scheme.Length < 3)
+ return false;
+
+ char c = scheme[0];
+ if (c == 'h')
+ return (scheme == "http" || scheme == "https");
+ if (c == 'f')
+ return (scheme == "file" || scheme == "ftp");
+
+ if (c == 'n')
+ {
+ c = scheme[1];
+ if (c == 'e')
+ return (scheme == "news" || scheme == "net.pipe" || scheme == "net.tcp");
+ if (scheme == "nntp")
+ return true;
+ return false;
+ }
+ if ((c == 'g' && scheme == "gopher") || (c == 'm' && scheme == "mailto"))
+ return true;
+
+ return false;
+ }
+
+ internal static string Unquote(String str)
+ {
+ int start = str.IndexOf('\"');
+ int end = str.LastIndexOf('\"');
+ if (start >= 0 && end >= 0)
+ str = str.Substring(start + 1, end - 1);
+ return str.Trim();
+ }
+
+ internal void AddHeader(string header)
+ {
+ int colon = header.IndexOf(':');
+ if (colon == -1 || colon == 0)
+ {
+ context.ErrorMessage = "Bad Request";
+ context.ErrorStatus = 400;
+ return;
+ }
+
+ string name = header.Substring(0, colon).Trim();
+ string val = header.Substring(colon + 1).Trim();
+ string lower = name.ToLowerInvariant();
+ headers.SetInternal(name, val);
+ switch (lower)
+ {
+ case "accept-language":
+ user_languages = val.Split(','); // yes, only split with a ','
+ break;
+ case "accept":
+ accept_types = val.Split(','); // yes, only split with a ','
+ break;
+ case "content-length":
+ try
+ {
+ //TODO: max. content_length?
+ content_length = Int64.Parse(val.Trim());
+ if (content_length < 0)
+ context.ErrorMessage = "Invalid Content-Length.";
+ cl_set = true;
+ }
+ catch
+ {
+ context.ErrorMessage = "Invalid Content-Length.";
+ }
+
+ break;
+ case "content-type":
+ {
+ var contents = val.Split(';');
+ foreach (var content in contents)
+ {
+ var tmp = content.Trim();
+ if (tmp.StartsWith("charset"))
+ {
+ var charset = tmp.GetValue("=");
+ if (charset != null && charset.Length > 0)
+ {
+ try
+ {
+
+ // Support upnp/dlna devices - CONTENT-TYPE: text/xml ; charset="utf-8"\r\n
+ charset = charset.Trim('"');
+ var index = charset.IndexOf('"');
+ if (index != -1) charset = charset.Substring(0, index);
+
+ content_encoding = Encoding.GetEncoding(charset);
+ }
+ catch
+ {
+ context.ErrorMessage = "Invalid Content-Type header: " + charset;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ break;
+ case "referer":
+ try
+ {
+ referrer = new Uri(val);
+ }
+ catch
+ {
+ referrer = new Uri("http://someone.is.screwing.with.the.headers.com/");
+ }
+ break;
+ case "cookie":
+ if (cookies == null)
+ cookies = new CookieCollection();
+
+ string[] cookieStrings = val.Split(new char[] { ',', ';' });
+ Cookie current = null;
+ int version = 0;
+ foreach (string cookieString in cookieStrings)
+ {
+ string str = cookieString.Trim();
+ if (str.Length == 0)
+ continue;
+ if (str.StartsWith("$Version"))
+ {
+ version = Int32.Parse(Unquote(str.Substring(str.IndexOf('=') + 1)));
+ }
+ else if (str.StartsWith("$Path"))
+ {
+ if (current != null)
+ current.Path = str.Substring(str.IndexOf('=') + 1).Trim();
+ }
+ else if (str.StartsWith("$Domain"))
+ {
+ if (current != null)
+ current.Domain = str.Substring(str.IndexOf('=') + 1).Trim();
+ }
+ else if (str.StartsWith("$Port"))
+ {
+ if (current != null)
+ current.Port = str.Substring(str.IndexOf('=') + 1).Trim();
+ }
+ else
+ {
+ if (current != null)
+ {
+ cookies.Add(current);
+ }
+ current = new Cookie();
+ int idx = str.IndexOf('=');
+ if (idx > 0)
+ {
+ current.Name = str.Substring(0, idx).Trim();
+ current.Value = str.Substring(idx + 1).Trim();
+ }
+ else
+ {
+ current.Name = str.Trim();
+ current.Value = String.Empty;
+ }
+ current.Version = version;
+ }
+ }
+ if (current != null)
+ {
+ cookies.Add(current);
+ }
+ break;
+ }
+ }
+
+ // returns true is the stream could be reused.
+ internal bool FlushInput()
+ {
+ if (!HasEntityBody)
+ return true;
+
+ int length = 2048;
+ if (content_length > 0)
+ length = (int)Math.Min(content_length, (long)length);
+
+ byte[] bytes = new byte[length];
+ while (true)
+ {
+ // TODO: test if MS has a timeout when doing this
+ try
+ {
+ var task = InputStream.ReadAsync(bytes, 0, length);
+ var result = Task.WaitAll(new [] { task }, 1000);
+ if (!result)
+ {
+ return false;
+ }
+ if (task.Result <= 0)
+ {
+ return true;
+ }
+ }
+ catch (ObjectDisposedException e)
+ {
+ input_stream = null;
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ }
+
+ public string[] AcceptTypes
+ {
+ get { return accept_types; }
+ }
+
+ public int ClientCertificateError
+ {
+ get
+ {
+ HttpConnection cnc = context.Connection;
+ //if (cnc.ClientCertificate == null)
+ // throw new InvalidOperationException("No client certificate");
+ //int[] errors = cnc.ClientCertificateErrors;
+ //if (errors != null && errors.Length > 0)
+ // return errors[0];
+ return 0;
+ }
+ }
+
+ public Encoding ContentEncoding
+ {
+ get
+ {
+ if (content_encoding == null)
+ content_encoding = _textEncoding.GetDefaultEncoding();
+ return content_encoding;
+ }
+ }
+
+ public long ContentLength64
+ {
+ get { return content_length; }
+ }
+
+ public string ContentType
+ {
+ get { return headers["content-type"]; }
+ }
+
+ public CookieCollection Cookies
+ {
+ get
+ {
+ // TODO: check if the collection is read-only
+ if (cookies == null)
+ cookies = new CookieCollection();
+ return cookies;
+ }
+ }
+
+ public bool HasEntityBody
+ {
+ get { return (content_length > 0 || is_chunked); }
+ }
+
+ public QueryParamCollection Headers
+ {
+ get { return headers; }
+ }
+
+ public string HttpMethod
+ {
+ get { return method; }
+ }
+
+ public Stream InputStream
+ {
+ get
+ {
+ if (input_stream == null)
+ {
+ if (is_chunked || content_length > 0)
+ input_stream = context.Connection.GetRequestStream(is_chunked, content_length);
+ else
+ input_stream = Stream.Null;
+ }
+
+ return input_stream;
+ }
+ }
+
+ public bool IsAuthenticated
+ {
+ get { return false; }
+ }
+
+ public bool IsLocal
+ {
+ get { return RemoteEndPoint.IpAddress.Equals(IpAddressInfo.Loopback) || RemoteEndPoint.IpAddress.Equals(IpAddressInfo.IPv6Loopback) || LocalEndPoint.IpAddress.Equals(RemoteEndPoint.IpAddress); }
+ }
+
+ public bool IsSecureConnection
+ {
+ get { return context.Connection.IsSecure; }
+ }
+
+ public bool KeepAlive
+ {
+ get
+ {
+ if (ka_set)
+ return keep_alive;
+
+ ka_set = true;
+ // 1. Connection header
+ // 2. Protocol (1.1 == keep-alive by default)
+ // 3. Keep-Alive header
+ string cnc = headers["Connection"];
+ if (!String.IsNullOrEmpty(cnc))
+ {
+ keep_alive = (0 == String.Compare(cnc, "keep-alive", StringComparison.OrdinalIgnoreCase));
+ }
+ else if (version == HttpVersion.Version11)
+ {
+ keep_alive = true;
+ }
+ else
+ {
+ cnc = headers["keep-alive"];
+ if (!String.IsNullOrEmpty(cnc))
+ keep_alive = (0 != String.Compare(cnc, "closed", StringComparison.OrdinalIgnoreCase));
+ }
+ return keep_alive;
+ }
+ }
+
+ public IpEndPointInfo LocalEndPoint
+ {
+ get { return context.Connection.LocalEndPoint; }
+ }
+
+ public Version ProtocolVersion
+ {
+ get { return version; }
+ }
+
+ public QueryParamCollection QueryString
+ {
+ get { return query_string; }
+ }
+
+ public string RawUrl
+ {
+ get { return raw_url; }
+ }
+
+ public IpEndPointInfo RemoteEndPoint
+ {
+ get { return context.Connection.RemoteEndPoint; }
+ }
+
+ public Guid RequestTraceIdentifier
+ {
+ get { return Guid.Empty; }
+ }
+
+ public Uri Url
+ {
+ get { return url; }
+ }
+
+ public Uri UrlReferrer
+ {
+ get { return referrer; }
+ }
+
+ public string UserAgent
+ {
+ get { return headers["user-agent"]; }
+ }
+
+ public string UserHostAddress
+ {
+ get { return LocalEndPoint.ToString(); }
+ }
+
+ public string UserHostName
+ {
+ get { return headers["host"]; }
+ }
+
+ public string[] UserLanguages
+ {
+ get { return user_languages; }
+ }
+
+ public string ServiceName
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ private bool _websocketRequestWasSet;
+ private bool _websocketRequest;
+
+ /// <summary>
+ /// Gets a value indicating whether the request is a WebSocket connection request.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if the request is a WebSocket connection request; otherwise, <c>false</c>.
+ /// </value>
+ public bool IsWebSocketRequest
+ {
+ get
+ {
+ if (!_websocketRequestWasSet)
+ {
+ _websocketRequest = method == "GET" &&
+ version > HttpVersion.Version10 &&
+ headers.Contains("Upgrade", "websocket") &&
+ headers.Contains("Connection", "Upgrade");
+
+ _websocketRequestWasSet = true;
+ }
+
+ return _websocketRequest;
+ }
+ }
+
+ public Task<ICertificate> GetClientCertificateAsync()
+ {
+ return Task.FromResult<ICertificate>(null);
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/HttpListenerResponse.cs b/SocketHttpListener.Portable/Net/HttpListenerResponse.cs
new file mode 100644
index 0000000000..0bc827b5a4
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/HttpListenerResponse.cs
@@ -0,0 +1,517 @@
+using System;
+using System.Globalization;
+using System.IO;
+using System.Net;
+using System.Text;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Text;
+using SocketHttpListener.Primitives;
+
+namespace SocketHttpListener.Net
+{
+ public sealed class HttpListenerResponse : IDisposable
+ {
+ bool disposed;
+ Encoding content_encoding;
+ long content_length;
+ bool cl_set;
+ string content_type;
+ CookieCollection cookies;
+ WebHeaderCollection headers = new WebHeaderCollection();
+ bool keep_alive = true;
+ ResponseStream output_stream;
+ Version version = HttpVersion.Version11;
+ string location;
+ int status_code = 200;
+ string status_description = "OK";
+ bool chunked;
+ HttpListenerContext context;
+
+ internal bool HeadersSent;
+ internal object headers_lock = new object();
+
+ bool force_close_chunked;
+
+ private readonly ILogger _logger;
+ private readonly ITextEncoding _textEncoding;
+
+ internal HttpListenerResponse(HttpListenerContext context, ILogger logger, ITextEncoding textEncoding)
+ {
+ this.context = context;
+ _logger = logger;
+ _textEncoding = textEncoding;
+ }
+
+ internal bool CloseConnection
+ {
+ get
+ {
+ return headers["Connection"] == "close";
+ }
+ }
+
+ internal bool ForceCloseChunked
+ {
+ get { return force_close_chunked; }
+ }
+
+ public Encoding ContentEncoding
+ {
+ get
+ {
+ if (content_encoding == null)
+ content_encoding = _textEncoding.GetDefaultEncoding();
+ return content_encoding;
+ }
+ set
+ {
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+
+ content_encoding = value;
+ }
+ }
+
+ public long ContentLength64
+ {
+ get { return content_length; }
+ set
+ {
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+
+ if (HeadersSent)
+ throw new InvalidOperationException("Cannot be changed after headers are sent.");
+
+ if (value < 0)
+ throw new ArgumentOutOfRangeException("Must be >= 0", "value");
+
+ cl_set = true;
+ content_length = value;
+ }
+ }
+
+ public string ContentType
+ {
+ get { return content_type; }
+ set
+ {
+ // TODO: is null ok?
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+
+ content_type = value;
+ }
+ }
+
+ // RFC 2109, 2965 + the netscape specification at http://wp.netscape.com/newsref/std/cookie_spec.html
+ public CookieCollection Cookies
+ {
+ get
+ {
+ if (cookies == null)
+ cookies = new CookieCollection();
+ return cookies;
+ }
+ set { cookies = value; } // null allowed?
+ }
+
+ public WebHeaderCollection Headers
+ {
+ get { return headers; }
+ set
+ {
+ /**
+ * "If you attempt to set a Content-Length, Keep-Alive, Transfer-Encoding, or
+ * WWW-Authenticate header using the Headers property, an exception will be
+ * thrown. Use the KeepAlive or ContentLength64 properties to set these headers.
+ * You cannot set the Transfer-Encoding or WWW-Authenticate headers manually."
+ */
+ // TODO: check if this is marked readonly after headers are sent.
+ headers = value;
+ }
+ }
+
+ public bool KeepAlive
+ {
+ get { return keep_alive; }
+ set
+ {
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+
+ keep_alive = value;
+ }
+ }
+
+ public Stream OutputStream
+ {
+ get
+ {
+ if (output_stream == null)
+ output_stream = context.Connection.GetResponseStream();
+ return output_stream;
+ }
+ }
+
+ public Version ProtocolVersion
+ {
+ get { return version; }
+ set
+ {
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+
+ if (value == null)
+ throw new ArgumentNullException("value");
+
+ if (value.Major != 1 || (value.Minor != 0 && value.Minor != 1))
+ throw new ArgumentException("Must be 1.0 or 1.1", "value");
+
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+
+ version = value;
+ }
+ }
+
+ public string RedirectLocation
+ {
+ get { return location; }
+ set
+ {
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+
+ location = value;
+ }
+ }
+
+ public bool SendChunked
+ {
+ get { return chunked; }
+ set
+ {
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+
+ chunked = value;
+ }
+ }
+
+ public int StatusCode
+ {
+ get { return status_code; }
+ set
+ {
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+
+ if (value < 100 || value > 999)
+ throw new ProtocolViolationException("StatusCode must be between 100 and 999.");
+ status_code = value;
+ status_description = GetStatusDescription(value);
+ }
+ }
+
+ internal static string GetStatusDescription(int code)
+ {
+ switch (code)
+ {
+ case 100: return "Continue";
+ case 101: return "Switching Protocols";
+ case 102: return "Processing";
+ case 200: return "OK";
+ case 201: return "Created";
+ case 202: return "Accepted";
+ case 203: return "Non-Authoritative Information";
+ case 204: return "No Content";
+ case 205: return "Reset Content";
+ case 206: return "Partial Content";
+ case 207: return "Multi-Status";
+ case 300: return "Multiple Choices";
+ case 301: return "Moved Permanently";
+ case 302: return "Found";
+ case 303: return "See Other";
+ case 304: return "Not Modified";
+ case 305: return "Use Proxy";
+ case 307: return "Temporary Redirect";
+ case 400: return "Bad Request";
+ case 401: return "Unauthorized";
+ case 402: return "Payment Required";
+ case 403: return "Forbidden";
+ case 404: return "Not Found";
+ case 405: return "Method Not Allowed";
+ case 406: return "Not Acceptable";
+ case 407: return "Proxy Authentication Required";
+ case 408: return "Request Timeout";
+ case 409: return "Conflict";
+ case 410: return "Gone";
+ case 411: return "Length Required";
+ case 412: return "Precondition Failed";
+ case 413: return "Request Entity Too Large";
+ case 414: return "Request-Uri Too Long";
+ case 415: return "Unsupported Media Type";
+ case 416: return "Requested Range Not Satisfiable";
+ case 417: return "Expectation Failed";
+ case 422: return "Unprocessable Entity";
+ case 423: return "Locked";
+ case 424: return "Failed Dependency";
+ case 500: return "Internal Server Error";
+ case 501: return "Not Implemented";
+ case 502: return "Bad Gateway";
+ case 503: return "Service Unavailable";
+ case 504: return "Gateway Timeout";
+ case 505: return "Http Version Not Supported";
+ case 507: return "Insufficient Storage";
+ }
+ return "";
+ }
+
+ public string StatusDescription
+ {
+ get { return status_description; }
+ set
+ {
+ status_description = value;
+ }
+ }
+
+ void IDisposable.Dispose()
+ {
+ Close(true); //TODO: Abort or Close?
+ }
+
+ public void Abort()
+ {
+ if (disposed)
+ return;
+
+ Close(true);
+ }
+
+ public void AddHeader(string name, string value)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ if (name == "")
+ throw new ArgumentException("'name' cannot be empty", "name");
+
+ //TODO: check for forbidden headers and invalid characters
+ if (value.Length > 65535)
+ throw new ArgumentOutOfRangeException("value");
+
+ headers.Set(name, value);
+ }
+
+ public void AppendCookie(Cookie cookie)
+ {
+ if (cookie == null)
+ throw new ArgumentNullException("cookie");
+
+ Cookies.Add(cookie);
+ }
+
+ public void AppendHeader(string name, string value)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ if (name == "")
+ throw new ArgumentException("'name' cannot be empty", "name");
+
+ if (value.Length > 65535)
+ throw new ArgumentOutOfRangeException("value");
+
+ headers.Add(name, value);
+ }
+
+ void Close(bool force)
+ {
+ if (force)
+ {
+ _logger.Debug("HttpListenerResponse force closing HttpConnection");
+ }
+ disposed = true;
+ context.Connection.Close(force);
+ }
+
+ public void Close()
+ {
+ if (disposed)
+ return;
+
+ Close(false);
+ }
+
+ public void Close(byte[] responseEntity, bool willBlock)
+ {
+ if (disposed)
+ return;
+
+ if (responseEntity == null)
+ throw new ArgumentNullException("responseEntity");
+
+ //TODO: if willBlock -> BeginWrite + Close ?
+ ContentLength64 = responseEntity.Length;
+ OutputStream.Write(responseEntity, 0, (int)content_length);
+ Close(false);
+ }
+
+ public void Redirect(string url)
+ {
+ StatusCode = 302; // Found
+ location = url;
+ }
+
+ bool FindCookie(Cookie cookie)
+ {
+ string name = cookie.Name;
+ string domain = cookie.Domain;
+ string path = cookie.Path;
+ foreach (Cookie c in cookies)
+ {
+ if (name != c.Name)
+ continue;
+ if (domain != c.Domain)
+ continue;
+ if (path == c.Path)
+ return true;
+ }
+
+ return false;
+ }
+
+ internal void SendHeaders(bool closing, MemoryStream ms)
+ {
+ Encoding encoding = content_encoding;
+ if (encoding == null)
+ encoding = _textEncoding.GetDefaultEncoding();
+
+ if (content_type != null)
+ {
+ if (content_encoding != null && content_type.IndexOf("charset=", StringComparison.Ordinal) == -1)
+ {
+ string enc_name = content_encoding.WebName;
+ headers.SetInternal("Content-Type", content_type + "; charset=" + enc_name);
+ }
+ else
+ {
+ headers.SetInternal("Content-Type", content_type);
+ }
+ }
+
+ if (headers["Server"] == null)
+ headers.SetInternal("Server", "Mono-HTTPAPI/1.0");
+
+ CultureInfo inv = CultureInfo.InvariantCulture;
+ if (headers["Date"] == null)
+ headers.SetInternal("Date", DateTime.UtcNow.ToString("r", inv));
+
+ if (!chunked)
+ {
+ if (!cl_set && closing)
+ {
+ cl_set = true;
+ content_length = 0;
+ }
+
+ if (cl_set)
+ headers.SetInternal("Content-Length", content_length.ToString(inv));
+ }
+
+ Version v = context.Request.ProtocolVersion;
+ if (!cl_set && !chunked && v >= HttpVersion.Version11)
+ chunked = true;
+
+ /* Apache forces closing the connection for these status codes:
+ * HttpStatusCode.BadRequest 400
+ * HttpStatusCode.RequestTimeout 408
+ * HttpStatusCode.LengthRequired 411
+ * HttpStatusCode.RequestEntityTooLarge 413
+ * HttpStatusCode.RequestUriTooLong 414
+ * HttpStatusCode.InternalServerError 500
+ * HttpStatusCode.ServiceUnavailable 503
+ */
+ bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 ||
+ status_code == 413 || status_code == 414 || status_code == 500 ||
+ status_code == 503);
+
+ if (conn_close == false)
+ conn_close = !context.Request.KeepAlive;
+
+ // They sent both KeepAlive: true and Connection: close!?
+ if (!keep_alive || conn_close)
+ {
+ headers.SetInternal("Connection", "close");
+ conn_close = true;
+ }
+
+ if (chunked)
+ headers.SetInternal("Transfer-Encoding", "chunked");
+
+ //int reuses = context.Connection.Reuses;
+ //if (reuses >= 100)
+ //{
+ // _logger.Debug("HttpListenerResponse - keep alive has exceeded 100 uses and will be closed.");
+
+ // force_close_chunked = true;
+ // if (!conn_close)
+ // {
+ // headers.SetInternal("Connection", "close");
+ // conn_close = true;
+ // }
+ //}
+
+ if (!conn_close)
+ {
+ if (context.Request.ProtocolVersion <= HttpVersion.Version10)
+ headers.SetInternal("Connection", "keep-alive");
+ }
+
+ if (location != null)
+ headers.SetInternal("Location", location);
+
+ if (cookies != null)
+ {
+ foreach (Cookie cookie in cookies)
+ headers.SetInternal("Set-Cookie", cookie.ToString());
+ }
+
+ using (StreamWriter writer = new StreamWriter(ms, encoding, 256, true))
+ {
+ writer.Write("HTTP/{0} {1} {2}\r\n", version, status_code, status_description);
+ string headers_str = headers.ToStringMultiValue();
+ writer.Write(headers_str);
+ writer.Flush();
+ }
+
+ int preamble = encoding.GetPreamble().Length;
+ if (output_stream == null)
+ output_stream = context.Connection.GetResponseStream();
+
+ /* Assumes that the ms was at position 0 */
+ ms.Position = preamble;
+ HeadersSent = true;
+ }
+
+ public void SetCookie(Cookie cookie)
+ {
+ if (cookie == null)
+ throw new ArgumentNullException("cookie");
+
+ if (cookies != null)
+ {
+ if (FindCookie(cookie))
+ throw new ArgumentException("The cookie already exists.");
+ }
+ else
+ {
+ cookies = new CookieCollection();
+ }
+
+ cookies.Add(cookie);
+ }
+ }
+} \ No newline at end of file
diff --git a/SocketHttpListener.Portable/Net/HttpStatusCode.cs b/SocketHttpListener.Portable/Net/HttpStatusCode.cs
new file mode 100644
index 0000000000..93da82ba08
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/HttpStatusCode.cs
@@ -0,0 +1,321 @@
+namespace SocketHttpListener.Net
+{
+ /// <summary>
+ /// Contains the values of the HTTP status codes.
+ /// </summary>
+ /// <remarks>
+ /// The HttpStatusCode enumeration contains the values of the HTTP status codes defined in
+ /// <see href="http://tools.ietf.org/html/rfc2616#section-10">RFC 2616</see> for HTTP 1.1.
+ /// </remarks>
+ public enum HttpStatusCode
+ {
+ /// <summary>
+ /// Equivalent to status code 100.
+ /// Indicates that the client should continue with its request.
+ /// </summary>
+ Continue = 100,
+ /// <summary>
+ /// Equivalent to status code 101.
+ /// Indicates that the server is switching the HTTP version or protocol on the connection.
+ /// </summary>
+ SwitchingProtocols = 101,
+ /// <summary>
+ /// Equivalent to status code 200.
+ /// Indicates that the client's request has succeeded.
+ /// </summary>
+ OK = 200,
+ /// <summary>
+ /// Equivalent to status code 201.
+ /// Indicates that the client's request has been fulfilled and resulted in a new resource being
+ /// created.
+ /// </summary>
+ Created = 201,
+ /// <summary>
+ /// Equivalent to status code 202.
+ /// Indicates that the client's request has been accepted for processing, but the processing
+ /// hasn't been completed.
+ /// </summary>
+ Accepted = 202,
+ /// <summary>
+ /// Equivalent to status code 203.
+ /// Indicates that the returned metainformation is from a local or a third-party copy instead of
+ /// the origin server.
+ /// </summary>
+ NonAuthoritativeInformation = 203,
+ /// <summary>
+ /// Equivalent to status code 204.
+ /// Indicates that the server has fulfilled the client's request but doesn't need to return
+ /// an entity-body.
+ /// </summary>
+ NoContent = 204,
+ /// <summary>
+ /// Equivalent to status code 205.
+ /// Indicates that the server has fulfilled the client's request, and the user agent should
+ /// reset the document view which caused the request to be sent.
+ /// </summary>
+ ResetContent = 205,
+ /// <summary>
+ /// Equivalent to status code 206.
+ /// Indicates that the server has fulfilled the partial GET request for the resource.
+ /// </summary>
+ PartialContent = 206,
+ /// <summary>
+ /// <para>
+ /// Equivalent to status code 300.
+ /// Indicates that the requested resource corresponds to any of multiple representations.
+ /// </para>
+ /// <para>
+ /// MultipleChoices is a synonym for Ambiguous.
+ /// </para>
+ /// </summary>
+ MultipleChoices = 300,
+ /// <summary>
+ /// <para>
+ /// Equivalent to status code 300.
+ /// Indicates that the requested resource corresponds to any of multiple representations.
+ /// </para>
+ /// <para>
+ /// Ambiguous is a synonym for MultipleChoices.
+ /// </para>
+ /// </summary>
+ Ambiguous = 300,
+ /// <summary>
+ /// <para>
+ /// Equivalent to status code 301.
+ /// Indicates that the requested resource has been assigned a new permanent URI and
+ /// any future references to this resource should use one of the returned URIs.
+ /// </para>
+ /// <para>
+ /// MovedPermanently is a synonym for Moved.
+ /// </para>
+ /// </summary>
+ MovedPermanently = 301,
+ /// <summary>
+ /// <para>
+ /// Equivalent to status code 301.
+ /// Indicates that the requested resource has been assigned a new permanent URI and
+ /// any future references to this resource should use one of the returned URIs.
+ /// </para>
+ /// <para>
+ /// Moved is a synonym for MovedPermanently.
+ /// </para>
+ /// </summary>
+ Moved = 301,
+ /// <summary>
+ /// <para>
+ /// Equivalent to status code 302.
+ /// Indicates that the requested resource is located temporarily under a different URI.
+ /// </para>
+ /// <para>
+ /// Found is a synonym for Redirect.
+ /// </para>
+ /// </summary>
+ Found = 302,
+ /// <summary>
+ /// <para>
+ /// Equivalent to status code 302.
+ /// Indicates that the requested resource is located temporarily under a different URI.
+ /// </para>
+ /// <para>
+ /// Redirect is a synonym for Found.
+ /// </para>
+ /// </summary>
+ Redirect = 302,
+ /// <summary>
+ /// <para>
+ /// Equivalent to status code 303.
+ /// Indicates that the response to the request can be found under a different URI and
+ /// should be retrieved using a GET method on that resource.
+ /// </para>
+ /// <para>
+ /// SeeOther is a synonym for RedirectMethod.
+ /// </para>
+ /// </summary>
+ SeeOther = 303,
+ /// <summary>
+ /// <para>
+ /// Equivalent to status code 303.
+ /// Indicates that the response to the request can be found under a different URI and
+ /// should be retrieved using a GET method on that resource.
+ /// </para>
+ /// <para>
+ /// RedirectMethod is a synonym for SeeOther.
+ /// </para>
+ /// </summary>
+ RedirectMethod = 303,
+ /// <summary>
+ /// Equivalent to status code 304.
+ /// Indicates that the client has performed a conditional GET request and access is allowed,
+ /// but the document hasn't been modified.
+ /// </summary>
+ NotModified = 304,
+ /// <summary>
+ /// Equivalent to status code 305.
+ /// Indicates that the requested resource must be accessed through the proxy given by
+ /// the Location field.
+ /// </summary>
+ UseProxy = 305,
+ /// <summary>
+ /// Equivalent to status code 306.
+ /// This status code was used in a previous version of the specification, is no longer used,
+ /// and is reserved for future use.
+ /// </summary>
+ Unused = 306,
+ /// <summary>
+ /// <para>
+ /// Equivalent to status code 307.
+ /// Indicates that the requested resource is located temporarily under a different URI.
+ /// </para>
+ /// <para>
+ /// TemporaryRedirect is a synonym for RedirectKeepVerb.
+ /// </para>
+ /// </summary>
+ TemporaryRedirect = 307,
+ /// <summary>
+ /// <para>
+ /// Equivalent to status code 307.
+ /// Indicates that the requested resource is located temporarily under a different URI.
+ /// </para>
+ /// <para>
+ /// RedirectKeepVerb is a synonym for TemporaryRedirect.
+ /// </para>
+ /// </summary>
+ RedirectKeepVerb = 307,
+ /// <summary>
+ /// Equivalent to status code 400.
+ /// Indicates that the client's request couldn't be understood by the server due to
+ /// malformed syntax.
+ /// </summary>
+ BadRequest = 400,
+ /// <summary>
+ /// Equivalent to status code 401.
+ /// Indicates that the client's request requires user authentication.
+ /// </summary>
+ Unauthorized = 401,
+ /// <summary>
+ /// Equivalent to status code 402.
+ /// This status code is reserved for future use.
+ /// </summary>
+ PaymentRequired = 402,
+ /// <summary>
+ /// Equivalent to status code 403.
+ /// Indicates that the server understood the client's request but is refusing to fulfill it.
+ /// </summary>
+ Forbidden = 403,
+ /// <summary>
+ /// Equivalent to status code 404.
+ /// Indicates that the server hasn't found anything matching the request URI.
+ /// </summary>
+ NotFound = 404,
+ /// <summary>
+ /// Equivalent to status code 405.
+ /// Indicates that the method specified in the request line isn't allowed for the resource
+ /// identified by the request URI.
+ /// </summary>
+ MethodNotAllowed = 405,
+ /// <summary>
+ /// Equivalent to status code 406.
+ /// Indicates that the server doesn't have the appropriate resource to respond to the Accept
+ /// headers in the client's request.
+ /// </summary>
+ NotAcceptable = 406,
+ /// <summary>
+ /// Equivalent to status code 407.
+ /// Indicates that the client must first authenticate itself with the proxy.
+ /// </summary>
+ ProxyAuthenticationRequired = 407,
+ /// <summary>
+ /// Equivalent to status code 408.
+ /// Indicates that the client didn't produce a request within the time that the server was
+ /// prepared to wait.
+ /// </summary>
+ RequestTimeout = 408,
+ /// <summary>
+ /// Equivalent to status code 409.
+ /// Indicates that the client's request couldn't be completed due to a conflict on the server.
+ /// </summary>
+ Conflict = 409,
+ /// <summary>
+ /// Equivalent to status code 410.
+ /// Indicates that the requested resource is no longer available at the server and
+ /// no forwarding address is known.
+ /// </summary>
+ Gone = 410,
+ /// <summary>
+ /// Equivalent to status code 411.
+ /// Indicates that the server refuses to accept the client's request without a defined
+ /// Content-Length.
+ /// </summary>
+ LengthRequired = 411,
+ /// <summary>
+ /// Equivalent to status code 412.
+ /// Indicates that the precondition given in one or more of the request headers evaluated to
+ /// false when it was tested on the server.
+ /// </summary>
+ PreconditionFailed = 412,
+ /// <summary>
+ /// Equivalent to status code 413.
+ /// Indicates that the entity of the client's request is larger than the server is willing or
+ /// able to process.
+ /// </summary>
+ RequestEntityTooLarge = 413,
+ /// <summary>
+ /// Equivalent to status code 414.
+ /// Indicates that the request URI is longer than the server is willing to interpret.
+ /// </summary>
+ RequestUriTooLong = 414,
+ /// <summary>
+ /// Equivalent to status code 415.
+ /// Indicates that the entity of the client's request is in a format not supported by
+ /// the requested resource for the requested method.
+ /// </summary>
+ UnsupportedMediaType = 415,
+ /// <summary>
+ /// Equivalent to status code 416.
+ /// Indicates that none of the range specifier values in a Range request header overlap
+ /// the current extent of the selected resource.
+ /// </summary>
+ RequestedRangeNotSatisfiable = 416,
+ /// <summary>
+ /// Equivalent to status code 417.
+ /// Indicates that the expectation given in an Expect request header couldn't be met by
+ /// the server.
+ /// </summary>
+ ExpectationFailed = 417,
+ /// <summary>
+ /// Equivalent to status code 500.
+ /// Indicates that the server encountered an unexpected condition which prevented it from
+ /// fulfilling the client's request.
+ /// </summary>
+ InternalServerError = 500,
+ /// <summary>
+ /// Equivalent to status code 501.
+ /// Indicates that the server doesn't support the functionality required to fulfill the client's
+ /// request.
+ /// </summary>
+ NotImplemented = 501,
+ /// <summary>
+ /// Equivalent to status code 502.
+ /// Indicates that a gateway or proxy server received an invalid response from the upstream
+ /// server.
+ /// </summary>
+ BadGateway = 502,
+ /// <summary>
+ /// Equivalent to status code 503.
+ /// Indicates that the server is currently unable to handle the client's request due to
+ /// a temporary overloading or maintenance of the server.
+ /// </summary>
+ ServiceUnavailable = 503,
+ /// <summary>
+ /// Equivalent to status code 504.
+ /// Indicates that a gateway or proxy server didn't receive a timely response from the upstream
+ /// server or some other auxiliary server.
+ /// </summary>
+ GatewayTimeout = 504,
+ /// <summary>
+ /// Equivalent to status code 505.
+ /// Indicates that the server doesn't support the HTTP version used in the client's request.
+ /// </summary>
+ HttpVersionNotSupported = 505,
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/HttpStreamAsyncResult.cs b/SocketHttpListener.Portable/Net/HttpStreamAsyncResult.cs
new file mode 100644
index 0000000000..518c45acba
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/HttpStreamAsyncResult.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Threading;
+
+namespace SocketHttpListener.Net
+{
+ class HttpStreamAsyncResult : IAsyncResult
+ {
+ object locker = new object();
+ ManualResetEvent handle;
+ bool completed;
+
+ internal byte[] Buffer;
+ internal int Offset;
+ internal int Count;
+ internal AsyncCallback Callback;
+ internal object State;
+ internal int SynchRead;
+ internal Exception Error;
+
+ public void Complete(Exception e)
+ {
+ Error = e;
+ Complete();
+ }
+
+ public void Complete()
+ {
+ lock (locker)
+ {
+ if (completed)
+ return;
+
+ completed = true;
+ if (handle != null)
+ handle.Set();
+
+ if (Callback != null)
+ Callback.BeginInvoke(this, null, null);
+ }
+ }
+
+ public object AsyncState
+ {
+ get { return State; }
+ }
+
+ public WaitHandle AsyncWaitHandle
+ {
+ get
+ {
+ lock (locker)
+ {
+ if (handle == null)
+ handle = new ManualResetEvent(completed);
+ }
+
+ return handle;
+ }
+ }
+
+ public bool CompletedSynchronously
+ {
+ get { return (SynchRead == Count); }
+ }
+
+ public bool IsCompleted
+ {
+ get
+ {
+ lock (locker)
+ {
+ return completed;
+ }
+ }
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/HttpVersion.cs b/SocketHttpListener.Portable/Net/HttpVersion.cs
new file mode 100644
index 0000000000..c0839b46d5
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/HttpVersion.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace SocketHttpListener.Net
+{
+ // <remarks>
+ // </remarks>
+ public class HttpVersion
+ {
+
+ public static readonly Version Version10 = new Version(1, 0);
+ public static readonly Version Version11 = new Version(1, 1);
+
+ // pretty useless..
+ public HttpVersion() { }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/ListenerPrefix.cs b/SocketHttpListener.Portable/Net/ListenerPrefix.cs
new file mode 100644
index 0000000000..2c314da506
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/ListenerPrefix.cs
@@ -0,0 +1,148 @@
+using System;
+using System.Net;
+using MediaBrowser.Model.Net;
+
+namespace SocketHttpListener.Net
+{
+ sealed class ListenerPrefix
+ {
+ string original;
+ string host;
+ ushort port;
+ string path;
+ bool secure;
+ IpAddressInfo[] addresses;
+ public HttpListener Listener;
+
+ public ListenerPrefix(string prefix)
+ {
+ this.original = prefix;
+ Parse(prefix);
+ }
+
+ public override string ToString()
+ {
+ return original;
+ }
+
+ public IpAddressInfo[] Addresses
+ {
+ get { return addresses; }
+ set { addresses = value; }
+ }
+ public bool Secure
+ {
+ get { return secure; }
+ }
+
+ public string Host
+ {
+ get { return host; }
+ }
+
+ public int Port
+ {
+ get { return (int)port; }
+ }
+
+ public string Path
+ {
+ get { return path; }
+ }
+
+ // Equals and GetHashCode are required to detect duplicates in HttpListenerPrefixCollection.
+ public override bool Equals(object o)
+ {
+ ListenerPrefix other = o as ListenerPrefix;
+ if (other == null)
+ return false;
+
+ return (original == other.original);
+ }
+
+ public override int GetHashCode()
+ {
+ return original.GetHashCode();
+ }
+
+ void Parse(string uri)
+ {
+ ushort default_port = 80;
+ if (uri.StartsWith("https://"))
+ {
+ default_port = 443;
+ secure = true;
+ }
+
+ int length = uri.Length;
+ int start_host = uri.IndexOf(':') + 3;
+ if (start_host >= length)
+ throw new ArgumentException("No host specified.");
+
+ int colon = uri.IndexOf(':', start_host, length - start_host);
+ int root;
+ if (colon > 0)
+ {
+ host = uri.Substring(start_host, colon - start_host);
+ root = uri.IndexOf('/', colon, length - colon);
+ port = (ushort)Int32.Parse(uri.Substring(colon + 1, root - colon - 1));
+ path = uri.Substring(root);
+ }
+ else
+ {
+ root = uri.IndexOf('/', start_host, length - start_host);
+ host = uri.Substring(start_host, root - start_host);
+ port = default_port;
+ path = uri.Substring(root);
+ }
+ if (path.Length != 1)
+ path = path.Substring(0, path.Length - 1);
+ }
+
+ public static void CheckUri(string uri)
+ {
+ if (uri == null)
+ throw new ArgumentNullException("uriPrefix");
+
+ if (!uri.StartsWith("http://") && !uri.StartsWith("https://"))
+ throw new ArgumentException("Only 'http' and 'https' schemes are supported.");
+
+ int length = uri.Length;
+ int start_host = uri.IndexOf(':') + 3;
+ if (start_host >= length)
+ throw new ArgumentException("No host specified.");
+
+ int colon = uri.IndexOf(':', start_host, length - start_host);
+ if (start_host == colon)
+ throw new ArgumentException("No host specified.");
+
+ int root;
+ if (colon > 0)
+ {
+ root = uri.IndexOf('/', colon, length - colon);
+ if (root == -1)
+ throw new ArgumentException("No path specified.");
+
+ try
+ {
+ int p = Int32.Parse(uri.Substring(colon + 1, root - colon - 1));
+ if (p <= 0 || p >= 65536)
+ throw new Exception();
+ }
+ catch
+ {
+ throw new ArgumentException("Invalid port.");
+ }
+ }
+ else
+ {
+ root = uri.IndexOf('/', start_host, length - start_host);
+ if (root == -1)
+ throw new ArgumentException("No path specified.");
+ }
+
+ if (uri[uri.Length - 1] != '/')
+ throw new ArgumentException("The prefix must end with '/'");
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/RequestStream.cs b/SocketHttpListener.Portable/Net/RequestStream.cs
new file mode 100644
index 0000000000..58030500d1
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/RequestStream.cs
@@ -0,0 +1,231 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace SocketHttpListener.Net
+{
+ class RequestStream : Stream
+ {
+ byte[] buffer;
+ int offset;
+ int length;
+ long remaining_body;
+ bool disposed;
+ Stream stream;
+
+ internal RequestStream(Stream stream, byte[] buffer, int offset, int length)
+ : this(stream, buffer, offset, length, -1)
+ {
+ }
+
+ internal RequestStream(Stream stream, byte[] buffer, int offset, int length, long contentlength)
+ {
+ this.stream = stream;
+ this.buffer = buffer;
+ this.offset = offset;
+ this.length = length;
+ this.remaining_body = contentlength;
+ }
+
+ public override bool CanRead
+ {
+ get { return true; }
+ }
+
+ public override bool CanSeek
+ {
+ get { return false; }
+ }
+
+ public override bool CanWrite
+ {
+ get { return false; }
+ }
+
+ public override long Length
+ {
+ get { throw new NotSupportedException(); }
+ }
+
+ public override long Position
+ {
+ get { throw new NotSupportedException(); }
+ set { throw new NotSupportedException(); }
+ }
+
+
+ protected override void Dispose(bool disposing)
+ {
+ disposed = true;
+ }
+
+ public override void Flush()
+ {
+ }
+
+
+ // Returns 0 if we can keep reading from the base stream,
+ // > 0 if we read something from the buffer.
+ // -1 if we had a content length set and we finished reading that many bytes.
+ int FillFromBuffer(byte[] buffer, int off, int count)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException("buffer");
+ if (off < 0)
+ throw new ArgumentOutOfRangeException("offset", "< 0");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", "< 0");
+ int len = buffer.Length;
+ if (off > len)
+ throw new ArgumentException("destination offset is beyond array size");
+ if (off > len - count)
+ throw new ArgumentException("Reading would overrun buffer");
+
+ if (this.remaining_body == 0)
+ return -1;
+
+ if (this.length == 0)
+ return 0;
+
+ int size = Math.Min(this.length, count);
+ if (this.remaining_body > 0)
+ size = (int)Math.Min(size, this.remaining_body);
+
+ if (this.offset > this.buffer.Length - size)
+ {
+ size = Math.Min(size, this.buffer.Length - this.offset);
+ }
+ if (size == 0)
+ return 0;
+
+ Buffer.BlockCopy(this.buffer, this.offset, buffer, off, size);
+ this.offset += size;
+ this.length -= size;
+ if (this.remaining_body > 0)
+ remaining_body -= size;
+ return size;
+ }
+
+ public override int Read([In, Out] byte[] buffer, int offset, int count)
+ {
+ if (disposed)
+ throw new ObjectDisposedException(typeof(RequestStream).ToString());
+
+ // Call FillFromBuffer to check for buffer boundaries even when remaining_body is 0
+ int nread = FillFromBuffer(buffer, offset, count);
+ if (nread == -1)
+ { // No more bytes available (Content-Length)
+ return 0;
+ }
+ else if (nread > 0)
+ {
+ return nread;
+ }
+
+ nread = stream.Read(buffer, offset, count);
+ if (nread > 0 && remaining_body > 0)
+ remaining_body -= nread;
+ return nread;
+ }
+
+ public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ if (disposed)
+ throw new ObjectDisposedException(typeof(RequestStream).ToString());
+
+ int nread = FillFromBuffer(buffer, offset, count);
+ if (nread > 0 || nread == -1)
+ {
+ return Math.Max(0, nread);
+ }
+
+ // Avoid reading past the end of the request to allow
+ // for HTTP pipelining
+ if (remaining_body >= 0 && count > remaining_body)
+ count = (int)Math.Min(Int32.MaxValue, remaining_body);
+
+ nread = await stream.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
+ if (remaining_body > 0 && nread > 0)
+ remaining_body -= nread;
+ return nread;
+ }
+
+ //public override IAsyncResult BeginRead(byte[] buffer, int offset, int count,
+ // AsyncCallback cback, object state)
+ //{
+ // if (disposed)
+ // throw new ObjectDisposedException(typeof(RequestStream).ToString());
+
+ // int nread = FillFromBuffer(buffer, offset, count);
+ // if (nread > 0 || nread == -1)
+ // {
+ // HttpStreamAsyncResult ares = new HttpStreamAsyncResult();
+ // ares.Buffer = buffer;
+ // ares.Offset = offset;
+ // ares.Count = count;
+ // ares.Callback = cback;
+ // ares.State = state;
+ // ares.SynchRead = Math.Max(0, nread);
+ // ares.Complete();
+ // return ares;
+ // }
+
+ // // Avoid reading past the end of the request to allow
+ // // for HTTP pipelining
+ // if (remaining_body >= 0 && count > remaining_body)
+ // count = (int)Math.Min(Int32.MaxValue, remaining_body);
+ // return stream.BeginRead(buffer, offset, count, cback, state);
+ //}
+
+ //public override int EndRead(IAsyncResult ares)
+ //{
+ // if (disposed)
+ // throw new ObjectDisposedException(typeof(RequestStream).ToString());
+
+ // if (ares == null)
+ // throw new ArgumentNullException("async_result");
+
+ // if (ares is HttpStreamAsyncResult)
+ // {
+ // HttpStreamAsyncResult r = (HttpStreamAsyncResult)ares;
+ // if (!ares.IsCompleted)
+ // ares.AsyncWaitHandle.WaitOne();
+ // return r.SynchRead;
+ // }
+
+ // // Close on exception?
+ // int nread = stream.EndRead(ares);
+ // if (remaining_body > 0 && nread > 0)
+ // remaining_body -= nread;
+ // return nread;
+ //}
+
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ throw new NotSupportedException();
+ }
+
+ public override void SetLength(long value)
+ {
+ throw new NotSupportedException();
+ }
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ throw new NotSupportedException();
+ }
+
+ //public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count,
+ // AsyncCallback cback, object state)
+ //{
+ // throw new NotSupportedException();
+ //}
+
+ //public override void EndWrite(IAsyncResult async_result)
+ //{
+ // throw new NotSupportedException();
+ //}
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/ResponseStream.cs b/SocketHttpListener.Portable/Net/ResponseStream.cs
new file mode 100644
index 0000000000..6ecbf97427
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/ResponseStream.cs
@@ -0,0 +1,316 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Text;
+using SocketHttpListener.Primitives;
+
+namespace SocketHttpListener.Net
+{
+ // FIXME: Does this buffer the response until Close?
+ // Update: we send a single packet for the first non-chunked Write
+ // What happens when we set content-length to X and write X-1 bytes then close?
+ // what if we don't set content-length at all?
+ class ResponseStream : Stream
+ {
+ HttpListenerResponse response;
+ bool ignore_errors;
+ bool disposed;
+ bool trailer_sent;
+ Stream stream;
+ private readonly IMemoryStreamFactory _memoryStreamFactory;
+ private readonly ITextEncoding _textEncoding;
+
+ internal ResponseStream(Stream stream, HttpListenerResponse response, bool ignore_errors, IMemoryStreamFactory memoryStreamFactory, ITextEncoding textEncoding)
+ {
+ this.response = response;
+ this.ignore_errors = ignore_errors;
+ _memoryStreamFactory = memoryStreamFactory;
+ _textEncoding = textEncoding;
+ this.stream = stream;
+ }
+
+ public override bool CanRead
+ {
+ get { return false; }
+ }
+
+ public override bool CanSeek
+ {
+ get { return false; }
+ }
+
+ public override bool CanWrite
+ {
+ get { return true; }
+ }
+
+ public override long Length
+ {
+ get { throw new NotSupportedException(); }
+ }
+
+ public override long Position
+ {
+ get { throw new NotSupportedException(); }
+ set { throw new NotSupportedException(); }
+ }
+
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposed == false)
+ {
+ disposed = true;
+ byte[] bytes = null;
+ MemoryStream ms = GetHeaders(true);
+ bool chunked = response.SendChunked;
+ if (stream.CanWrite)
+ {
+ try
+ {
+ if (ms != null)
+ {
+ long start = ms.Position;
+ if (chunked && !trailer_sent)
+ {
+ bytes = GetChunkSizeBytes(0, true);
+ ms.Position = ms.Length;
+ ms.Write(bytes, 0, bytes.Length);
+ }
+ byte[] msBuffer;
+ _memoryStreamFactory.TryGetBuffer(ms, out msBuffer);
+ InternalWrite(msBuffer, (int)start, (int)(ms.Length - start));
+ trailer_sent = true;
+ }
+ else if (chunked && !trailer_sent)
+ {
+ bytes = GetChunkSizeBytes(0, true);
+ InternalWrite(bytes, 0, bytes.Length);
+ trailer_sent = true;
+ }
+ }
+ catch (IOException ex)
+ {
+ // Ignore error due to connection reset by peer
+ }
+ }
+ response.Close();
+ }
+
+ base.Dispose(disposing);
+ }
+
+ MemoryStream GetHeaders(bool closing)
+ {
+ // SendHeaders works on shared headers
+ lock (response.headers_lock)
+ {
+ if (response.HeadersSent)
+ return null;
+ MemoryStream ms = _memoryStreamFactory.CreateNew();
+ response.SendHeaders(closing, ms);
+ return ms;
+ }
+ }
+
+ public override void Flush()
+ {
+ }
+
+ static byte[] crlf = new byte[] { 13, 10 };
+ byte[] GetChunkSizeBytes(int size, bool final)
+ {
+ string str = String.Format("{0:x}\r\n{1}", size, final ? "\r\n" : "");
+ return _textEncoding.GetASCIIEncoding().GetBytes(str);
+ }
+
+ internal void InternalWrite(byte[] buffer, int offset, int count)
+ {
+ if (ignore_errors)
+ {
+ try
+ {
+ stream.Write(buffer, offset, count);
+ }
+ catch { }
+ }
+ else
+ {
+ stream.Write(buffer, offset, count);
+ }
+ }
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+
+ byte[] bytes = null;
+ MemoryStream ms = GetHeaders(false);
+ bool chunked = response.SendChunked;
+ if (ms != null)
+ {
+ long start = ms.Position; // After the possible preamble for the encoding
+ ms.Position = ms.Length;
+ if (chunked)
+ {
+ bytes = GetChunkSizeBytes(count, false);
+ ms.Write(bytes, 0, bytes.Length);
+ }
+
+ int new_count = Math.Min(count, 16384 - (int)ms.Position + (int)start);
+ ms.Write(buffer, offset, new_count);
+ count -= new_count;
+ offset += new_count;
+ byte[] msBuffer;
+ _memoryStreamFactory.TryGetBuffer(ms, out msBuffer);
+ InternalWrite(msBuffer, (int)start, (int)(ms.Length - start));
+ ms.SetLength(0);
+ ms.Capacity = 0; // 'dispose' the buffer in ms.
+ }
+ else if (chunked)
+ {
+ bytes = GetChunkSizeBytes(count, false);
+ InternalWrite(bytes, 0, bytes.Length);
+ }
+
+ if (count > 0)
+ InternalWrite(buffer, offset, count);
+ if (chunked)
+ InternalWrite(crlf, 0, 2);
+ }
+
+ public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ if (disposed)
+ throw new ObjectDisposedException(GetType().ToString());
+
+ byte[] bytes = null;
+ MemoryStream ms = GetHeaders(false);
+ bool chunked = response.SendChunked;
+ if (ms != null)
+ {
+ long start = ms.Position;
+ ms.Position = ms.Length;
+ if (chunked)
+ {
+ bytes = GetChunkSizeBytes(count, false);
+ ms.Write(bytes, 0, bytes.Length);
+ }
+ ms.Write(buffer, offset, count);
+ byte[] msBuffer;
+ _memoryStreamFactory.TryGetBuffer(ms, out msBuffer);
+ buffer = msBuffer;
+ offset = (int)start;
+ count = (int)(ms.Position - start);
+ }
+ else if (chunked)
+ {
+ bytes = GetChunkSizeBytes(count, false);
+ InternalWrite(bytes, 0, bytes.Length);
+ }
+
+ try
+ {
+ if (count > 0)
+ {
+ await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
+ }
+
+ if (response.SendChunked)
+ stream.Write(crlf, 0, 2);
+ }
+ catch
+ {
+ if (!ignore_errors)
+ {
+ throw;
+ }
+ }
+ }
+
+ //public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count,
+ // AsyncCallback cback, object state)
+ //{
+ // if (disposed)
+ // throw new ObjectDisposedException(GetType().ToString());
+
+ // byte[] bytes = null;
+ // MemoryStream ms = GetHeaders(false);
+ // bool chunked = response.SendChunked;
+ // if (ms != null)
+ // {
+ // long start = ms.Position;
+ // ms.Position = ms.Length;
+ // if (chunked)
+ // {
+ // bytes = GetChunkSizeBytes(count, false);
+ // ms.Write(bytes, 0, bytes.Length);
+ // }
+ // ms.Write(buffer, offset, count);
+ // buffer = ms.ToArray();
+ // offset = (int)start;
+ // count = (int)(ms.Position - start);
+ // }
+ // else if (chunked)
+ // {
+ // bytes = GetChunkSizeBytes(count, false);
+ // InternalWrite(bytes, 0, bytes.Length);
+ // }
+
+ // return stream.BeginWrite(buffer, offset, count, cback, state);
+ //}
+
+ //public override void EndWrite(IAsyncResult ares)
+ //{
+ // if (disposed)
+ // throw new ObjectDisposedException(GetType().ToString());
+
+ // if (ignore_errors)
+ // {
+ // try
+ // {
+ // stream.EndWrite(ares);
+ // if (response.SendChunked)
+ // stream.Write(crlf, 0, 2);
+ // }
+ // catch { }
+ // }
+ // else {
+ // stream.EndWrite(ares);
+ // if (response.SendChunked)
+ // stream.Write(crlf, 0, 2);
+ // }
+ //}
+
+ public override int Read([In, Out] byte[] buffer, int offset, int count)
+ {
+ throw new NotSupportedException();
+ }
+
+ //public override IAsyncResult BeginRead(byte[] buffer, int offset, int count,
+ // AsyncCallback cback, object state)
+ //{
+ // throw new NotSupportedException();
+ //}
+
+ //public override int EndRead(IAsyncResult ares)
+ //{
+ // throw new NotSupportedException();
+ //}
+
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ throw new NotSupportedException();
+ }
+
+ public override void SetLength(long value)
+ {
+ throw new NotSupportedException();
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/WebHeaderCollection.cs b/SocketHttpListener.Portable/Net/WebHeaderCollection.cs
new file mode 100644
index 0000000000..d20f99b9b8
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/WebHeaderCollection.cs
@@ -0,0 +1,391 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Net;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Text;
+using MediaBrowser.Model.Services;
+
+namespace SocketHttpListener.Net
+{
+ [ComVisible(true)]
+ public class WebHeaderCollection : QueryParamCollection
+ {
+ [Flags]
+ internal enum HeaderInfo
+ {
+ Request = 1,
+ Response = 1 << 1,
+ MultiValue = 1 << 10
+ }
+
+ static readonly bool[] allowed_chars = {
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, true, false, true, true, true, true, false, false, false, true,
+ true, false, true, true, false, true, true, true, true, true, true, true, true, true, true, false,
+ false, false, false, false, false, false, true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+ false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+ false, true, false
+ };
+
+ static readonly Dictionary<string, HeaderInfo> headers;
+ HeaderInfo? headerRestriction;
+ HeaderInfo? headerConsistency;
+
+ static WebHeaderCollection()
+ {
+ headers = new Dictionary<string, HeaderInfo>(StringComparer.OrdinalIgnoreCase) {
+ { "Allow", HeaderInfo.MultiValue },
+ { "Accept", HeaderInfo.Request | HeaderInfo.MultiValue },
+ { "Accept-Charset", HeaderInfo.MultiValue },
+ { "Accept-Encoding", HeaderInfo.MultiValue },
+ { "Accept-Language", HeaderInfo.MultiValue },
+ { "Accept-Ranges", HeaderInfo.MultiValue },
+ { "Age", HeaderInfo.Response },
+ { "Authorization", HeaderInfo.MultiValue },
+ { "Cache-Control", HeaderInfo.MultiValue },
+ { "Cookie", HeaderInfo.MultiValue },
+ { "Connection", HeaderInfo.Request | HeaderInfo.MultiValue },
+ { "Content-Encoding", HeaderInfo.MultiValue },
+ { "Content-Length", HeaderInfo.Request | HeaderInfo.Response },
+ { "Content-Type", HeaderInfo.Request },
+ { "Content-Language", HeaderInfo.MultiValue },
+ { "Date", HeaderInfo.Request },
+ { "Expect", HeaderInfo.Request | HeaderInfo.MultiValue},
+ { "Host", HeaderInfo.Request },
+ { "If-Match", HeaderInfo.MultiValue },
+ { "If-Modified-Since", HeaderInfo.Request },
+ { "If-None-Match", HeaderInfo.MultiValue },
+ { "Keep-Alive", HeaderInfo.Response },
+ { "Pragma", HeaderInfo.MultiValue },
+ { "Proxy-Authenticate", HeaderInfo.MultiValue },
+ { "Proxy-Authorization", HeaderInfo.MultiValue },
+ { "Proxy-Connection", HeaderInfo.Request | HeaderInfo.MultiValue },
+ { "Range", HeaderInfo.Request | HeaderInfo.MultiValue },
+ { "Referer", HeaderInfo.Request },
+ { "Set-Cookie", HeaderInfo.MultiValue },
+ { "Set-Cookie2", HeaderInfo.MultiValue },
+ { "Server", HeaderInfo.Response },
+ { "TE", HeaderInfo.MultiValue },
+ { "Trailer", HeaderInfo.MultiValue },
+ { "Transfer-Encoding", HeaderInfo.Request | HeaderInfo.Response | HeaderInfo.MultiValue },
+ { "Translate", HeaderInfo.Request | HeaderInfo.Response },
+ { "Upgrade", HeaderInfo.MultiValue },
+ { "User-Agent", HeaderInfo.Request },
+ { "Vary", HeaderInfo.MultiValue },
+ { "Via", HeaderInfo.MultiValue },
+ { "Warning", HeaderInfo.MultiValue },
+ { "WWW-Authenticate", HeaderInfo.Response | HeaderInfo. MultiValue },
+ { "SecWebSocketAccept", HeaderInfo.Response },
+ { "SecWebSocketExtensions", HeaderInfo.Request | HeaderInfo.Response | HeaderInfo. MultiValue },
+ { "SecWebSocketKey", HeaderInfo.Request },
+ { "Sec-WebSocket-Protocol", HeaderInfo.Request | HeaderInfo.Response | HeaderInfo. MultiValue },
+ { "SecWebSocketVersion", HeaderInfo.Response | HeaderInfo. MultiValue }
+ };
+ }
+
+ // Methods
+
+ public void Add(string header)
+ {
+ if (header == null)
+ throw new ArgumentNullException("header");
+ int pos = header.IndexOf(':');
+ if (pos == -1)
+ throw new ArgumentException("no colon found", "header");
+
+ this.Add(header.Substring(0, pos), header.Substring(pos + 1));
+ }
+
+ public override void Add(string name, string value)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ ThrowIfRestricted(name);
+ this.AddWithoutValidate(name, value);
+ }
+
+ protected void AddWithoutValidate(string headerName, string headerValue)
+ {
+ if (!IsHeaderName(headerName))
+ throw new ArgumentException("invalid header name: " + headerName, "headerName");
+ if (headerValue == null)
+ headerValue = String.Empty;
+ else
+ headerValue = headerValue.Trim();
+ if (!IsHeaderValue(headerValue))
+ throw new ArgumentException("invalid header value: " + headerValue, "headerValue");
+
+ AddValue(headerName, headerValue);
+ }
+
+ internal void AddValue(string headerName, string headerValue)
+ {
+ base.Add(headerName, headerValue);
+ }
+
+ internal string[] GetValues_internal(string header, bool split)
+ {
+ if (header == null)
+ throw new ArgumentNullException("header");
+
+ string[] values = base.GetValues(header);
+ if (values == null || values.Length == 0)
+ return null;
+
+ if (split && IsMultiValue(header))
+ {
+ List<string> separated = null;
+ foreach (var value in values)
+ {
+ if (value.IndexOf(',') < 0)
+ {
+ if (separated != null)
+ separated.Add(value);
+
+ continue;
+ }
+
+ if (separated == null)
+ {
+ separated = new List<string>(values.Length + 1);
+ foreach (var v in values)
+ {
+ if (v == value)
+ break;
+
+ separated.Add(v);
+ }
+ }
+
+ var slices = value.Split(',');
+ var slices_length = slices.Length;
+ if (value[value.Length - 1] == ',')
+ --slices_length;
+
+ for (int i = 0; i < slices_length; ++i)
+ {
+ separated.Add(slices[i].Trim());
+ }
+ }
+
+ if (separated != null)
+ return separated.ToArray();
+ }
+
+ return values;
+ }
+
+ public override string[] GetValues(string header)
+ {
+ return GetValues_internal(header, true);
+ }
+
+ public override string[] GetValues(int index)
+ {
+ string[] values = base.GetValues(index);
+
+ if (values == null || values.Length == 0)
+ {
+ return null;
+ }
+
+ return values;
+ }
+
+ public static bool IsRestricted(string headerName)
+ {
+ return IsRestricted(headerName, false);
+ }
+
+ public static bool IsRestricted(string headerName, bool response)
+ {
+ if (headerName == null)
+ throw new ArgumentNullException("headerName");
+
+ if (headerName.Length == 0)
+ throw new ArgumentException("empty string", "headerName");
+
+ if (!IsHeaderName(headerName))
+ throw new ArgumentException("Invalid character in header");
+
+ HeaderInfo info;
+ if (!headers.TryGetValue(headerName, out info))
+ return false;
+
+ var flag = response ? HeaderInfo.Response : HeaderInfo.Request;
+ return (info & flag) != 0;
+ }
+
+ public override void Set(string name, string value)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (!IsHeaderName(name))
+ throw new ArgumentException("invalid header name");
+ if (value == null)
+ value = String.Empty;
+ else
+ value = value.Trim();
+ if (!IsHeaderValue(value))
+ throw new ArgumentException("invalid header value");
+
+ ThrowIfRestricted(name);
+ base.Set(name, value);
+ }
+
+ internal string ToStringMultiValue()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ int count = base.Count;
+ for (int i = 0; i < count; i++)
+ {
+ string key = GetKey(i);
+ if (IsMultiValue(key))
+ {
+ foreach (string v in GetValues(i))
+ {
+ sb.Append(key)
+ .Append(": ")
+ .Append(v)
+ .Append("\r\n");
+ }
+ }
+ else
+ {
+ sb.Append(key)
+ .Append(": ")
+ .Append(Get(i))
+ .Append("\r\n");
+ }
+ }
+ return sb.Append("\r\n").ToString();
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ int count = base.Count;
+ for (int i = 0; i < count; i++)
+ sb.Append(GetKey(i))
+ .Append(": ")
+ .Append(Get(i))
+ .Append("\r\n");
+
+ return sb.Append("\r\n").ToString();
+ }
+
+
+ // Internal Methods
+
+ // With this we don't check for invalid characters in header. See bug #55994.
+ internal void SetInternal(string header)
+ {
+ int pos = header.IndexOf(':');
+ if (pos == -1)
+ throw new ArgumentException("no colon found", "header");
+
+ SetInternal(header.Substring(0, pos), header.Substring(pos + 1));
+ }
+
+ internal void SetInternal(string name, string value)
+ {
+ if (value == null)
+ value = String.Empty;
+ else
+ value = value.Trim();
+ if (!IsHeaderValue(value))
+ throw new ArgumentException("invalid header value");
+
+ if (IsMultiValue(name))
+ {
+ base.Add(name, value);
+ }
+ else
+ {
+ base.Remove(name);
+ base.Set(name, value);
+ }
+ }
+
+ // Private Methods
+
+ public override int Remove(string name)
+ {
+ ThrowIfRestricted(name);
+ return base.Remove(name);
+ }
+
+ protected void ThrowIfRestricted(string headerName)
+ {
+ if (!headerRestriction.HasValue)
+ return;
+
+ HeaderInfo info;
+ if (!headers.TryGetValue(headerName, out info))
+ return;
+
+ if ((info & headerRestriction.Value) != 0)
+ throw new ArgumentException("This header must be modified with the appropriate property.");
+ }
+
+ internal static bool IsMultiValue(string headerName)
+ {
+ if (headerName == null)
+ return false;
+
+ HeaderInfo info;
+ return headers.TryGetValue(headerName, out info) && (info & HeaderInfo.MultiValue) != 0;
+ }
+
+ internal static bool IsHeaderValue(string value)
+ {
+ // TEXT any 8 bit value except CTL's (0-31 and 127)
+ // but including \r\n space and \t
+ // after a newline at least one space or \t must follow
+ // certain header fields allow comments ()
+
+ int len = value.Length;
+ for (int i = 0; i < len; i++)
+ {
+ char c = value[i];
+ if (c == 127)
+ return false;
+ if (c < 0x20 && (c != '\r' && c != '\n' && c != '\t'))
+ return false;
+ if (c == '\n' && ++i < len)
+ {
+ c = value[i];
+ if (c != ' ' && c != '\t')
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ internal static bool IsHeaderName(string name)
+ {
+ if (name == null || name.Length == 0)
+ return false;
+
+ int len = name.Length;
+ for (int i = 0; i < len; i++)
+ {
+ char c = name[i];
+ if (c > 126 || !allowed_chars[c])
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/WebSockets/HttpListenerWebSocketContext.cs b/SocketHttpListener.Portable/Net/WebSockets/HttpListenerWebSocketContext.cs
new file mode 100644
index 0000000000..426e15ecde
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/WebSockets/HttpListenerWebSocketContext.cs
@@ -0,0 +1,347 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+using System.Net;
+using System.Security.Principal;
+using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Services;
+using SocketHttpListener.Primitives;
+
+namespace SocketHttpListener.Net.WebSockets
+{
+ /// <summary>
+ /// Provides the properties used to access the information in a WebSocket connection request
+ /// received by the <see cref="HttpListener"/>.
+ /// </summary>
+ /// <remarks>
+ /// </remarks>
+ public class HttpListenerWebSocketContext : WebSocketContext
+ {
+ #region Private Fields
+
+ private HttpListenerContext _context;
+ private WebSocket _websocket;
+
+ #endregion
+
+ #region Internal Constructors
+
+ internal HttpListenerWebSocketContext(
+ HttpListenerContext context, string protocol, ICryptoProvider cryptoProvider, IMemoryStreamFactory memoryStreamFactory)
+ {
+ _context = context;
+ _websocket = new WebSocket(this, protocol, cryptoProvider, memoryStreamFactory);
+ }
+
+ #endregion
+
+ #region Internal Properties
+
+ internal Stream Stream
+ {
+ get
+ {
+ return _context.Connection.Stream;
+ }
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the HTTP cookies included in the request.
+ /// </summary>
+ /// <value>
+ /// A <see cref="System.Net.CookieCollection"/> that contains the cookies.
+ /// </value>
+ public override CookieCollection CookieCollection
+ {
+ get
+ {
+ return _context.Request.Cookies;
+ }
+ }
+
+ /// <summary>
+ /// Gets the HTTP headers included in the request.
+ /// </summary>
+ /// <value>
+ /// A <see cref="QueryParamCollection"/> that contains the headers.
+ /// </value>
+ public override QueryParamCollection Headers
+ {
+ get
+ {
+ return _context.Request.Headers;
+ }
+ }
+
+ /// <summary>
+ /// Gets the value of the Host header included in the request.
+ /// </summary>
+ /// <value>
+ /// A <see cref="string"/> that represents the value of the Host header.
+ /// </value>
+ public override string Host
+ {
+ get
+ {
+ return _context.Request.Headers["Host"];
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the client is authenticated.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if the client is authenticated; otherwise, <c>false</c>.
+ /// </value>
+ public override bool IsAuthenticated
+ {
+ get
+ {
+ return _context.Request.IsAuthenticated;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the client connected from the local computer.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if the client connected from the local computer; otherwise, <c>false</c>.
+ /// </value>
+ public override bool IsLocal
+ {
+ get
+ {
+ return _context.Request.IsLocal;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the WebSocket connection is secured.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if the connection is secured; otherwise, <c>false</c>.
+ /// </value>
+ public override bool IsSecureConnection
+ {
+ get
+ {
+ return _context.Connection.IsSecure;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the request is a WebSocket connection request.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if the request is a WebSocket connection request; otherwise, <c>false</c>.
+ /// </value>
+ public override bool IsWebSocketRequest
+ {
+ get
+ {
+ return _context.Request.IsWebSocketRequest;
+ }
+ }
+
+ /// <summary>
+ /// Gets the value of the Origin header included in the request.
+ /// </summary>
+ /// <value>
+ /// A <see cref="string"/> that represents the value of the Origin header.
+ /// </value>
+ public override string Origin
+ {
+ get
+ {
+ return _context.Request.Headers["Origin"];
+ }
+ }
+
+ /// <summary>
+ /// Gets the query string included in the request.
+ /// </summary>
+ /// <value>
+ /// A <see cref="QueryParamCollection"/> that contains the query string parameters.
+ /// </value>
+ public override QueryParamCollection QueryString
+ {
+ get
+ {
+ return _context.Request.QueryString;
+ }
+ }
+
+ /// <summary>
+ /// Gets the URI requested by the client.
+ /// </summary>
+ /// <value>
+ /// A <see cref="Uri"/> that represents the requested URI.
+ /// </value>
+ public override Uri RequestUri
+ {
+ get
+ {
+ return _context.Request.Url;
+ }
+ }
+
+ /// <summary>
+ /// Gets the value of the Sec-WebSocket-Key header included in the request.
+ /// </summary>
+ /// <remarks>
+ /// This property provides a part of the information used by the server to prove that it
+ /// received a valid WebSocket connection request.
+ /// </remarks>
+ /// <value>
+ /// A <see cref="string"/> that represents the value of the Sec-WebSocket-Key header.
+ /// </value>
+ public override string SecWebSocketKey
+ {
+ get
+ {
+ return _context.Request.Headers["Sec-WebSocket-Key"];
+ }
+ }
+
+ /// <summary>
+ /// Gets the values of the Sec-WebSocket-Protocol header included in the request.
+ /// </summary>
+ /// <remarks>
+ /// This property represents the subprotocols requested by the client.
+ /// </remarks>
+ /// <value>
+ /// An <see cref="T:System.Collections.Generic.IEnumerable{string}"/> instance that provides
+ /// an enumerator which supports the iteration over the values of the Sec-WebSocket-Protocol
+ /// header.
+ /// </value>
+ public override IEnumerable<string> SecWebSocketProtocols
+ {
+ get
+ {
+ var protocols = _context.Request.Headers["Sec-WebSocket-Protocol"];
+ if (protocols != null)
+ foreach (var protocol in protocols.Split(','))
+ yield return protocol.Trim();
+ }
+ }
+
+ /// <summary>
+ /// Gets the value of the Sec-WebSocket-Version header included in the request.
+ /// </summary>
+ /// <remarks>
+ /// This property represents the WebSocket protocol version.
+ /// </remarks>
+ /// <value>
+ /// A <see cref="string"/> that represents the value of the Sec-WebSocket-Version header.
+ /// </value>
+ public override string SecWebSocketVersion
+ {
+ get
+ {
+ return _context.Request.Headers["Sec-WebSocket-Version"];
+ }
+ }
+
+ /// <summary>
+ /// Gets the server endpoint as an IP address and a port number.
+ /// </summary>
+ /// <value>
+ /// </value>
+ public override IpEndPointInfo ServerEndPoint
+ {
+ get
+ {
+ return _context.Connection.LocalEndPoint;
+ }
+ }
+
+ /// <summary>
+ /// Gets the client information (identity, authentication, and security roles).
+ /// </summary>
+ /// <value>
+ /// A <see cref="IPrincipal"/> that represents the client information.
+ /// </value>
+ public override IPrincipal User
+ {
+ get
+ {
+ return _context.User;
+ }
+ }
+
+ /// <summary>
+ /// Gets the client endpoint as an IP address and a port number.
+ /// </summary>
+ /// <value>
+ /// </value>
+ public override IpEndPointInfo UserEndPoint
+ {
+ get
+ {
+ return _context.Connection.RemoteEndPoint;
+ }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="SocketHttpListener.WebSocket"/> instance used for two-way communication
+ /// between client and server.
+ /// </summary>
+ /// <value>
+ /// A <see cref="SocketHttpListener.WebSocket"/>.
+ /// </value>
+ public override WebSocket WebSocket
+ {
+ get
+ {
+ return _websocket;
+ }
+ }
+
+ #endregion
+
+ #region Internal Methods
+
+ internal void Close()
+ {
+ try
+ {
+ _context.Connection.Close(true);
+ }
+ catch
+ {
+ // catch errors sending the closing handshake
+ }
+ }
+
+ internal void Close(HttpStatusCode code)
+ {
+ _context.Response.Close(code);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Returns a <see cref="string"/> that represents the current
+ /// <see cref="HttpListenerWebSocketContext"/>.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="string"/> that represents the current
+ /// <see cref="HttpListenerWebSocketContext"/>.
+ /// </returns>
+ public override string ToString()
+ {
+ return _context.Request.ToString();
+ }
+
+ #endregion
+ }
+}
diff --git a/SocketHttpListener.Portable/Net/WebSockets/WebSocketContext.cs b/SocketHttpListener.Portable/Net/WebSockets/WebSocketContext.cs
new file mode 100644
index 0000000000..3ffa6e639a
--- /dev/null
+++ b/SocketHttpListener.Portable/Net/WebSockets/WebSocketContext.cs
@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Net;
+using System.Security.Principal;
+using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Services;
+
+namespace SocketHttpListener.Net.WebSockets
+{
+ /// <summary>
+ /// Exposes the properties used to access the information in a WebSocket connection request.
+ /// </summary>
+ /// <remarks>
+ /// The WebSocketContext class is an abstract class.
+ /// </remarks>
+ public abstract class WebSocketContext
+ {
+ #region Protected Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="WebSocketContext"/> class.
+ /// </summary>
+ protected WebSocketContext()
+ {
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the HTTP cookies included in the request.
+ /// </summary>
+ /// <value>
+ /// A <see cref="System.Net.CookieCollection"/> that contains the cookies.
+ /// </value>
+ public abstract CookieCollection CookieCollection { get; }
+
+ /// <summary>
+ /// Gets the HTTP headers included in the request.
+ /// </summary>
+ /// <value>
+ /// A <see cref="QueryParamCollection"/> that contains the headers.
+ /// </value>
+ public abstract QueryParamCollection Headers { get; }
+
+ /// <summary>
+ /// Gets the value of the Host header included in the request.
+ /// </summary>
+ /// <value>
+ /// A <see cref="string"/> that represents the value of the Host header.
+ /// </value>
+ public abstract string Host { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether the client is authenticated.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if the client is authenticated; otherwise, <c>false</c>.
+ /// </value>
+ public abstract bool IsAuthenticated { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether the client connected from the local computer.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if the client connected from the local computer; otherwise, <c>false</c>.
+ /// </value>
+ public abstract bool IsLocal { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether the WebSocket connection is secured.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if the connection is secured; otherwise, <c>false</c>.
+ /// </value>
+ public abstract bool IsSecureConnection { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether the request is a WebSocket connection request.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if the request is a WebSocket connection request; otherwise, <c>false</c>.
+ /// </value>
+ public abstract bool IsWebSocketRequest { get; }
+
+ /// <summary>
+ /// Gets the value of the Origin header included in the request.
+ /// </summary>
+ /// <value>
+ /// A <see cref="string"/> that represents the value of the Origin header.
+ /// </value>
+ public abstract string Origin { get; }
+
+ /// <summary>
+ /// Gets the query string included in the request.
+ /// </summary>
+ /// <value>
+ /// A <see cref="QueryParamCollection"/> that contains the query string parameters.
+ /// </value>
+ public abstract QueryParamCollection QueryString { get; }
+
+ /// <summary>
+ /// Gets the URI requested by the client.
+ /// </summary>
+ /// <value>
+ /// A <see cref="Uri"/> that represents the requested URI.
+ /// </value>
+ public abstract Uri RequestUri { get; }
+
+ /// <summary>
+ /// Gets the value of the Sec-WebSocket-Key header included in the request.
+ /// </summary>
+ /// <remarks>
+ /// This property provides a part of the information used by the server to prove that it
+ /// received a valid WebSocket connection request.
+ /// </remarks>
+ /// <value>
+ /// A <see cref="string"/> that represents the value of the Sec-WebSocket-Key header.
+ /// </value>
+ public abstract string SecWebSocketKey { get; }
+
+ /// <summary>
+ /// Gets the values of the Sec-WebSocket-Protocol header included in the request.
+ /// </summary>
+ /// <remarks>
+ /// This property represents the subprotocols requested by the client.
+ /// </remarks>
+ /// <value>
+ /// An <see cref="T:System.Collections.Generic.IEnumerable{string}"/> instance that provides
+ /// an enumerator which supports the iteration over the values of the Sec-WebSocket-Protocol
+ /// header.
+ /// </value>
+ public abstract IEnumerable<string> SecWebSocketProtocols { get; }
+
+ /// <summary>
+ /// Gets the value of the Sec-WebSocket-Version header included in the request.
+ /// </summary>
+ /// <remarks>
+ /// This property represents the WebSocket protocol version.
+ /// </remarks>
+ /// <value>
+ /// A <see cref="string"/> that represents the value of the Sec-WebSocket-Version header.
+ /// </value>
+ public abstract string SecWebSocketVersion { get; }
+
+ /// <summary>
+ /// Gets the server endpoint as an IP address and a port number.
+ /// </summary>
+ /// <value>
+ /// A <see cref="System.Net.IPEndPoint"/> that represents the server endpoint.
+ /// </value>
+ public abstract IpEndPointInfo ServerEndPoint { get; }
+
+ /// <summary>
+ /// Gets the client information (identity, authentication, and security roles).
+ /// </summary>
+ /// <value>
+ /// A <see cref="IPrincipal"/> that represents the client information.
+ /// </value>
+ public abstract IPrincipal User { get; }
+
+ /// <summary>
+ /// Gets the client endpoint as an IP address and a port number.
+ /// </summary>
+ /// <value>
+ /// A <see cref="System.Net.IPEndPoint"/> that represents the client endpoint.
+ /// </value>
+ public abstract IpEndPointInfo UserEndPoint { get; }
+
+ /// <summary>
+ /// Gets the <see cref="SocketHttpListener.WebSocket"/> instance used for two-way communication
+ /// between client and server.
+ /// </summary>
+ /// <value>
+ /// A <see cref="SocketHttpListener.WebSocket"/>.
+ /// </value>
+ public abstract WebSocket WebSocket { get; }
+
+ #endregion
+ }
+}
diff --git a/SocketHttpListener.Portable/Opcode.cs b/SocketHttpListener.Portable/Opcode.cs
new file mode 100644
index 0000000000..62b7d8585c
--- /dev/null
+++ b/SocketHttpListener.Portable/Opcode.cs
@@ -0,0 +1,43 @@
+namespace SocketHttpListener
+{
+ /// <summary>
+ /// Contains the values of the opcode that indicates the type of a WebSocket frame.
+ /// </summary>
+ /// <remarks>
+ /// The values of the opcode are defined in
+ /// <see href="http://tools.ietf.org/html/rfc6455#section-5.2">Section 5.2</see> of RFC 6455.
+ /// </remarks>
+ public enum Opcode : byte
+ {
+ /// <summary>
+ /// Equivalent to numeric value 0.
+ /// Indicates a continuation frame.
+ /// </summary>
+ Cont = 0x0,
+ /// <summary>
+ /// Equivalent to numeric value 1.
+ /// Indicates a text frame.
+ /// </summary>
+ Text = 0x1,
+ /// <summary>
+ /// Equivalent to numeric value 2.
+ /// Indicates a binary frame.
+ /// </summary>
+ Binary = 0x2,
+ /// <summary>
+ /// Equivalent to numeric value 8.
+ /// Indicates a connection close frame.
+ /// </summary>
+ Close = 0x8,
+ /// <summary>
+ /// Equivalent to numeric value 9.
+ /// Indicates a ping frame.
+ /// </summary>
+ Ping = 0x9,
+ /// <summary>
+ /// Equivalent to numeric value 10.
+ /// Indicates a pong frame.
+ /// </summary>
+ Pong = 0xa
+ }
+}
diff --git a/SocketHttpListener.Portable/PayloadData.cs b/SocketHttpListener.Portable/PayloadData.cs
new file mode 100644
index 0000000000..a6318da2b8
--- /dev/null
+++ b/SocketHttpListener.Portable/PayloadData.cs
@@ -0,0 +1,149 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SocketHttpListener
+{
+ internal class PayloadData : IEnumerable<byte>
+ {
+ #region Private Fields
+
+ private byte [] _applicationData;
+ private byte [] _extensionData;
+ private bool _masked;
+
+ #endregion
+
+ #region Public Const Fields
+
+ public const ulong MaxLength = long.MaxValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ public PayloadData ()
+ : this (new byte [0], new byte [0], false)
+ {
+ }
+
+ public PayloadData (byte [] applicationData)
+ : this (new byte [0], applicationData, false)
+ {
+ }
+
+ public PayloadData (string applicationData)
+ : this (new byte [0], Encoding.UTF8.GetBytes (applicationData), false)
+ {
+ }
+
+ public PayloadData (byte [] applicationData, bool masked)
+ : this (new byte [0], applicationData, masked)
+ {
+ }
+
+ public PayloadData (byte [] extensionData, byte [] applicationData, bool masked)
+ {
+ _extensionData = extensionData;
+ _applicationData = applicationData;
+ _masked = masked;
+ }
+
+ #endregion
+
+ #region Internal Properties
+
+ internal bool ContainsReservedCloseStatusCode {
+ get {
+ return _applicationData.Length > 1 &&
+ _applicationData.SubArray (0, 2).ToUInt16 (ByteOrder.Big).IsReserved ();
+ }
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ public byte [] ApplicationData {
+ get {
+ return _applicationData;
+ }
+ }
+
+ public byte [] ExtensionData {
+ get {
+ return _extensionData;
+ }
+ }
+
+ public bool IsMasked {
+ get {
+ return _masked;
+ }
+ }
+
+ public ulong Length {
+ get {
+ return (ulong) (_extensionData.Length + _applicationData.Length);
+ }
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private static void mask (byte [] src, byte [] key)
+ {
+ for (long i = 0; i < src.Length; i++)
+ src [i] = (byte) (src [i] ^ key [i % 4]);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public IEnumerator<byte> GetEnumerator ()
+ {
+ foreach (byte b in _extensionData)
+ yield return b;
+
+ foreach (byte b in _applicationData)
+ yield return b;
+ }
+
+ public void Mask (byte [] maskingKey)
+ {
+ if (_extensionData.Length > 0)
+ mask (_extensionData, maskingKey);
+
+ if (_applicationData.Length > 0)
+ mask (_applicationData, maskingKey);
+
+ _masked = !_masked;
+ }
+
+ public byte [] ToByteArray ()
+ {
+ return _extensionData.Length > 0
+ ? new List<byte> (this).ToArray ()
+ : _applicationData;
+ }
+
+ public override string ToString ()
+ {
+ return BitConverter.ToString (ToByteArray ());
+ }
+
+ #endregion
+
+ #region Explicitly Implemented Interface Members
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return GetEnumerator ();
+ }
+
+ #endregion
+ }
+}
diff --git a/SocketHttpListener.Portable/Primitives/HttpListenerException.cs b/SocketHttpListener.Portable/Primitives/HttpListenerException.cs
new file mode 100644
index 0000000000..7b383fd230
--- /dev/null
+++ b/SocketHttpListener.Portable/Primitives/HttpListenerException.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SocketHttpListener.Primitives
+{
+ public class HttpListenerException : Exception
+ {
+ public HttpListenerException(int statusCode, string message)
+ : base(message)
+ {
+
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Primitives/ICertificate.cs b/SocketHttpListener.Portable/Primitives/ICertificate.cs
new file mode 100644
index 0000000000..1289da13d7
--- /dev/null
+++ b/SocketHttpListener.Portable/Primitives/ICertificate.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SocketHttpListener.Primitives
+{
+ public interface ICertificate
+ {
+ }
+}
diff --git a/SocketHttpListener.Portable/Primitives/IStreamFactory.cs b/SocketHttpListener.Portable/Primitives/IStreamFactory.cs
new file mode 100644
index 0000000000..f189b95b47
--- /dev/null
+++ b/SocketHttpListener.Portable/Primitives/IStreamFactory.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Net;
+
+namespace SocketHttpListener.Primitives
+{
+ public interface IStreamFactory
+ {
+ Stream CreateNetworkStream(ISocket socket, bool ownsSocket);
+ Stream CreateSslStream(Stream innerStream, bool leaveInnerStreamOpen);
+
+ Task AuthenticateSslStreamAsServer(Stream stream, ICertificate certificate);
+ }
+}
diff --git a/SocketHttpListener.Portable/Primitives/ITextEncoding.cs b/SocketHttpListener.Portable/Primitives/ITextEncoding.cs
new file mode 100644
index 0000000000..b10145687b
--- /dev/null
+++ b/SocketHttpListener.Portable/Primitives/ITextEncoding.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Text;
+
+namespace SocketHttpListener.Primitives
+{
+ public static class TextEncodingExtensions
+ {
+ public static Encoding GetDefaultEncoding(this ITextEncoding encoding)
+ {
+ return Encoding.UTF8;
+ }
+ }
+}
diff --git a/SocketHttpListener.Portable/Properties/AssemblyInfo.cs b/SocketHttpListener.Portable/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..8704264603
--- /dev/null
+++ b/SocketHttpListener.Portable/Properties/AssemblyInfo.cs
@@ -0,0 +1,30 @@
+using System.Resources;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("SocketHttpListener.Portable")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SocketHttpListener.Portable")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: NeutralResourcesLanguage("en")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/SocketHttpListener.Portable/Rsv.cs b/SocketHttpListener.Portable/Rsv.cs
new file mode 100644
index 0000000000..668059b8a3
--- /dev/null
+++ b/SocketHttpListener.Portable/Rsv.cs
@@ -0,0 +1,8 @@
+namespace SocketHttpListener
+{
+ internal enum Rsv : byte
+ {
+ Off = 0x0,
+ On = 0x1
+ }
+}
diff --git a/SocketHttpListener.Portable/SocketHttpListener.Portable.csproj b/SocketHttpListener.Portable/SocketHttpListener.Portable.csproj
new file mode 100644
index 0000000000..f7b3a643cc
--- /dev/null
+++ b/SocketHttpListener.Portable/SocketHttpListener.Portable.csproj
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{4F26D5D8-A7B0-42B3-BA42-7CB7D245934E}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>SocketHttpListener.Portable</RootNamespace>
+ <AssemblyName>SocketHttpListener.Portable</AssemblyName>
+ <DefaultLanguage>en-US</DefaultLanguage>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="ByteOrder.cs" />
+ <Compile Include="CloseEventArgs.cs" />
+ <Compile Include="CloseStatusCode.cs" />
+ <Compile Include="CompressionMethod.cs" />
+ <Compile Include="ErrorEventArgs.cs" />
+ <Compile Include="Ext.cs" />
+ <Compile Include="Fin.cs" />
+ <Compile Include="HttpBase.cs" />
+ <Compile Include="HttpResponse.cs" />
+ <Compile Include="Mask.cs" />
+ <Compile Include="MessageEventArgs.cs" />
+ <Compile Include="Net\AuthenticationSchemeSelector.cs" />
+ <Compile Include="Net\ChunkedInputStream.cs" />
+ <Compile Include="Net\ChunkStream.cs" />
+ <Compile Include="Net\CookieHelper.cs" />
+ <Compile Include="Net\EndPointListener.cs" />
+ <Compile Include="Net\EndPointManager.cs" />
+ <Compile Include="Net\HttpConnection.cs" />
+ <Compile Include="Net\HttpListener.cs" />
+ <Compile Include="Net\HttpListenerBasicIdentity.cs" />
+ <Compile Include="Net\HttpListenerContext.cs" />
+ <Compile Include="Net\HttpListenerPrefixCollection.cs" />
+ <Compile Include="Net\HttpListenerRequest.cs" />
+ <Compile Include="Net\HttpListenerResponse.cs" />
+ <Compile Include="Net\HttpStatusCode.cs" />
+ <Compile Include="Net\HttpStreamAsyncResult.cs" />
+ <Compile Include="Net\HttpVersion.cs" />
+ <Compile Include="Net\ListenerPrefix.cs" />
+ <Compile Include="Net\RequestStream.cs" />
+ <Compile Include="Net\ResponseStream.cs" />
+ <Compile Include="Net\WebHeaderCollection.cs" />
+ <Compile Include="Net\WebSockets\HttpListenerWebSocketContext.cs" />
+ <Compile Include="Net\WebSockets\WebSocketContext.cs" />
+ <Compile Include="Opcode.cs" />
+ <Compile Include="PayloadData.cs" />
+ <Compile Include="Primitives\HttpListenerException.cs" />
+ <Compile Include="Primitives\ICertificate.cs" />
+ <Compile Include="Primitives\IStreamFactory.cs" />
+ <Compile Include="Primitives\ITextEncoding.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Rsv.cs" />
+ <Compile Include="WebSocket.cs" />
+ <Compile Include="WebSocketException.cs" />
+ <Compile Include="WebSocketFrame.cs" />
+ <Compile Include="WebSocketState.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
+ <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
+ <Name>MediaBrowser.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
+ <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
+ <Name>MediaBrowser.Model</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
+ <PropertyGroup>
+ <PostBuildEvent>if $(ConfigurationName) == Release (
+xcopy "$(TargetPath)" "$(SolutionDir)\Nuget\dlls\" /y /d /r /i
+)</PostBuildEvent>
+ </PropertyGroup>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/SocketHttpListener.Portable/SocketHttpListener.Portable.nuget.targets b/SocketHttpListener.Portable/SocketHttpListener.Portable.nuget.targets
new file mode 100644
index 0000000000..e69ce0e64f
--- /dev/null
+++ b/SocketHttpListener.Portable/SocketHttpListener.Portable.nuget.targets
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Target Name="EmitMSBuildWarning" BeforeTargets="Build">
+ <Warning Text="Packages containing MSBuild targets and props files cannot be fully installed in projects targeting multiple frameworks. The MSBuild targets and props files have been ignored." />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/SocketHttpListener.Portable/WebSocket.cs b/SocketHttpListener.Portable/WebSocket.cs
new file mode 100644
index 0000000000..889880387e
--- /dev/null
+++ b/SocketHttpListener.Portable/WebSocket.cs
@@ -0,0 +1,898 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading;
+using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.IO;
+using SocketHttpListener.Net.WebSockets;
+using SocketHttpListener.Primitives;
+using HttpStatusCode = SocketHttpListener.Net.HttpStatusCode;
+
+namespace SocketHttpListener
+{
+ /// <summary>
+ /// Implements the WebSocket interface.
+ /// </summary>
+ /// <remarks>
+ /// The WebSocket class provides a set of methods and properties for two-way communication using
+ /// the WebSocket protocol (<see href="http://tools.ietf.org/html/rfc6455">RFC 6455</see>).
+ /// </remarks>
+ public class WebSocket : IDisposable
+ {
+ #region Private Fields
+
+ private string _base64Key;
+ private Action _closeContext;
+ private CompressionMethod _compression;
+ private WebSocketContext _context;
+ private CookieCollection _cookies;
+ private string _extensions;
+ private AutoResetEvent _exitReceiving;
+ private object _forConn;
+ private object _forEvent;
+ private object _forMessageEventQueue;
+ private object _forSend;
+ private const string _guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+ private Func<WebSocketContext, string>
+ _handshakeRequestChecker;
+ private Queue<MessageEventArgs> _messageEventQueue;
+ private uint _nonceCount;
+ private string _origin;
+ private bool _preAuth;
+ private string _protocol;
+ private string[] _protocols;
+ private Uri _proxyUri;
+ private volatile WebSocketState _readyState;
+ private AutoResetEvent _receivePong;
+ private bool _secure;
+ private Stream _stream;
+ private Uri _uri;
+ private const string _version = "13";
+ private readonly IMemoryStreamFactory _memoryStreamFactory;
+
+ private readonly ICryptoProvider _cryptoProvider;
+
+ #endregion
+
+ #region Internal Fields
+
+ internal const int FragmentLength = 1016; // Max value is int.MaxValue - 14.
+
+ #endregion
+
+ #region Internal Constructors
+
+ // As server
+ internal WebSocket(HttpListenerWebSocketContext context, string protocol, ICryptoProvider cryptoProvider, IMemoryStreamFactory memoryStreamFactory)
+ {
+ _context = context;
+ _protocol = protocol;
+ _cryptoProvider = cryptoProvider;
+ _memoryStreamFactory = memoryStreamFactory;
+
+ _closeContext = context.Close;
+ _secure = context.IsSecureConnection;
+ _stream = context.Stream;
+
+ init();
+ }
+
+ #endregion
+
+ // As server
+ internal Func<WebSocketContext, string> CustomHandshakeRequestChecker
+ {
+ get
+ {
+ return _handshakeRequestChecker ?? (context => null);
+ }
+
+ set
+ {
+ _handshakeRequestChecker = value;
+ }
+ }
+
+ internal bool IsConnected
+ {
+ get
+ {
+ return _readyState == WebSocketState.Open || _readyState == WebSocketState.Closing;
+ }
+ }
+
+ /// <summary>
+ /// Gets the state of the WebSocket connection.
+ /// </summary>
+ /// <value>
+ /// One of the <see cref="WebSocketState"/> enum values, indicates the state of the WebSocket
+ /// connection. The default value is <see cref="WebSocketState.Connecting"/>.
+ /// </value>
+ public WebSocketState ReadyState
+ {
+ get
+ {
+ return _readyState;
+ }
+ }
+
+ #region Public Events
+
+ /// <summary>
+ /// Occurs when the WebSocket connection has been closed.
+ /// </summary>
+ public event EventHandler<CloseEventArgs> OnClose;
+
+ /// <summary>
+ /// Occurs when the <see cref="WebSocket"/> gets an error.
+ /// </summary>
+ public event EventHandler<ErrorEventArgs> OnError;
+
+ /// <summary>
+ /// Occurs when the <see cref="WebSocket"/> receives a message.
+ /// </summary>
+ public event EventHandler<MessageEventArgs> OnMessage;
+
+ /// <summary>
+ /// Occurs when the WebSocket connection has been established.
+ /// </summary>
+ public event EventHandler OnOpen;
+
+ #endregion
+
+ #region Private Methods
+
+ // As server
+ private bool acceptHandshake()
+ {
+ var msg = checkIfValidHandshakeRequest(_context);
+ if (msg != null)
+ {
+ error("An error has occurred while connecting: " + msg);
+ Close(HttpStatusCode.BadRequest);
+
+ return false;
+ }
+
+ if (_protocol != null &&
+ !_context.SecWebSocketProtocols.Contains(protocol => protocol == _protocol))
+ _protocol = null;
+
+ ////var extensions = _context.Headers["Sec-WebSocket-Extensions"];
+ ////if (extensions != null && extensions.Length > 0)
+ //// processSecWebSocketExtensionsHeader(extensions);
+
+ return sendHttpResponse(createHandshakeResponse());
+ }
+
+ // As server
+ private string checkIfValidHandshakeRequest(WebSocketContext context)
+ {
+ var headers = context.Headers;
+ return context.RequestUri == null
+ ? "Invalid request url."
+ : !context.IsWebSocketRequest
+ ? "Not WebSocket connection request."
+ : !validateSecWebSocketKeyHeader(headers["Sec-WebSocket-Key"])
+ ? "Invalid Sec-WebSocket-Key header."
+ : !validateSecWebSocketVersionClientHeader(headers["Sec-WebSocket-Version"])
+ ? "Invalid Sec-WebSocket-Version header."
+ : CustomHandshakeRequestChecker(context);
+ }
+
+ private void close(CloseStatusCode code, string reason, bool wait)
+ {
+ close(new PayloadData(((ushort)code).Append(reason)), !code.IsReserved(), wait);
+ }
+
+ private void close(PayloadData payload, bool send, bool wait)
+ {
+ lock (_forConn)
+ {
+ if (_readyState == WebSocketState.Closing || _readyState == WebSocketState.Closed)
+ {
+ return;
+ }
+
+ _readyState = WebSocketState.Closing;
+ }
+
+ var e = new CloseEventArgs(payload);
+ e.WasClean =
+ closeHandshake(
+ send ? WebSocketFrame.CreateCloseFrame(Mask.Unmask, payload).ToByteArray() : null,
+ wait ? 1000 : 0,
+ closeServerResources);
+
+ _readyState = WebSocketState.Closed;
+ try
+ {
+ OnClose.Emit(this, e);
+ }
+ catch (Exception ex)
+ {
+ error("An exception has occurred while OnClose.", ex);
+ }
+ }
+
+ private bool closeHandshake(byte[] frameAsBytes, int millisecondsTimeout, Action release)
+ {
+ var sent = frameAsBytes != null && writeBytes(frameAsBytes);
+ var received =
+ millisecondsTimeout == 0 ||
+ (sent && _exitReceiving != null && _exitReceiving.WaitOne(millisecondsTimeout));
+
+ release();
+ if (_receivePong != null)
+ {
+ _receivePong.Dispose();
+ _receivePong = null;
+ }
+
+ if (_exitReceiving != null)
+ {
+ _exitReceiving.Dispose();
+ _exitReceiving = null;
+ }
+
+ var result = sent && received;
+
+ return result;
+ }
+
+ // As server
+ private void closeServerResources()
+ {
+ if (_closeContext == null)
+ return;
+
+ _closeContext();
+ _closeContext = null;
+ _stream = null;
+ _context = null;
+ }
+
+ private bool concatenateFragmentsInto(Stream dest)
+ {
+ while (true)
+ {
+ var frame = WebSocketFrame.Read(_stream, true);
+ if (frame.IsFinal)
+ {
+ /* FINAL */
+
+ // CONT
+ if (frame.IsContinuation)
+ {
+ dest.WriteBytes(frame.PayloadData.ApplicationData);
+ break;
+ }
+
+ // PING
+ if (frame.IsPing)
+ {
+ processPingFrame(frame);
+ continue;
+ }
+
+ // PONG
+ if (frame.IsPong)
+ {
+ processPongFrame(frame);
+ continue;
+ }
+
+ // CLOSE
+ if (frame.IsClose)
+ return processCloseFrame(frame);
+ }
+ else
+ {
+ /* MORE */
+
+ // CONT
+ if (frame.IsContinuation)
+ {
+ dest.WriteBytes(frame.PayloadData.ApplicationData);
+ continue;
+ }
+ }
+
+ // ?
+ return processUnsupportedFrame(
+ frame,
+ CloseStatusCode.IncorrectData,
+ "An incorrect data has been received while receiving fragmented data.");
+ }
+
+ return true;
+ }
+
+ // As server
+ private HttpResponse createHandshakeCloseResponse(HttpStatusCode code)
+ {
+ var res = HttpResponse.CreateCloseResponse(code);
+ res.Headers["Sec-WebSocket-Version"] = _version;
+
+ return res;
+ }
+
+ // As server
+ private HttpResponse createHandshakeResponse()
+ {
+ var res = HttpResponse.CreateWebSocketResponse();
+
+ var headers = res.Headers;
+ headers["Sec-WebSocket-Accept"] = CreateResponseKey(_base64Key);
+
+ if (_protocol != null)
+ headers["Sec-WebSocket-Protocol"] = _protocol;
+
+ if (_extensions != null)
+ headers["Sec-WebSocket-Extensions"] = _extensions;
+
+ if (_cookies.Count > 0)
+ res.SetCookies(_cookies);
+
+ return res;
+ }
+
+ private MessageEventArgs dequeueFromMessageEventQueue()
+ {
+ lock (_forMessageEventQueue)
+ return _messageEventQueue.Count > 0
+ ? _messageEventQueue.Dequeue()
+ : null;
+ }
+
+ private void enqueueToMessageEventQueue(MessageEventArgs e)
+ {
+ lock (_forMessageEventQueue)
+ _messageEventQueue.Enqueue(e);
+ }
+
+ private void error(string message, Exception exception)
+ {
+ try
+ {
+ if (exception != null)
+ {
+ message += ". Exception.Message: " + exception.Message;
+ }
+ OnError.Emit(this, new ErrorEventArgs(message));
+ }
+ catch (Exception ex)
+ {
+ }
+ }
+
+ private void error(string message)
+ {
+ try
+ {
+ OnError.Emit(this, new ErrorEventArgs(message));
+ }
+ catch (Exception ex)
+ {
+ }
+ }
+
+ private void init()
+ {
+ _compression = CompressionMethod.None;
+ _cookies = new CookieCollection();
+ _forConn = new object();
+ _forEvent = new object();
+ _forSend = new object();
+ _messageEventQueue = new Queue<MessageEventArgs>();
+ _forMessageEventQueue = ((ICollection)_messageEventQueue).SyncRoot;
+ _readyState = WebSocketState.Connecting;
+ }
+
+ private void open()
+ {
+ try
+ {
+ startReceiving();
+
+ lock (_forEvent)
+ {
+ try
+ {
+ OnOpen.Emit(this, EventArgs.Empty);
+ }
+ catch (Exception ex)
+ {
+ processException(ex, "An exception has occurred while OnOpen.");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ processException(ex, "An exception has occurred while opening.");
+ }
+ }
+
+ private bool processCloseFrame(WebSocketFrame frame)
+ {
+ var payload = frame.PayloadData;
+ close(payload, !payload.ContainsReservedCloseStatusCode, false);
+
+ return false;
+ }
+
+ private bool processDataFrame(WebSocketFrame frame)
+ {
+ var e = frame.IsCompressed
+ ? new MessageEventArgs(
+ frame.Opcode, frame.PayloadData.ApplicationData.Decompress(_compression))
+ : new MessageEventArgs(frame.Opcode, frame.PayloadData);
+
+ enqueueToMessageEventQueue(e);
+ return true;
+ }
+
+ private void processException(Exception exception, string message)
+ {
+ var code = CloseStatusCode.Abnormal;
+ var reason = message;
+ if (exception is WebSocketException)
+ {
+ var wsex = (WebSocketException)exception;
+ code = wsex.Code;
+ reason = wsex.Message;
+ }
+
+ error(message ?? code.GetMessage(), exception);
+ if (_readyState == WebSocketState.Connecting)
+ Close(HttpStatusCode.BadRequest);
+ else
+ close(code, reason ?? code.GetMessage(), false);
+ }
+
+ private bool processFragmentedFrame(WebSocketFrame frame)
+ {
+ return frame.IsContinuation // Not first fragment
+ ? true
+ : processFragments(frame);
+ }
+
+ private bool processFragments(WebSocketFrame first)
+ {
+ using (var buff = _memoryStreamFactory.CreateNew())
+ {
+ buff.WriteBytes(first.PayloadData.ApplicationData);
+ if (!concatenateFragmentsInto(buff))
+ return false;
+
+ byte[] data;
+ if (_compression != CompressionMethod.None)
+ {
+ data = buff.DecompressToArray(_compression);
+ }
+ else
+ {
+ data = buff.ToArray();
+ }
+
+ enqueueToMessageEventQueue(new MessageEventArgs(first.Opcode, data));
+ return true;
+ }
+ }
+
+ private bool processPingFrame(WebSocketFrame frame)
+ {
+ var mask = Mask.Unmask;
+
+ return true;
+ }
+
+ private bool processPongFrame(WebSocketFrame frame)
+ {
+ _receivePong.Set();
+
+ return true;
+ }
+
+ private bool processUnsupportedFrame(WebSocketFrame frame, CloseStatusCode code, string reason)
+ {
+ processException(new WebSocketException(code, reason), null);
+
+ return false;
+ }
+
+ private bool processWebSocketFrame(WebSocketFrame frame)
+ {
+ return frame.IsCompressed && _compression == CompressionMethod.None
+ ? processUnsupportedFrame(
+ frame,
+ CloseStatusCode.IncorrectData,
+ "A compressed data has been received without available decompression method.")
+ : frame.IsFragmented
+ ? processFragmentedFrame(frame)
+ : frame.IsData
+ ? processDataFrame(frame)
+ : frame.IsPing
+ ? processPingFrame(frame)
+ : frame.IsPong
+ ? processPongFrame(frame)
+ : frame.IsClose
+ ? processCloseFrame(frame)
+ : processUnsupportedFrame(frame, CloseStatusCode.PolicyViolation, null);
+ }
+
+ private bool send(Opcode opcode, Stream stream)
+ {
+ lock (_forSend)
+ {
+ var src = stream;
+ var compressed = false;
+ var sent = false;
+ try
+ {
+ if (_compression != CompressionMethod.None)
+ {
+ stream = stream.Compress(_compression);
+ compressed = true;
+ }
+
+ sent = send(opcode, Mask.Unmask, stream, compressed);
+ if (!sent)
+ error("Sending a data has been interrupted.");
+ }
+ catch (Exception ex)
+ {
+ error("An exception has occurred while sending a data.", ex);
+ }
+ finally
+ {
+ if (compressed)
+ stream.Dispose();
+
+ src.Dispose();
+ }
+
+ return sent;
+ }
+ }
+
+ private bool send(Opcode opcode, Mask mask, Stream stream, bool compressed)
+ {
+ var len = stream.Length;
+
+ /* Not fragmented */
+
+ if (len == 0)
+ return send(Fin.Final, opcode, mask, new byte[0], compressed);
+
+ var quo = len / FragmentLength;
+ var rem = (int)(len % FragmentLength);
+
+ byte[] buff = null;
+ if (quo == 0)
+ {
+ buff = new byte[rem];
+ return stream.Read(buff, 0, rem) == rem &&
+ send(Fin.Final, opcode, mask, buff, compressed);
+ }
+
+ buff = new byte[FragmentLength];
+ if (quo == 1 && rem == 0)
+ return stream.Read(buff, 0, FragmentLength) == FragmentLength &&
+ send(Fin.Final, opcode, mask, buff, compressed);
+
+ /* Send fragmented */
+
+ // Begin
+ if (stream.Read(buff, 0, FragmentLength) != FragmentLength ||
+ !send(Fin.More, opcode, mask, buff, compressed))
+ return false;
+
+ var n = rem == 0 ? quo - 2 : quo - 1;
+ for (long i = 0; i < n; i++)
+ if (stream.Read(buff, 0, FragmentLength) != FragmentLength ||
+ !send(Fin.More, Opcode.Cont, mask, buff, compressed))
+ return false;
+
+ // End
+ if (rem == 0)
+ rem = FragmentLength;
+ else
+ buff = new byte[rem];
+
+ return stream.Read(buff, 0, rem) == rem &&
+ send(Fin.Final, Opcode.Cont, mask, buff, compressed);
+ }
+
+ private bool send(Fin fin, Opcode opcode, Mask mask, byte[] data, bool compressed)
+ {
+ lock (_forConn)
+ {
+ if (_readyState != WebSocketState.Open)
+ {
+ return false;
+ }
+
+ return writeBytes(
+ WebSocketFrame.CreateWebSocketFrame(fin, opcode, mask, data, compressed).ToByteArray());
+ }
+ }
+
+ private void sendAsync(Opcode opcode, Stream stream, Action<bool> completed)
+ {
+ Func<Opcode, Stream, bool> sender = send;
+ sender.BeginInvoke(
+ opcode,
+ stream,
+ ar =>
+ {
+ try
+ {
+ var sent = sender.EndInvoke(ar);
+ if (completed != null)
+ completed(sent);
+ }
+ catch (Exception ex)
+ {
+ error("An exception has occurred while callback.", ex);
+ }
+ },
+ null);
+ }
+
+ // As server
+ private bool sendHttpResponse(HttpResponse response)
+ {
+ return writeBytes(response.ToByteArray());
+ }
+
+ private void startReceiving()
+ {
+ if (_messageEventQueue.Count > 0)
+ _messageEventQueue.Clear();
+
+ _exitReceiving = new AutoResetEvent(false);
+ _receivePong = new AutoResetEvent(false);
+
+ Action receive = null;
+ receive = () => WebSocketFrame.ReadAsync(
+ _stream,
+ true,
+ frame =>
+ {
+ if (processWebSocketFrame(frame) && _readyState != WebSocketState.Closed)
+ {
+ receive();
+
+ if (!frame.IsData)
+ return;
+
+ lock (_forEvent)
+ {
+ try
+ {
+ var e = dequeueFromMessageEventQueue();
+ if (e != null && _readyState == WebSocketState.Open)
+ OnMessage.Emit(this, e);
+ }
+ catch (Exception ex)
+ {
+ processException(ex, "An exception has occurred while OnMessage.");
+ }
+ }
+ }
+ else if (_exitReceiving != null)
+ {
+ _exitReceiving.Set();
+ }
+ },
+ ex => processException(ex, "An exception has occurred while receiving a message."));
+
+ receive();
+ }
+
+ // As server
+ private bool validateSecWebSocketKeyHeader(string value)
+ {
+ if (value == null || value.Length == 0)
+ return false;
+
+ _base64Key = value;
+ return true;
+ }
+
+ // As server
+ private bool validateSecWebSocketVersionClientHeader(string value)
+ {
+ return true;
+ //return value != null && value == _version;
+ }
+
+ private bool writeBytes(byte[] data)
+ {
+ try
+ {
+ _stream.Write(data, 0, data.Length);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ }
+
+ #endregion
+
+ #region Internal Methods
+
+ // As server
+ internal void Close(HttpResponse response)
+ {
+ _readyState = WebSocketState.Closing;
+
+ sendHttpResponse(response);
+ closeServerResources();
+
+ _readyState = WebSocketState.Closed;
+ }
+
+ // As server
+ internal void Close(HttpStatusCode code)
+ {
+ Close(createHandshakeCloseResponse(code));
+ }
+
+ // As server
+ public void ConnectAsServer()
+ {
+ try
+ {
+ if (acceptHandshake())
+ {
+ _readyState = WebSocketState.Open;
+ open();
+ }
+ }
+ catch (Exception ex)
+ {
+ processException(ex, "An exception has occurred while connecting.");
+ }
+ }
+
+ private string CreateResponseKey(string base64Key)
+ {
+ var buff = new StringBuilder(base64Key, 64);
+ buff.Append(_guid);
+ var src = _cryptoProvider.ComputeSHA1(Encoding.UTF8.GetBytes(buff.ToString()));
+
+ return Convert.ToBase64String(src);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Closes the WebSocket connection, and releases all associated resources.
+ /// </summary>
+ public void Close()
+ {
+ var msg = _readyState.CheckIfClosable();
+ if (msg != null)
+ {
+ error(msg);
+
+ return;
+ }
+
+ var send = _readyState == WebSocketState.Open;
+ close(new PayloadData(), send, send);
+ }
+
+ /// <summary>
+ /// Closes the WebSocket connection with the specified <see cref="CloseStatusCode"/>
+ /// and <see cref="string"/>, and releases all associated resources.
+ /// </summary>
+ /// <remarks>
+ /// This method emits a <see cref="OnError"/> event if the size
+ /// of <paramref name="reason"/> is greater than 123 bytes.
+ /// </remarks>
+ /// <param name="code">
+ /// One of the <see cref="CloseStatusCode"/> enum values, represents the status code
+ /// indicating the reason for the close.
+ /// </param>
+ /// <param name="reason">
+ /// A <see cref="string"/> that represents the reason for the close.
+ /// </param>
+ public void Close(CloseStatusCode code, string reason)
+ {
+ byte[] data = null;
+ var msg = _readyState.CheckIfClosable() ??
+ (data = ((ushort)code).Append(reason)).CheckIfValidControlData("reason");
+
+ if (msg != null)
+ {
+ error(msg);
+
+ return;
+ }
+
+ var send = _readyState == WebSocketState.Open && !code.IsReserved();
+ close(new PayloadData(data), send, send);
+ }
+
+ /// <summary>
+ /// Sends a binary <paramref name="data"/> asynchronously using the WebSocket connection.
+ /// </summary>
+ /// <remarks>
+ /// This method doesn't wait for the send to be complete.
+ /// </remarks>
+ /// <param name="data">
+ /// An array of <see cref="byte"/> that represents the binary data to send.
+ /// </param>
+ /// <param name="completed">
+ /// An Action&lt;bool&gt; delegate that references the method(s) called when the send is
+ /// complete. A <see cref="bool"/> passed to this delegate is <c>true</c> if the send is
+ /// complete successfully; otherwise, <c>false</c>.
+ /// </param>
+ public void SendAsync(byte[] data, Action<bool> completed)
+ {
+ var msg = _readyState.CheckIfOpen() ?? data.CheckIfValidSendData();
+ if (msg != null)
+ {
+ error(msg);
+
+ return;
+ }
+
+ sendAsync(Opcode.Binary, _memoryStreamFactory.CreateNew(data), completed);
+ }
+
+ /// <summary>
+ /// Sends a text <paramref name="data"/> asynchronously using the WebSocket connection.
+ /// </summary>
+ /// <remarks>
+ /// This method doesn't wait for the send to be complete.
+ /// </remarks>
+ /// <param name="data">
+ /// A <see cref="string"/> that represents the text data to send.
+ /// </param>
+ /// <param name="completed">
+ /// An Action&lt;bool&gt; delegate that references the method(s) called when the send is
+ /// complete. A <see cref="bool"/> passed to this delegate is <c>true</c> if the send is
+ /// complete successfully; otherwise, <c>false</c>.
+ /// </param>
+ public void SendAsync(string data, Action<bool> completed)
+ {
+ var msg = _readyState.CheckIfOpen() ?? data.CheckIfValidSendData();
+ if (msg != null)
+ {
+ error(msg);
+
+ return;
+ }
+
+ sendAsync(Opcode.Text, _memoryStreamFactory.CreateNew(Encoding.UTF8.GetBytes(data)), completed);
+ }
+
+ #endregion
+
+ #region Explicit Interface Implementation
+
+ /// <summary>
+ /// Closes the WebSocket connection, and releases all associated resources.
+ /// </summary>
+ /// <remarks>
+ /// This method closes the WebSocket connection with <see cref="CloseStatusCode.Away"/>.
+ /// </remarks>
+ void IDisposable.Dispose()
+ {
+ Close(CloseStatusCode.Away, null);
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/SocketHttpListener.Portable/WebSocketException.cs b/SocketHttpListener.Portable/WebSocketException.cs
new file mode 100644
index 0000000000..260721317c
--- /dev/null
+++ b/SocketHttpListener.Portable/WebSocketException.cs
@@ -0,0 +1,60 @@
+using System;
+
+namespace SocketHttpListener
+{
+ /// <summary>
+ /// The exception that is thrown when a <see cref="WebSocket"/> gets a fatal error.
+ /// </summary>
+ public class WebSocketException : Exception
+ {
+ #region Internal Constructors
+
+ internal WebSocketException ()
+ : this (CloseStatusCode.Abnormal, null, null)
+ {
+ }
+
+ internal WebSocketException (string message)
+ : this (CloseStatusCode.Abnormal, message, null)
+ {
+ }
+
+ internal WebSocketException (CloseStatusCode code)
+ : this (code, null, null)
+ {
+ }
+
+ internal WebSocketException (string message, Exception innerException)
+ : this (CloseStatusCode.Abnormal, message, innerException)
+ {
+ }
+
+ internal WebSocketException (CloseStatusCode code, string message)
+ : this (code, message, null)
+ {
+ }
+
+ internal WebSocketException (CloseStatusCode code, string message, Exception innerException)
+ : base (message ?? code.GetMessage (), innerException)
+ {
+ Code = code;
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the status code indicating the cause for the exception.
+ /// </summary>
+ /// <value>
+ /// One of the <see cref="CloseStatusCode"/> enum values, represents the status code indicating
+ /// the cause for the exception.
+ /// </value>
+ public CloseStatusCode Code {
+ get; private set;
+ }
+
+ #endregion
+ }
+}
diff --git a/SocketHttpListener.Portable/WebSocketFrame.cs b/SocketHttpListener.Portable/WebSocketFrame.cs
new file mode 100644
index 0000000000..44fa4a5dc3
--- /dev/null
+++ b/SocketHttpListener.Portable/WebSocketFrame.cs
@@ -0,0 +1,578 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace SocketHttpListener
+{
+ internal class WebSocketFrame : IEnumerable<byte>
+ {
+ #region Private Fields
+
+ private byte[] _extPayloadLength;
+ private Fin _fin;
+ private Mask _mask;
+ private byte[] _maskingKey;
+ private Opcode _opcode;
+ private PayloadData _payloadData;
+ private byte _payloadLength;
+ private Rsv _rsv1;
+ private Rsv _rsv2;
+ private Rsv _rsv3;
+
+ #endregion
+
+ #region Internal Fields
+
+ internal static readonly byte[] EmptyUnmaskPingData;
+
+ #endregion
+
+ #region Static Constructor
+
+ static WebSocketFrame()
+ {
+ EmptyUnmaskPingData = CreatePingFrame(Mask.Unmask).ToByteArray();
+ }
+
+ #endregion
+
+ #region Private Constructors
+
+ private WebSocketFrame()
+ {
+ }
+
+ #endregion
+
+ #region Internal Constructors
+
+ internal WebSocketFrame(Opcode opcode, PayloadData payload)
+ : this(Fin.Final, opcode, Mask.Mask, payload, false)
+ {
+ }
+
+ internal WebSocketFrame(Opcode opcode, Mask mask, PayloadData payload)
+ : this(Fin.Final, opcode, mask, payload, false)
+ {
+ }
+
+ internal WebSocketFrame(Fin fin, Opcode opcode, Mask mask, PayloadData payload)
+ : this(fin, opcode, mask, payload, false)
+ {
+ }
+
+ internal WebSocketFrame(
+ Fin fin, Opcode opcode, Mask mask, PayloadData payload, bool compressed)
+ {
+ _fin = fin;
+ _rsv1 = isData(opcode) && compressed ? Rsv.On : Rsv.Off;
+ _rsv2 = Rsv.Off;
+ _rsv3 = Rsv.Off;
+ _opcode = opcode;
+ _mask = mask;
+
+ var len = payload.Length;
+ if (len < 126)
+ {
+ _payloadLength = (byte)len;
+ _extPayloadLength = new byte[0];
+ }
+ else if (len < 0x010000)
+ {
+ _payloadLength = (byte)126;
+ _extPayloadLength = ((ushort)len).ToByteArrayInternally(ByteOrder.Big);
+ }
+ else
+ {
+ _payloadLength = (byte)127;
+ _extPayloadLength = len.ToByteArrayInternally(ByteOrder.Big);
+ }
+
+ if (mask == Mask.Mask)
+ {
+ _maskingKey = createMaskingKey();
+ payload.Mask(_maskingKey);
+ }
+ else
+ {
+ _maskingKey = new byte[0];
+ }
+
+ _payloadData = payload;
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ public byte[] ExtendedPayloadLength
+ {
+ get
+ {
+ return _extPayloadLength;
+ }
+ }
+
+ public Fin Fin
+ {
+ get
+ {
+ return _fin;
+ }
+ }
+
+ public bool IsBinary
+ {
+ get
+ {
+ return _opcode == Opcode.Binary;
+ }
+ }
+
+ public bool IsClose
+ {
+ get
+ {
+ return _opcode == Opcode.Close;
+ }
+ }
+
+ public bool IsCompressed
+ {
+ get
+ {
+ return _rsv1 == Rsv.On;
+ }
+ }
+
+ public bool IsContinuation
+ {
+ get
+ {
+ return _opcode == Opcode.Cont;
+ }
+ }
+
+ public bool IsControl
+ {
+ get
+ {
+ return _opcode == Opcode.Close || _opcode == Opcode.Ping || _opcode == Opcode.Pong;
+ }
+ }
+
+ public bool IsData
+ {
+ get
+ {
+ return _opcode == Opcode.Binary || _opcode == Opcode.Text;
+ }
+ }
+
+ public bool IsFinal
+ {
+ get
+ {
+ return _fin == Fin.Final;
+ }
+ }
+
+ public bool IsFragmented
+ {
+ get
+ {
+ return _fin == Fin.More || _opcode == Opcode.Cont;
+ }
+ }
+
+ public bool IsMasked
+ {
+ get
+ {
+ return _mask == Mask.Mask;
+ }
+ }
+
+ public bool IsPerMessageCompressed
+ {
+ get
+ {
+ return (_opcode == Opcode.Binary || _opcode == Opcode.Text) && _rsv1 == Rsv.On;
+ }
+ }
+
+ public bool IsPing
+ {
+ get
+ {
+ return _opcode == Opcode.Ping;
+ }
+ }
+
+ public bool IsPong
+ {
+ get
+ {
+ return _opcode == Opcode.Pong;
+ }
+ }
+
+ public bool IsText
+ {
+ get
+ {
+ return _opcode == Opcode.Text;
+ }
+ }
+
+ public ulong Length
+ {
+ get
+ {
+ return 2 + (ulong)(_extPayloadLength.Length + _maskingKey.Length) + _payloadData.Length;
+ }
+ }
+
+ public Mask Mask
+ {
+ get
+ {
+ return _mask;
+ }
+ }
+
+ public byte[] MaskingKey
+ {
+ get
+ {
+ return _maskingKey;
+ }
+ }
+
+ public Opcode Opcode
+ {
+ get
+ {
+ return _opcode;
+ }
+ }
+
+ public PayloadData PayloadData
+ {
+ get
+ {
+ return _payloadData;
+ }
+ }
+
+ public byte PayloadLength
+ {
+ get
+ {
+ return _payloadLength;
+ }
+ }
+
+ public Rsv Rsv1
+ {
+ get
+ {
+ return _rsv1;
+ }
+ }
+
+ public Rsv Rsv2
+ {
+ get
+ {
+ return _rsv2;
+ }
+ }
+
+ public Rsv Rsv3
+ {
+ get
+ {
+ return _rsv3;
+ }
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private byte[] createMaskingKey()
+ {
+ var key = new byte[4];
+ var rand = new Random();
+ rand.NextBytes(key);
+
+ return key;
+ }
+
+ private static bool isControl(Opcode opcode)
+ {
+ return opcode == Opcode.Close || opcode == Opcode.Ping || opcode == Opcode.Pong;
+ }
+
+ private static bool isData(Opcode opcode)
+ {
+ return opcode == Opcode.Text || opcode == Opcode.Binary;
+ }
+
+ private static WebSocketFrame read(byte[] header, Stream stream, bool unmask)
+ {
+ /* Header */
+
+ // FIN
+ var fin = (header[0] & 0x80) == 0x80 ? Fin.Final : Fin.More;
+ // RSV1
+ var rsv1 = (header[0] & 0x40) == 0x40 ? Rsv.On : Rsv.Off;
+ // RSV2
+ var rsv2 = (header[0] & 0x20) == 0x20 ? Rsv.On : Rsv.Off;
+ // RSV3
+ var rsv3 = (header[0] & 0x10) == 0x10 ? Rsv.On : Rsv.Off;
+ // Opcode
+ var opcode = (Opcode)(header[0] & 0x0f);
+ // MASK
+ var mask = (header[1] & 0x80) == 0x80 ? Mask.Mask : Mask.Unmask;
+ // Payload Length
+ var payloadLen = (byte)(header[1] & 0x7f);
+
+ // Check if correct frame.
+ var incorrect = isControl(opcode) && fin == Fin.More
+ ? "A control frame is fragmented."
+ : !isData(opcode) && rsv1 == Rsv.On
+ ? "A non data frame is compressed."
+ : null;
+
+ if (incorrect != null)
+ throw new WebSocketException(CloseStatusCode.IncorrectData, incorrect);
+
+ // Check if consistent frame.
+ if (isControl(opcode) && payloadLen > 125)
+ throw new WebSocketException(
+ CloseStatusCode.InconsistentData,
+ "The length of payload data of a control frame is greater than 125 bytes.");
+
+ var frame = new WebSocketFrame();
+ frame._fin = fin;
+ frame._rsv1 = rsv1;
+ frame._rsv2 = rsv2;
+ frame._rsv3 = rsv3;
+ frame._opcode = opcode;
+ frame._mask = mask;
+ frame._payloadLength = payloadLen;
+
+ /* Extended Payload Length */
+
+ var size = payloadLen < 126
+ ? 0
+ : payloadLen == 126
+ ? 2
+ : 8;
+
+ var extPayloadLen = size > 0 ? stream.ReadBytes(size) : new byte[0];
+ if (size > 0 && extPayloadLen.Length != size)
+ throw new WebSocketException(
+ "The 'Extended Payload Length' of a frame cannot be read from the data source.");
+
+ frame._extPayloadLength = extPayloadLen;
+
+ /* Masking Key */
+
+ var masked = mask == Mask.Mask;
+ var maskingKey = masked ? stream.ReadBytes(4) : new byte[0];
+ if (masked && maskingKey.Length != 4)
+ throw new WebSocketException(
+ "The 'Masking Key' of a frame cannot be read from the data source.");
+
+ frame._maskingKey = maskingKey;
+
+ /* Payload Data */
+
+ ulong len = payloadLen < 126
+ ? payloadLen
+ : payloadLen == 126
+ ? extPayloadLen.ToUInt16(ByteOrder.Big)
+ : extPayloadLen.ToUInt64(ByteOrder.Big);
+
+ byte[] data = null;
+ if (len > 0)
+ {
+ // Check if allowable payload data length.
+ if (payloadLen > 126 && len > PayloadData.MaxLength)
+ throw new WebSocketException(
+ CloseStatusCode.TooBig,
+ "The length of 'Payload Data' of a frame is greater than the allowable length.");
+
+ data = payloadLen > 126
+ ? stream.ReadBytes((long)len, 1024)
+ : stream.ReadBytes((int)len);
+
+ //if (data.LongLength != (long)len)
+ // throw new WebSocketException(
+ // "The 'Payload Data' of a frame cannot be read from the data source.");
+ }
+ else
+ {
+ data = new byte[0];
+ }
+
+ var payload = new PayloadData(data, masked);
+ if (masked && unmask)
+ {
+ payload.Mask(maskingKey);
+ frame._mask = Mask.Unmask;
+ frame._maskingKey = new byte[0];
+ }
+
+ frame._payloadData = payload;
+ return frame;
+ }
+
+ #endregion
+
+ #region Internal Methods
+
+ internal static WebSocketFrame CreateCloseFrame(Mask mask, byte[] data)
+ {
+ return new WebSocketFrame(Opcode.Close, mask, new PayloadData(data));
+ }
+
+ internal static WebSocketFrame CreateCloseFrame(Mask mask, PayloadData payload)
+ {
+ return new WebSocketFrame(Opcode.Close, mask, payload);
+ }
+
+ internal static WebSocketFrame CreateCloseFrame(Mask mask, CloseStatusCode code, string reason)
+ {
+ return new WebSocketFrame(
+ Opcode.Close, mask, new PayloadData(((ushort)code).Append(reason)));
+ }
+
+ internal static WebSocketFrame CreatePingFrame(Mask mask)
+ {
+ return new WebSocketFrame(Opcode.Ping, mask, new PayloadData());
+ }
+
+ internal static WebSocketFrame CreatePingFrame(Mask mask, byte[] data)
+ {
+ return new WebSocketFrame(Opcode.Ping, mask, new PayloadData(data));
+ }
+
+ internal static WebSocketFrame CreatePongFrame(Mask mask, PayloadData payload)
+ {
+ return new WebSocketFrame(Opcode.Pong, mask, payload);
+ }
+
+ internal static WebSocketFrame CreateWebSocketFrame(
+ Fin fin, Opcode opcode, Mask mask, byte[] data, bool compressed)
+ {
+ return new WebSocketFrame(fin, opcode, mask, new PayloadData(data), compressed);
+ }
+
+ internal static WebSocketFrame Read(Stream stream)
+ {
+ return Read(stream, true);
+ }
+
+ internal static WebSocketFrame Read(Stream stream, bool unmask)
+ {
+ var header = stream.ReadBytes(2);
+ if (header.Length != 2)
+ throw new WebSocketException(
+ "The header part of a frame cannot be read from the data source.");
+
+ return read(header, stream, unmask);
+ }
+
+ internal static async void ReadAsync(
+ Stream stream, bool unmask, Action<WebSocketFrame> completed, Action<Exception> error)
+ {
+ try
+ {
+ var header = await stream.ReadBytesAsync(2).ConfigureAwait(false);
+ if (header.Length != 2)
+ throw new WebSocketException(
+ "The header part of a frame cannot be read from the data source.");
+
+ var frame = read(header, stream, unmask);
+ if (completed != null)
+ completed(frame);
+ }
+ catch (Exception ex)
+ {
+ if (error != null)
+ {
+ error(ex);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public IEnumerator<byte> GetEnumerator()
+ {
+ foreach (var b in ToByteArray())
+ yield return b;
+ }
+
+ public void Print(bool dumped)
+ {
+ //Console.WriteLine(dumped ? dump(this) : print(this));
+ }
+
+ public byte[] ToByteArray()
+ {
+ using (var buff = new MemoryStream())
+ {
+ var header = (int)_fin;
+ header = (header << 1) + (int)_rsv1;
+ header = (header << 1) + (int)_rsv2;
+ header = (header << 1) + (int)_rsv3;
+ header = (header << 4) + (int)_opcode;
+ header = (header << 1) + (int)_mask;
+ header = (header << 7) + (int)_payloadLength;
+ buff.Write(((ushort)header).ToByteArrayInternally(ByteOrder.Big), 0, 2);
+
+ if (_payloadLength > 125)
+ buff.Write(_extPayloadLength, 0, _extPayloadLength.Length);
+
+ if (_mask == Mask.Mask)
+ buff.Write(_maskingKey, 0, _maskingKey.Length);
+
+ if (_payloadLength > 0)
+ {
+ var payload = _payloadData.ToByteArray();
+ if (_payloadLength < 127)
+ buff.Write(payload, 0, payload.Length);
+ else
+ buff.WriteBytes(payload);
+ }
+
+ return buff.ToArray();
+ }
+ }
+
+ public override string ToString()
+ {
+ return BitConverter.ToString(ToByteArray());
+ }
+
+ #endregion
+
+ #region Explicitly Implemented Interface Members
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/SocketHttpListener.Portable/WebSocketState.cs b/SocketHttpListener.Portable/WebSocketState.cs
new file mode 100644
index 0000000000..73b3a49ddc
--- /dev/null
+++ b/SocketHttpListener.Portable/WebSocketState.cs
@@ -0,0 +1,35 @@
+namespace SocketHttpListener
+{
+ /// <summary>
+ /// Contains the values of the state of the WebSocket connection.
+ /// </summary>
+ /// <remarks>
+ /// The values of the state are defined in
+ /// <see href="http://www.w3.org/TR/websockets/#dom-websocket-readystate">The WebSocket
+ /// API</see>.
+ /// </remarks>
+ public enum WebSocketState : ushort
+ {
+ /// <summary>
+ /// Equivalent to numeric value 0.
+ /// Indicates that the connection has not yet been established.
+ /// </summary>
+ Connecting = 0,
+ /// <summary>
+ /// Equivalent to numeric value 1.
+ /// Indicates that the connection is established and the communication is possible.
+ /// </summary>
+ Open = 1,
+ /// <summary>
+ /// Equivalent to numeric value 2.
+ /// Indicates that the connection is going through the closing handshake or
+ /// the <c>WebSocket.Close</c> method has been invoked.
+ /// </summary>
+ Closing = 2,
+ /// <summary>
+ /// Equivalent to numeric value 3.
+ /// Indicates that the connection has been closed or couldn't be opened.
+ /// </summary>
+ Closed = 3
+ }
+}
diff --git a/SocketHttpListener.Portable/packages.config b/SocketHttpListener.Portable/packages.config
new file mode 100644
index 0000000000..2aae715b5a
--- /dev/null
+++ b/SocketHttpListener.Portable/packages.config
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="MediaBrowser.Common" version="3.0.689" targetFramework="portable45-net45+win8" />
+ <package id="Patterns.Logging" version="1.0.0.6" targetFramework="portable45-net45+win8" />
+</packages> \ No newline at end of file
diff --git a/SocketHttpListener.Portable/project.json b/SocketHttpListener.Portable/project.json
new file mode 100644
index 0000000000..fbbe9eaf32
--- /dev/null
+++ b/SocketHttpListener.Portable/project.json
@@ -0,0 +1,17 @@
+{
+ "frameworks":{
+ "netstandard1.6":{
+ "dependencies":{
+ "NETStandard.Library":"1.6.0",
+ }
+ },
+ ".NETPortable,Version=v4.5,Profile=Profile7":{
+ "buildOptions": {
+ "define": [ ]
+ },
+ "frameworkAssemblies":{
+
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Emby.Server/Emby.Server.xproj b/src/Emby.Server/Emby.Server.xproj
index 81fffc6391..6a23809ced 100644
--- a/src/Emby.Server/Emby.Server.xproj
+++ b/src/Emby.Server/Emby.Server.xproj
@@ -18,14 +18,24 @@
<ItemGroup>
<ProjectReference Include="..\..\BDInfo\BDInfo.csproj" />
<ProjectReference Include="..\..\DvdLib\DvdLib.csproj" />
+ <ProjectReference Include="..\..\Emby.Dlna\Emby.Dlna.csproj" />
+ <ProjectReference Include="..\..\Emby.Drawing\Emby.Drawing.csproj" />
+ <ProjectReference Include="..\..\Emby.Photos\Emby.Photos.csproj" />
+ <ProjectReference Include="..\..\Emby.Server.Implementations\Emby.Server.Implementations.csproj" />
+ <ProjectReference Include="..\..\MediaBrowser.Api\MediaBrowser.Api.csproj" />
<ProjectReference Include="..\..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
<ProjectReference Include="..\..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
<ProjectReference Include="..\..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj" />
+ <ProjectReference Include="..\..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj" />
<ProjectReference Include="..\..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
<ProjectReference Include="..\..\MediaBrowser.Providers\MediaBrowser.Providers.csproj" />
+ <ProjectReference Include="..\..\MediaBrowser.Server.Implementations\MediaBrowser.Server.Implementations.csproj" />
<ProjectReference Include="..\..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj" />
<ProjectReference Include="..\..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj" />
<ProjectReference Include="..\..\OpenSubtitlesHandler\OpenSubtitlesHandler.csproj" />
+ <ProjectReference Include="..\..\RSSDP\RSSDP.csproj" />
+ <ProjectReference Include="..\..\ServiceStack\ServiceStack.csproj" />
+ <ProjectReference Include="..\..\SocketHttpListener.Portable\SocketHttpListener.Portable.csproj" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project> \ No newline at end of file
diff --git a/src/Emby.Server/project.json b/src/Emby.Server/project.json
index 66ebeec3c9..2693435a45 100644
--- a/src/Emby.Server/project.json
+++ b/src/Emby.Server/project.json
@@ -6,13 +6,12 @@
"dependencies": {
"Emby.Common.Implementations": "1.0.0-*",
- "Emby.Dlna": "1.0.0-*",
+ "Emby.Server.Core": "1.0.0-*",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
},
- "Mono.Nat": "1.0.0-*",
- "RSSDP": "1.0.0-*"
+ "Mono.Nat": "1.0.0-*"
},
"frameworks": {
@@ -25,6 +24,21 @@
"DvdLib": {
"target": "project"
},
+ "Emby.Dlna": {
+ "target": "project"
+ },
+ "Emby.Drawing": {
+ "target": "project"
+ },
+ "Emby.Photos": {
+ "target": "project"
+ },
+ "Emby.Server.Implementations": {
+ "target": "project"
+ },
+ "MediaBrowser.Api": {
+ "target": "project"
+ },
"MediaBrowser.Common": {
"target": "project"
},
@@ -34,12 +48,18 @@
"MediaBrowser.LocalMetadata": {
"target": "project"
},
+ "MediaBrowser.MediaEncoding": {
+ "target": "project"
+ },
"MediaBrowser.Model": {
"target": "project"
},
"MediaBrowser.Providers": {
"target": "project"
},
+ "MediaBrowser.Server.Implementations": {
+ "target": "project"
+ },
"MediaBrowser.WebDashboard": {
"target": "project"
},
@@ -48,6 +68,15 @@
},
"OpenSubtitlesHandler": {
"target": "project"
+ },
+ "RSSDP": {
+ "target": "project"
+ },
+ "ServiceStack": {
+ "target": "project"
+ },
+ "SocketHttpListener.Portable": {
+ "target": "project"
}
}
}