Merge pull request #2364 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-12-22 18:54:45 -05:00 committed by GitHub
commit 026e58eb16
19 changed files with 190 additions and 161 deletions

View File

@ -10,11 +10,17 @@ namespace Emby.Common.Implementations.EnvironmentInfo
public class EnvironmentInfo : IEnvironmentInfo public class EnvironmentInfo : IEnvironmentInfo
{ {
public MediaBrowser.Model.System.Architecture? CustomArchitecture { get; set; } public MediaBrowser.Model.System.Architecture? CustomArchitecture { get; set; }
public MediaBrowser.Model.System.OperatingSystem? CustomOperatingSystem { get; set; }
public MediaBrowser.Model.System.OperatingSystem OperatingSystem public MediaBrowser.Model.System.OperatingSystem OperatingSystem
{ {
get get
{ {
if (CustomOperatingSystem.HasValue)
{
return CustomOperatingSystem.Value;
}
#if NET46 #if NET46
switch (Environment.OSVersion.Platform) switch (Environment.OSVersion.Platform)
{ {

View File

@ -282,9 +282,12 @@ namespace Emby.Common.Implementations.ScheduledTasks
throw new ArgumentNullException("value"); throw new ArgumentNullException("value");
} }
SaveTriggers(value); // This null check is not great, but is needed to handle bad user input, or user mucking with the config file incorrectly
var triggerList = value.Where(i => i != null).ToArray();
InternalTriggers = value.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray(); SaveTriggers(triggerList);
InternalTriggers = triggerList.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
} }
} }
@ -535,7 +538,8 @@ namespace Emby.Common.Implementations.ScheduledTasks
/// <returns>IEnumerable{BaseTaskTrigger}.</returns> /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
private Tuple<TaskTriggerInfo, ITaskTrigger>[] LoadTriggers() private Tuple<TaskTriggerInfo, ITaskTrigger>[] LoadTriggers()
{ {
var settings = LoadTriggerSettings(); // This null check is not great, but is needed to handle bad user input, or user mucking with the config file incorrectly
var settings = LoadTriggerSettings().Where(i => i != null).ToArray();
return settings.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray(); return settings.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
} }
@ -544,8 +548,12 @@ namespace Emby.Common.Implementations.ScheduledTasks
{ {
try try
{ {
return JsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(GetConfigurationFilePath()) var list = JsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(GetConfigurationFilePath());
.ToArray();
if (list != null)
{
return list.ToArray();
}
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
@ -555,8 +563,8 @@ namespace Emby.Common.Implementations.ScheduledTasks
catch (DirectoryNotFoundException) catch (DirectoryNotFoundException)
{ {
// File doesn't exist. No biggie. Return defaults. // File doesn't exist. No biggie. Return defaults.
return ScheduledTask.GetDefaultTriggers().ToArray();
} }
return ScheduledTask.GetDefaultTriggers().ToArray();
} }
/// <summary> /// <summary>

View File

@ -1583,7 +1583,8 @@ namespace Emby.Server.Core
public void LaunchUrl(string url) public void LaunchUrl(string url)
{ {
if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows) if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows &&
EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -1591,7 +1592,7 @@ namespace Emby.Server.Core
var process = ProcessFactory.Create(new ProcessOptions var process = ProcessFactory.Create(new ProcessOptions
{ {
FileName = url, FileName = url,
EnableRaisingEvents = true, //EnableRaisingEvents = true,
UseShellExecute = true, UseShellExecute = true,
ErrorDialog = false ErrorDialog = false
}); });

View File

@ -203,20 +203,12 @@ namespace Emby.Server.Implementations.HttpServer
// Do not use the memoryStreamFactory here, they don't place nice with compression // Do not use the memoryStreamFactory here, they don't place nice with compression
using (var ms = new MemoryStream()) using (var ms = new MemoryStream())
{ {
using (var compressionStream = GetCompressionStream(ms, compressionType)) ContentTypes.Instance.SerializeToStream(request, dto, ms);
{ ms.Position = 0;
ContentTypes.Instance.SerializeToStream(request, dto, compressionStream);
compressionStream.Dispose();
var compressedBytes = ms.ToArray(); var responseHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var httpResult = new StreamWriter(compressedBytes, request.ResponseContentType, _logger); return GetCompressedResult(ms, compressionType, responseHeaders, false, request.ResponseContentType).Result;
//httpResult.Headers["Content-Length"] = compressedBytes.Length.ToString(UsCulture);
httpResult.Headers["Content-Encoding"] = compressionType;
return httpResult;
}
} }
} }
@ -591,45 +583,53 @@ namespace Emby.Server.Implementations.HttpServer
}; };
} }
string content;
using (var stream = await factoryFn().ConfigureAwait(false)) using (var stream = await factoryFn().ConfigureAwait(false))
{ {
using (var reader = new StreamReader(stream)) return await GetCompressedResult(stream, requestedCompressionType, responseHeaders, isHeadRequest, contentType).ConfigureAwait(false);
}
}
private async Task<IHasHeaders> GetCompressedResult(Stream stream,
string requestedCompressionType,
IDictionary<string,string> responseHeaders,
bool isHeadRequest,
string contentType)
{ {
content = await reader.ReadToEndAsync().ConfigureAwait(false); using (var reader = new MemoryStream())
} {
} await stream.CopyToAsync(reader).ConfigureAwait(false);
var contents = Compress(content, requestedCompressionType); reader.Position = 0;
var content = reader.ToArray();
responseHeaders["Content-Length"] = contents.Length.ToString(UsCulture); if (content.Length >= 1024)
{
content = Compress(content, requestedCompressionType);
responseHeaders["Content-Encoding"] = requestedCompressionType; responseHeaders["Content-Encoding"] = requestedCompressionType;
}
responseHeaders["Content-Length"] = content.Length.ToString(UsCulture);
if (isHeadRequest) if (isHeadRequest)
{ {
return GetHttpResult(new byte[] { }, contentType, true); return GetHttpResult(new byte[] { }, contentType, true);
} }
return GetHttpResult(contents, contentType, true, responseHeaders); return GetHttpResult(content, contentType, true, responseHeaders);
}
} }
private byte[] Compress(string text, string compressionType) private byte[] Compress(byte[] bytes, string compressionType)
{ {
if (compressionType == "deflate") if (compressionType == "deflate")
return Deflate(text); return Deflate(bytes);
if (compressionType == "gzip") if (compressionType == "gzip")
return GZip(text); return GZip(bytes);
throw new NotSupportedException(compressionType); throw new NotSupportedException(compressionType);
} }
private byte[] Deflate(string text)
{
return Deflate(Encoding.UTF8.GetBytes(text));
}
private byte[] Deflate(byte[] bytes) private byte[] Deflate(byte[] bytes)
{ {
// In .NET FX incompat-ville, you can't access compressed bytes without closing DeflateStream // In .NET FX incompat-ville, you can't access compressed bytes without closing DeflateStream
@ -644,11 +644,6 @@ namespace Emby.Server.Implementations.HttpServer
} }
} }
private byte[] GZip(string text)
{
return GZip(Encoding.UTF8.GetBytes(text));
}
private byte[] GZip(byte[] buffer) private byte[] GZip(byte[] buffer)
{ {
using (var ms = new MemoryStream()) using (var ms = new MemoryStream())

View File

@ -74,21 +74,21 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)) if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
{ {
return ResolveVideos<MusicVideo>(parent, files, directoryService, false); return ResolveVideos<MusicVideo>(parent, files, directoryService, false, collectionType);
} }
if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) || if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) ||
string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase)) string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
{ {
return ResolveVideos<Video>(parent, files, directoryService, false); return ResolveVideos<Video>(parent, files, directoryService, false, collectionType);
} }
if (string.IsNullOrEmpty(collectionType)) if (string.IsNullOrWhiteSpace(collectionType))
{ {
// Owned items should just use the plain video type // Owned items should just use the plain video type
if (parent == null) if (parent == null)
{ {
return ResolveVideos<Video>(parent, files, directoryService, false); return ResolveVideos<Video>(parent, files, directoryService, false, collectionType);
} }
if (parent is Series || parent.GetParents().OfType<Series>().Any()) if (parent is Series || parent.GetParents().OfType<Series>().Any())
@ -96,18 +96,18 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
return null; return null;
} }
return ResolveVideos<Movie>(parent, files, directoryService, false); return ResolveVideos<Movie>(parent, files, directoryService, false, collectionType);
} }
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase)) if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
{ {
return ResolveVideos<Movie>(parent, files, directoryService, true); return ResolveVideos<Movie>(parent, files, directoryService, true, collectionType);
} }
return null; return null;
} }
private MultiItemResolverResult ResolveVideos<T>(Folder parent, IEnumerable<FileSystemMetadata> fileSystemEntries, IDirectoryService directoryService, bool suppportMultiEditions) private MultiItemResolverResult ResolveVideos<T>(Folder parent, IEnumerable<FileSystemMetadata> fileSystemEntries, IDirectoryService directoryService, bool suppportMultiEditions, string collectionType)
where T : Video, new() where T : Video, new()
{ {
var files = new List<FileSystemMetadata>(); var files = new List<FileSystemMetadata>();
@ -117,6 +117,16 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
// Loop through each child file/folder and see if we find a video // Loop through each child file/folder and see if we find a video
foreach (var child in fileSystemEntries) foreach (var child in fileSystemEntries)
{ {
// This is a hack but currently no better way to resolve a sometimes ambiguous situation
if (string.IsNullOrWhiteSpace(collectionType))
{
if (string.Equals(child.Name, "tvshow.nfo", StringComparison.OrdinalIgnoreCase) ||
string.Equals(child.Name, "season.nfo", StringComparison.OrdinalIgnoreCase))
{
return null;
}
}
if (child.IsDirectory) if (child.IsDirectory)
{ {
leftOver.Add(child); leftOver.Add(child);
@ -408,7 +418,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
!string.Equals(collectionType, CollectionType.Photos) && !string.Equals(collectionType, CollectionType.Photos) &&
!string.Equals(collectionType, CollectionType.MusicVideos); !string.Equals(collectionType, CollectionType.MusicVideos);
var result = ResolveVideos<T>(parent, fileSystemEntries, directoryService, supportsMultiVersion); var result = ResolveVideos<T>(parent, fileSystemEntries, directoryService, supportsMultiVersion, collectionType) ??
new MultiItemResolverResult();
if (result.Items.Count == 1) if (result.Items.Count == 1)
{ {

View File

@ -440,10 +440,23 @@ namespace Emby.Server.Implementations.LiveTv.Listings
IsKids = string.Equals(details.audience, "children", StringComparison.OrdinalIgnoreCase), IsKids = string.Equals(details.audience, "children", StringComparison.OrdinalIgnoreCase),
IsSports = showType.IndexOf("sports", StringComparison.OrdinalIgnoreCase) != -1, IsSports = showType.IndexOf("sports", StringComparison.OrdinalIgnoreCase) != -1,
IsMovie = showType.IndexOf("movie", StringComparison.OrdinalIgnoreCase) != -1 || showType.IndexOf("film", StringComparison.OrdinalIgnoreCase) != -1, IsMovie = showType.IndexOf("movie", StringComparison.OrdinalIgnoreCase) != -1 || showType.IndexOf("film", StringComparison.OrdinalIgnoreCase) != -1,
ShowId = programInfo.programID,
Etag = programInfo.md5 Etag = programInfo.md5
}; };
var showId = programInfo.programID ?? string.Empty;
// According to SchedulesDirect, these are generic, unidentified episodes
// SH005316560000
var hasUniqueShowId = !showId.StartsWith("SH", StringComparison.OrdinalIgnoreCase) ||
!showId.EndsWith("0000", StringComparison.OrdinalIgnoreCase);
if (!hasUniqueShowId)
{
showId = newID;
}
info.ShowId = showId;
if (programInfo.videoProperties != null) if (programInfo.videoProperties != null)
{ {
info.IsHD = programInfo.videoProperties.Contains("hdtv", StringComparer.OrdinalIgnoreCase); info.IsHD = programInfo.videoProperties.Contains("hdtv", StringComparer.OrdinalIgnoreCase);

View File

@ -2647,7 +2647,7 @@ namespace Emby.Server.Implementations.LiveTv
public GuideInfo GetGuideInfo() public GuideInfo GetGuideInfo()
{ {
var startDate = DateTime.UtcNow; var startDate = DateTime.UtcNow;
var endDate = startDate.AddDays(14); var endDate = startDate.AddDays(GetGuideDays());
return new GuideInfo return new GuideInfo
{ {

View File

@ -1042,10 +1042,7 @@ namespace Emby.Server.Implementations.Sync
throw new ArgumentException("Operation is not valid for this job item"); throw new ArgumentException("Operation is not valid for this job item");
} }
if (jobItem.Status != SyncJobItemStatus.Synced)
{
jobItem.Status = SyncJobItemStatus.Cancelled; jobItem.Status = SyncJobItemStatus.Cancelled;
}
jobItem.Progress = 0; jobItem.Progress = 0;
jobItem.IsMarkedForRemoval = true; jobItem.IsMarkedForRemoval = true;
@ -1071,18 +1068,18 @@ namespace Emby.Server.Implementations.Sync
_logger.ErrorException("Error deleting directory {0}", ex, path); _logger.ErrorException("Error deleting directory {0}", ex, path);
} }
//var jobItemsResult = GetJobItems(new SyncJobItemQuery var jobItemsResult = GetJobItems(new SyncJobItemQuery
//{ {
// AddMetadata = false, AddMetadata = false,
// JobId = jobItem.JobId, JobId = jobItem.JobId,
// Limit = 0, Limit = 0,
// Statuses = new[] { SyncJobItemStatus.Converting, SyncJobItemStatus.Failed, SyncJobItemStatus.Queued, SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced, SyncJobItemStatus.Transferring } Statuses = new[] { SyncJobItemStatus.Converting, SyncJobItemStatus.Queued, SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced, SyncJobItemStatus.Transferring }
//}); });
//if (jobItemsResult.TotalRecordCount == 0) if (jobItemsResult.TotalRecordCount == 0)
//{ {
// await CancelJob(jobItem.JobId).ConfigureAwait(false); await CancelJob(jobItem.JobId).ConfigureAwait(false);
//} }
} }
public Task MarkJobItemForRemoval(string id) public Task MarkJobItemForRemoval(string id)

View File

@ -38,6 +38,18 @@ namespace Emby.Server.Implementations.Sync
} }
} }
if (item.Status == SyncJobItemStatus.Cancelled)
{
try
{
await _sessionManager.SendMessageToUserDeviceSessions(item.TargetId, "SyncJobItemCancelled", item, CancellationToken.None).ConfigureAwait(false);
}
catch
{
}
}
} }
public void Dispose() public void Dispose()

