aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs18
-rw-r--r--Emby.Server.Implementations/HttpServer/FileWriter.cs10
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpResultFactory.cs5
-rw-r--r--Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs11
-rw-r--r--Emby.Server.Implementations/HttpServer/ResponseFilter.cs20
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs1
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs1
-rw-r--r--Emby.Server.Implementations/Security/PluginSecurityManager.cs6
-rw-r--r--Emby.Server.Implementations/Session/HttpSessionController.cs2
-rw-r--r--Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs2
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs8
-rw-r--r--MediaBrowser.Api/Playback/StreamState.cs2
-rw-r--r--MediaBrowser.Controller/Entities/AudioBook.cs4
-rw-r--r--MediaBrowser.Controller/Entities/Book.cs4
-rw-r--r--MediaBrowser.Controller/Entities/IHasSeries.cs1
-rw-r--r--MediaBrowser.Controller/Entities/TV/Episode.cs5
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs5
-rw-r--r--MediaBrowser.Providers/TV/DummySeasonProvider.cs3
-rw-r--r--MediaBrowser.Providers/TV/EpisodeMetadataService.cs7
-rw-r--r--MediaBrowser.Providers/TV/SeasonMetadataService.cs7
-rw-r--r--SocketHttpListener.Portable/Net/HttpListenerResponse.cs2
-rw-r--r--SocketHttpListener.Portable/Net/ResponseStream.cs28
22 files changed, 63 insertions, 89 deletions
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 688596ab8..272d79e48 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -254,7 +254,6 @@ namespace Emby.Server.Implementations.Data
AddColumn(db, "TypedBaseItems", "SeasonName", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "SeasonId", "GUID", existingColumnNames);
AddColumn(db, "TypedBaseItems", "SeriesId", "GUID", existingColumnNames);
- AddColumn(db, "TypedBaseItems", "SeriesSortName", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "ExternalSeriesId", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "Tagline", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "Keywords", "Text", existingColumnNames);
@@ -458,7 +457,6 @@ namespace Emby.Server.Implementations.Data
"SeasonName",
"SeasonId",
"SeriesId",
- "SeriesSortName",
"PresentationUniqueKey",
"InheritedParentalRatingValue",
"InheritedTags",
@@ -591,7 +589,6 @@ namespace Emby.Server.Implementations.Data
"SeasonName",
"SeasonId",
"SeriesId",
- "SeriesSortName",
"ExternalSeriesId",
"Tagline",
"Keywords",
@@ -1020,13 +1017,11 @@ namespace Emby.Server.Implementations.Data
if (hasSeries != null)
{
saveItemStatement.TryBind("@SeriesId", hasSeries.SeriesId);
- saveItemStatement.TryBind("@SeriesSortName", hasSeries.SeriesSortName);
saveItemStatement.TryBind("@SeriesPresentationUniqueKey", hasSeries.SeriesPresentationUniqueKey);
}
else
{
saveItemStatement.TryBindNull("@SeriesId");
- saveItemStatement.TryBindNull("@SeriesSortName");
saveItemStatement.TryBindNull("@SeriesPresentationUniqueKey");
}
@@ -1843,15 +1838,6 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (hasSeries != null)
- {
- if (!reader.IsDBNull(index))
- {
- hasSeries.SeriesSortName = reader.GetString(index);
- }
- }
- index++;
-
if (!reader.IsDBNull(index))
{
item.PresentationUniqueKey = reader.GetString(index);
@@ -2880,6 +2866,10 @@ namespace Emby.Server.Implementations.Data
{
return new Tuple<string, bool>("(Select MAX(LastPlayedDate) from TypedBaseItems B" + GetJoinUserDataText(query) + " where Played=1 and B.SeriesPresentationUniqueKey=A.PresentationUniqueKey)", false);
}
+ if (string.Equals(name, ItemSortBy.SeriesSortName, StringComparison.OrdinalIgnoreCase))
+ {
+ return new Tuple<string, bool>("(Select SortName from TypedBaseItems where B.Guid=A.SeriesId)", false);
+ }
return new Tuple<string, bool>(name, false);
}
diff --git a/Emby.Server.Implementations/HttpServer/FileWriter.cs b/Emby.Server.Implementations/HttpServer/FileWriter.cs
index dbaf97b1e..8cb7b5dbf 100644
--- a/Emby.Server.Implementations/HttpServer/FileWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/FileWriter.cs
@@ -58,6 +58,7 @@ namespace Emby.Server.Implementations.HttpServer
Headers["Content-Type"] = contentType;
TotalContentLength = fileSystem.GetFileInfo(path).Length;
+ Headers["Accept-Ranges"] = "bytes";
if (string.IsNullOrWhiteSpace(rangeHeader))
{
@@ -66,7 +67,6 @@ namespace Emby.Server.Implementations.HttpServer
}
else
{
- Headers["Accept-Ranges"] = "bytes";
StatusCode = HttpStatusCode.PartialContent;
SetRangeValues();
}
@@ -96,8 +96,12 @@ namespace Emby.Server.Implementations.HttpServer
RangeLength = 1 + RangeEnd - RangeStart;
// Content-Length is the length of what we're serving, not the original content
- Headers["Content-Length"] = RangeLength.ToString(UsCulture);
- Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", RangeStart, RangeEnd, TotalContentLength);
+ var lengthString = RangeLength.ToString(UsCulture);
+ Headers["Content-Length"] = lengthString;
+ var rangeString = string.Format("bytes {0}-{1}/{2}", RangeStart, RangeEnd, TotalContentLength);
+ Headers["Content-Range"] = rangeString;
+
+ Logger.Info("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString);
}
/// <summary>
diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
index 310161d41..687bd62b0 100644
--- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -501,7 +501,7 @@ namespace Emby.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.Headers.Get("Range")))
+ if (!string.IsNullOrWhiteSpace(requestContext.Headers.Get("Range")))
{
return false;
}
@@ -566,7 +566,7 @@ namespace Emby.Server.Implementations.HttpServer
};
}
- if (!string.IsNullOrEmpty(rangeHeader))
+ if (!string.IsNullOrWhiteSpace(rangeHeader))
{
var stream = await factoryFn().ConfigureAwait(false);
@@ -621,6 +621,7 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders["Content-Encoding"] = requestedCompressionType;
}
+ responseHeaders["Vary"] = "Accept-Encoding";
responseHeaders["Content-Length"] = content.Length.ToString(UsCulture);
if (isHeadRequest)
diff --git a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
index e88994bec..7c967949b 100644
--- a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
@@ -189,10 +189,15 @@ namespace Emby.Server.Implementations.HttpServer
private async Task CopyToInternalAsync(Stream source, Stream destination, long copyLength)
{
var array = new byte[BufferSize];
- int count;
- while ((count = await source.ReadAsync(array, 0, array.Length).ConfigureAwait(false)) != 0)
+ int bytesRead;
+ while ((bytesRead = await source.ReadAsync(array, 0, array.Length).ConfigureAwait(false)) != 0)
{
- var bytesToCopy = Math.Min(count, copyLength);
+ if (bytesRead == 0)
+ {
+ break;
+ }
+
+ var bytesToCopy = Math.Min(bytesRead, copyLength);
await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToCopy)).ConfigureAwait(false);
diff --git a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
index 6d9d7d921..57eef5db0 100644
--- a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
+++ b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
@@ -26,8 +26,8 @@ namespace Emby.Server.Implementations.HttpServer
public void FilterResponse(IRequest req, IResponse res, object dto)
{
// Try to prevent compatibility view
- res.AddHeader("X-UA-Compatible", "IE=Edge");
- res.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization");
+ //res.AddHeader("X-UA-Compatible", "IE=Edge");
+ res.AddHeader("Access-Control-Allow-Headers", "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Authorization");
res.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
res.AddHeader("Access-Control-Allow-Origin", "*");
@@ -46,8 +46,6 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- var vary = "Accept-Encoding";
-
var hasHeaders = dto as IHasHeaders;
var sharpResponse = res as WebSocketSharpResponse;
@@ -86,23 +84,9 @@ namespace Emby.Server.Implementations.HttpServer
}
}
}
-
- string hasHeadersVary;
- if (hasHeaders.Headers.TryGetValue("Vary", out hasHeadersVary))
- {
- vary = hasHeadersVary;
- }
-
- hasHeaders.Headers["Vary"] = vary;
}
//res.KeepAlive = false;
-
- // Per Google PageSpeed
- // This instructs the proxies to cache two versions of the resource: one compressed, and one uncompressed.
- // The correct version of the resource is delivered based on the client request header.
- // This is a good choice for applications that are singly homed and depend on public proxies for user locality.
- res.AddHeader("Vary", vary);
}
/// <summary>
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
index cf37366fb..bdab8552a 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
@@ -57,7 +57,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
{
episode.SeriesId = series.Id;
episode.SeriesName = series.Name;
- episode.SeriesSortName = series.SortName;
}
if (season != null)
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
index c065feda1..84ceac65e 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
@@ -44,7 +44,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
{
IndexNumber = new SeasonPathParser(namingOptions, new RegexProvider()).Parse(args.Path, true, true).SeasonNumber,
SeriesId = series.Id,
- SeriesSortName = series.SortName,
SeriesName = series.Name
};
diff --git a/Emby.Server.Implementations/Security/PluginSecurityManager.cs b/Emby.Server.Implementations/Security/PluginSecurityManager.cs
index d42fae3ad..7cd0a8d5f 100644
--- a/Emby.Server.Implementations/Security/PluginSecurityManager.cs
+++ b/Emby.Server.Implementations/Security/PluginSecurityManager.cs
@@ -101,6 +101,12 @@ namespace Emby.Server.Implementations.Security
/// <returns></returns>
public async Task LoadAllRegistrationInfo()
{
+ var response = await _httpClient.GetResponse(new HttpRequestOptions
+ {
+ Url = "http://192.168.1.2:8096/emby/Videos/663c8a38ccfe91af6566852f78e62c26/stream.mkv?Static=true&mediaSourceId=663c8a38ccfe91af6566852f78e62c26&deviceId=hyJA92oXn4RExFTGismCnY6da91kwnTvv8YvsYf0E&Tag=bcdc02b1cdd6f1eb4a57a6812831617b"
+
+ }).ConfigureAwait(false);
+
var tasks = new List<Task>();
ResetSupporterInfo();
diff --git a/Emby.Server.Implementations/Session/HttpSessionController.cs b/Emby.Server.Implementations/Session/HttpSessionController.cs
index cea5d9b40..2acc3902f 100644
--- a/Emby.Server.Implementations/Session/HttpSessionController.cs
+++ b/Emby.Server.Implementations/Session/HttpSessionController.cs
@@ -129,7 +129,7 @@ namespace Emby.Server.Implementations.Session
public Task SendLibraryUpdateInfo(LibraryUpdateInfo info, CancellationToken cancellationToken)
{
- return Task.FromResult(true);
+ return SendMessage("LibraryChanged", info, cancellationToken);
}
public Task SendRestartRequiredNotification(SystemInfo info, CancellationToken cancellationToken)
diff --git a/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs b/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs
index b315d33c3..b441a29c1 100644
--- a/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs
+++ b/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs
@@ -22,7 +22,7 @@ namespace Emby.Server.Implementations.Sorting
{
var hasSeries = item as IHasSeries;
- return hasSeries != null ? hasSeries.SeriesSortName : null;
+ return hasSeries != null ? hasSeries.FindSeriesSortName() : null;
}
/// <summary>
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index a92cf164a..daec00e10 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -675,7 +675,8 @@ namespace MediaBrowser.Api.Playback
{
Request = request,
RequestedUrl = url,
- UserAgent = Request.UserAgent
+ UserAgent = Request.UserAgent,
+ EnableDlnaHeaders = !string.IsNullOrWhiteSpace(request.Params)
};
var auth = AuthorizationContext.GetAuthorizationInfo(Request);
@@ -917,6 +918,11 @@ namespace MediaBrowser.Api.Playback
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
protected void AddDlnaHeaders(StreamState state, IDictionary<string, string> responseHeaders, bool isStaticallyStreamed)
{
+ if (!state.EnableDlnaHeaders)
+ {
+ return;
+ }
+
var profile = state.DeviceProfile;
var transferMode = GetHeader("transferMode.dlna.org");
diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs
index 7f146466d..4b1687d68 100644
--- a/MediaBrowser.Api/Playback/StreamState.cs
+++ b/MediaBrowser.Api/Playback/StreamState.cs
@@ -138,6 +138,8 @@ namespace MediaBrowser.Api.Playback
return MimeTypes.GetMimeType(outputPath);
}
+ public bool EnableDlnaHeaders { get; set; }
+
public void Dispose()
{
DisposeTranscodingThrottler();
diff --git a/MediaBrowser.Controller/Entities/AudioBook.cs b/MediaBrowser.Controller/Entities/AudioBook.cs
index 8b1c338f1..1bdcfb881 100644
--- a/MediaBrowser.Controller/Entities/AudioBook.cs
+++ b/MediaBrowser.Controller/Entities/AudioBook.cs
@@ -31,12 +31,10 @@ namespace MediaBrowser.Controller.Entities
public string SeriesName { get; set; }
[IgnoreDataMember]
public Guid? SeriesId { get; set; }
- [IgnoreDataMember]
- public string SeriesSortName { get; set; }
public string FindSeriesSortName()
{
- return SeriesSortName;
+ return SeriesName;
}
public string FindSeriesName()
{
diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs
index a6da389f0..7cb242589 100644
--- a/MediaBrowser.Controller/Entities/Book.cs
+++ b/MediaBrowser.Controller/Entities/Book.cs
@@ -24,12 +24,10 @@ namespace MediaBrowser.Controller.Entities
public string SeriesName { get; set; }
[IgnoreDataMember]
public Guid? SeriesId { get; set; }
- [IgnoreDataMember]
- public string SeriesSortName { get; set; }
public string FindSeriesSortName()
{
- return SeriesSortName;
+ return SeriesName;
}
public string FindSeriesName()
{
diff --git a/MediaBrowser.Controller/Entities/IHasSeries.cs b/MediaBrowser.Controller/Entities/IHasSeries.cs
index 203be93e8..20efdc2b8 100644
--- a/MediaBrowser.Controller/Entities/IHasSeries.cs
+++ b/MediaBrowser.Controller/Entities/IHasSeries.cs
@@ -11,7 +11,6 @@ namespace MediaBrowser.Controller.Entities
/// <value>The name of the series.</value>
string SeriesName { get; set; }
string FindSeriesName();
- string SeriesSortName { get; set; }
string FindSeriesSortName();
Guid? SeriesId { get; set; }
Guid? FindSeriesId();
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index 31bf8d28b..c2f7a6168 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -57,13 +57,10 @@ namespace MediaBrowser.Controller.Entities.TV
/// <value>The index number.</value>
public int? IndexNumberEnd { get; set; }
- [IgnoreDataMember]
- public string SeriesSortName { get; set; }
-
public string FindSeriesSortName()
{
var series = Series;
- return series == null ? SeriesSortName : series.SortName;
+ return series == null ? SeriesName : series.SortName;
}
[IgnoreDataMember]
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index 6c97a32a0..ed04b5ddc 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -51,9 +51,6 @@ namespace MediaBrowser.Controller.Entities.TV
get { return SeriesId; }
}
- [IgnoreDataMember]
- public string SeriesSortName { get; set; }
-
public override double? GetDefaultPrimaryImageAspectRatio()
{
double value = 2;
@@ -65,7 +62,7 @@ namespace MediaBrowser.Controller.Entities.TV
public string FindSeriesSortName()
{
var series = Series;
- return series == null ? SeriesSortName : series.SortName;
+ return series == null ? SeriesName : series.SortName;
}
// Genre, Rating and Stuido will all be the same
diff --git a/MediaBrowser.Providers/TV/DummySeasonProvider.cs b/MediaBrowser.Providers/TV/DummySeasonProvider.cs
index 36701a0bd..279447a18 100644
--- a/MediaBrowser.Providers/TV/DummySeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/DummySeasonProvider.cs
@@ -125,8 +125,7 @@ namespace MediaBrowser.Providers.TV
Id = _libraryManager.GetNewItemId((series.Id + (seasonNumber ?? -1).ToString(_usCulture) + seasonName), typeof(Season)),
IsVirtualItem = isVirtualItem,
SeriesId = series.Id,
- SeriesName = series.Name,
- SeriesSortName = series.SortName
+ SeriesName = series.Name
};
season.SetParent(series);
diff --git a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs
index 538d96c17..bef4d8815 100644
--- a/MediaBrowser.Providers/TV/EpisodeMetadataService.cs
+++ b/MediaBrowser.Providers/TV/EpisodeMetadataService.cs
@@ -27,13 +27,6 @@ namespace MediaBrowser.Providers.TV
updateType |= ItemUpdateType.MetadataImport;
}
- var seriesSortName = item.FindSeriesSortName();
- if (!string.Equals(item.SeriesSortName, seriesSortName, StringComparison.Ordinal))
- {
- item.SeriesSortName = seriesSortName;
- updateType |= ItemUpdateType.MetadataImport;
- }
-
var seasonName = item.FindSeasonName();
if (!string.Equals(item.SeasonName, seasonName, StringComparison.Ordinal))
{
diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs
index af7dea59e..74c8b4ec3 100644
--- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs
+++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs
@@ -44,13 +44,6 @@ namespace MediaBrowser.Providers.TV
updateType |= ItemUpdateType.MetadataImport;
}
- var seriesSortName = item.FindSeriesSortName();
- if (!string.Equals(item.SeriesSortName, seriesSortName, StringComparison.Ordinal))
- {
- item.SeriesSortName = seriesSortName;
- updateType |= ItemUpdateType.MetadataImport;
- }
-
var seriesPresentationUniqueKey = item.FindSeriesPresentationUniqueKey();
if (!string.Equals(item.SeriesPresentationUniqueKey, seriesPresentationUniqueKey, StringComparison.Ordinal))
{
diff --git a/SocketHttpListener.Portable/Net/HttpListenerResponse.cs b/SocketHttpListener.Portable/Net/HttpListenerResponse.cs
index d9f91c0cc..3cb6a0d75 100644
--- a/SocketHttpListener.Portable/Net/HttpListenerResponse.cs
+++ b/SocketHttpListener.Portable/Net/HttpListenerResponse.cs
@@ -480,6 +480,8 @@ namespace SocketHttpListener.Net
headers.SetInternal("Set-Cookie", cookie.ToString());
}
+ headers.SetInternal("Status", status_code.ToString(CultureInfo.InvariantCulture));
+
using (StreamWriter writer = new StreamWriter(ms, encoding, 256, true))
{
writer.Write("HTTP/{0} {1} {2}\r\n", version, status_code, status_description);
diff --git a/SocketHttpListener.Portable/Net/ResponseStream.cs b/SocketHttpListener.Portable/Net/ResponseStream.cs
index 71d081046..dea4049d5 100644
--- a/SocketHttpListener.Portable/Net/ResponseStream.cs
+++ b/SocketHttpListener.Portable/Net/ResponseStream.cs
@@ -344,13 +344,6 @@ namespace SocketHttpListener.Net
private async Task TransmitFileManaged(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
{
- var chunked = response.SendChunked;
-
- if (!chunked)
- {
- await WriteAsync(_emptyBuffer, 0, 0, cancellationToken).ConfigureAwait(false);
- }
-
using (var fs = _fileSystem.GetFileStream(path, FileOpenMode.Open, FileAccessMode.Read, fileShareMode, true))
{
if (offset > 0)
@@ -358,7 +351,7 @@ namespace SocketHttpListener.Net
fs.Position = offset;
}
- var targetStream = chunked ? this : stream;
+ var targetStream = this;
if (count > 0)
{
@@ -374,14 +367,23 @@ namespace SocketHttpListener.Net
private static async Task CopyToInternalAsync(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken)
{
var array = new byte[81920];
- int count;
- while ((count = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0)
+ int bytesRead;
+
+ while ((bytesRead = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0)
{
- var bytesToCopy = Math.Min(count, copyLength);
+ if (bytesRead == 0)
+ {
+ break;
+ }
+
+ var bytesToWrite = Math.Min(bytesRead, copyLength);
- await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToCopy), cancellationToken).ConfigureAwait(false);
+ if (bytesToWrite > 0)
+ {
+ await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false);
+ }
- copyLength -= bytesToCopy;
+ copyLength -= bytesToWrite;
if (copyLength <= 0)
{