View File

@ -153,7 +153,7 @@ namespace MediaBrowser.Api.Playback.Progressive
if (!state.RunTimeTicks.HasValue) if (!state.RunTimeTicks.HasValue)
{ {
args += " -fflags +genpts -flags +global_header"; args += " -flags -global_header -fflags +genpts";
} }
return args; return args;

View File

@ -95,6 +95,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
int defaultImageExtractionTimeoutMs, int defaultImageExtractionTimeoutMs,
bool enableEncoderFontFile, IEnvironmentInfo environmentInfo) bool enableEncoderFontFile, IEnvironmentInfo environmentInfo)
{ {
if (jsonSerializer == null)
{
throw new ArgumentNullException("jsonSerializer");
}
_logger = logger; _logger = logger;
_jsonSerializer = jsonSerializer; _jsonSerializer = jsonSerializer;
ConfigurationManager = configurationManager; ConfigurationManager = configurationManager;
@ -632,7 +637,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
var result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream); var result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
if (result.streams == null && result.format == null) if (result == null || (result.streams == null && result.format == null))
{ {
throw new Exception("ffprobe failed - streams and format are both null."); throw new Exception("ffprobe failed - streams and format are both null.");
} }

View File

@ -238,7 +238,7 @@ namespace MediaBrowser.Providers.TV
var targetSeries = DetermineAppropriateSeries(series, tuple.Item1); var targetSeries = DetermineAppropriateSeries(series, tuple.Item1);
var seasonOffset = TvdbSeriesProvider.GetSeriesOffset(targetSeries.ProviderIds) ?? ((targetSeries.AnimeSeriesIndex ?? 1) - 1); var seasonOffset = TvdbSeriesProvider.GetSeriesOffset(targetSeries.ProviderIds) ?? ((targetSeries.AnimeSeriesIndex ?? 1) - 1);
var unairedThresholdDays = 1; var unairedThresholdDays = 2;
now = now.AddDays(0 - unairedThresholdDays); now = now.AddDays(0 - unairedThresholdDays);
if (airDate.Value < now) if (airDate.Value < now)

View File

@ -142,7 +142,10 @@ namespace MediaBrowser.Server.Mac
private static EnvironmentInfo GetEnvironmentInfo() private static EnvironmentInfo GetEnvironmentInfo()
{ {
var info = new EnvironmentInfo(); var info = new EnvironmentInfo()
{
CustomOperatingSystem = MediaBrowser.Model.System.OperatingSystem.OSX
};
var uname = GetUnixName(); var uname = GetUnixName();

View File

@ -51,8 +51,11 @@ namespace MediaBrowser.Server.Mono
} }
else if (environment.OperatingSystem == Model.System.OperatingSystem.Linux) else if (environment.OperatingSystem == Model.System.OperatingSystem.Linux)
{ {
info.FFMpegFilename = "ffmpeg";
info.FFProbeFilename = "ffprobe";
info.ArchiveType = "7z"; info.ArchiveType = "7z";
info.Version = "20160215"; info.Version = "20160215";
info.DownloadUrls = GetDownloadUrls();
} }
// No version available - user requirement // No version available - user requirement
@ -61,6 +64,25 @@ namespace MediaBrowser.Server.Mono
return info; return info;
} }
private string[] GetDownloadUrls()
{
switch (EnvironmentInfo.SystemArchitecture)
{
case Architecture.X64:
return new[]
{
"https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-git-20160215-64bit-static.7z"
};
case Architecture.X86:
return new[]
{
"https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-git-20160215-32bit-static.7z"
};
}
return new string[] { };
}
protected override void RestartInternal() protected override void RestartInternal()
{ {
MainClass.Restart(StartupOptions); MainClass.Restart(StartupOptions);

View File

@ -1,6 +1,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Security; using System.Security;
using System.Text; using System.Text;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
@ -52,7 +53,7 @@ namespace MediaBrowser.ServerApplication.Native
/// <summary> /// <summary>
/// The STG m_ READ /// The STG m_ READ
/// </summary> /// </summary>
public const uint STGM_READ = 0; public const int STGM_READ = 0;
} }
/// <summary> /// <summary>
@ -319,72 +320,6 @@ namespace MediaBrowser.ServerApplication.Native
} }
/// <summary>
/// Interface IPersist
/// </summary>
[ComImport, Guid("0000010c-0000-0000-c000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersist
{
/// <summary>
/// Gets the class ID.
/// </summary>
/// <param name="pClassID">The p class ID.</param>
[PreserveSig]
void GetClassID(out Guid pClassID);
}
/// <summary>
/// Interface IPersistFile
/// </summary>
[ComImport, Guid("0000010b-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersistFile : IPersist
{
/// <summary>
/// Gets the class ID.
/// </summary>
/// <param name="pClassID">The p class ID.</param>
new void GetClassID(out Guid pClassID);
/// <summary>
/// Determines whether this instance is dirty.
/// </summary>
[PreserveSig]
int IsDirty();
/// <summary>
/// Loads the specified PSZ file name.
/// </summary>
/// <param name="pszFileName">Name of the PSZ file.</param>
/// <param name="dwMode">The dw mode.</param>
[PreserveSig]
void Load([In, MarshalAs(UnmanagedType.LPWStr)]
string pszFileName, uint dwMode);
/// <summary>
/// Saves the specified PSZ file name.
/// </summary>
/// <param name="pszFileName">Name of the PSZ file.</param>
/// <param name="remember">if set to <c>true</c> [remember].</param>
[PreserveSig]
void Save([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
[In, MarshalAs(UnmanagedType.Bool)] bool remember);
/// <summary>
/// Saves the completed.
/// </summary>
/// <param name="pszFileName">Name of the PSZ file.</param>
[PreserveSig]
void SaveCompleted([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName);
/// <summary>
/// Gets the cur file.
/// </summary>
/// <param name="ppszFileName">Name of the PPSZ file.</param>
[PreserveSig]
void GetCurFile([In, MarshalAs(UnmanagedType.LPWStr)] string ppszFileName);
}
// CLSID_ShellLink from ShlGuid.h // CLSID_ShellLink from ShlGuid.h
/// <summary> /// <summary>
/// Class ShellLink /// Class ShellLink

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices.ComTypes;
using Emby.Server.Core; using Emby.Server.Core;
using Emby.Server.Implementations; using Emby.Server.Implementations;
using Emby.Server.Implementations.EntryPoints; using Emby.Server.Implementations.EntryPoints;
@ -93,21 +94,30 @@ namespace MediaBrowser.ServerApplication
protected override void ConfigureAutoRunInternal(bool autorun) protected override void ConfigureAutoRunInternal(bool autorun)
{ {
var shortcutPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.StartMenu), "Emby", "Emby Server.lnk");
var startupPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Startup); var startupPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Startup);
if (autorun) if (autorun && !MainStartup.IsRunningAsService)
{ {
//Copy our shortut into the startup folder for this user //Copy our shortut into the startup folder for this user
var targetPath = Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk"); var targetPath = Path.Combine(startupPath, "Emby Server.lnk");
FileSystemManager.CreateDirectory(Path.GetDirectoryName(targetPath));
File.Copy(shortcutPath, targetPath, true); IShellLinkW link = (IShellLinkW)new ShellLink();
var appPath = Process.GetCurrentProcess().MainModule.FileName;
// setup shortcut information
link.SetDescription(Name);
link.SetPath(appPath);
link.SetWorkingDirectory(Path.GetDirectoryName(appPath));
// save it
IPersistFile file = (IPersistFile)link;
file.Save(targetPath, false);
} }
else else
{ {
//Remove our shortcut from the startup folder for this user //Remove our shortcut from the startup folder for this user
FileSystemManager.DeleteFile(Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk")); FileSystemManager.DeleteFile(Path.Combine(startupPath, "Emby Server.lnk"));
} }
} }

View File

@ -209,7 +209,7 @@ namespace SocketHttpListener.Net
// TODO: can we get this stream before reading the input? // TODO: can we get this stream before reading the input?
if (o_stream == null) if (o_stream == null)
{ {
context.Response.DetermineIfChunked(); //context.Response.DetermineIfChunked();
if (context.Response.SendChunked || isExpect100Continue || context.Request.IsWebSocketRequest || true) if (context.Response.SendChunked || isExpect100Continue || context.Request.IsWebSocketRequest || true)
{ {
@ -508,7 +508,7 @@ namespace SocketHttpListener.Net
{ {
force_close |= !context.Request.KeepAlive; force_close |= !context.Request.KeepAlive;
if (!force_close) if (!force_close)
force_close = (context.Response.Headers["connection"] == "close"); force_close = (string.Equals(context.Response.Headers["connection"], "close", StringComparison.OrdinalIgnoreCase));
/* /*
if (!force_close) { if (!force_close) {
// bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 || // bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 ||

View File

@ -386,7 +386,7 @@ namespace SocketHttpListener.Net
if (content_type != null) if (content_type != null)
{ {
if (content_encoding != null && content_type.IndexOf("charset=", StringComparison.Ordinal) == -1) if (content_encoding != null && content_type.IndexOf("charset=", StringComparison.OrdinalIgnoreCase) == -1)
{ {
string enc_name = content_encoding.WebName; string enc_name = content_encoding.WebName;
headers.SetInternal("Content-Type", content_type + "; charset=" + enc_name); headers.SetInternal("Content-Type", content_type + "; charset=" + enc_name);
@ -429,9 +429,10 @@ namespace SocketHttpListener.Net
* HttpStatusCode.InternalServerError 500 * HttpStatusCode.InternalServerError 500
* HttpStatusCode.ServiceUnavailable 503 * HttpStatusCode.ServiceUnavailable 503
*/ */
bool conn_close = (status_code == 408 || status_code == 411 || bool conn_close = status_code == 400 || status_code == 408 || status_code == 411 ||
status_code == 413 || status_code == 414 || status_code == 413 || status_code == 414 ||
status_code == 503); status_code == 500 ||
status_code == 503;
if (conn_close == false) if (conn_close == false)
conn_close = !context.Request.KeepAlive; conn_close = !context.Request.KeepAlive;

View File

@ -136,6 +136,11 @@ namespace SocketHttpListener.Net
if (disposed) if (disposed)
throw new ObjectDisposedException(GetType().ToString()); throw new ObjectDisposedException(GetType().ToString());
if (count == 0)
{
//return;
}
byte[] bytes = null; byte[] bytes = null;
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false); MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
bool chunked = response.SendChunked; bool chunked = response.SendChunked;
@ -176,6 +181,11 @@ namespace SocketHttpListener.Net
if (disposed) if (disposed)
throw new ObjectDisposedException(GetType().ToString()); throw new ObjectDisposedException(GetType().ToString());
if (count == 0)
{
//return;
}
byte[] bytes = null; byte[] bytes = null;
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false); MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
bool chunked = response.SendChunked; bool chunked = response.SendChunked;
@ -206,7 +216,7 @@ namespace SocketHttpListener.Net
await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
} }
if (response.SendChunked) if (chunked)
stream.Write(crlf, 0, 2); stream.Write(crlf, 0, 2);
} }