Changed output cache storage from string to byte[] to fix encoding issues with binary content.

This commit is contained in:
Daniel Stolt
2015-03-19 21:03:00 +01:00
parent fbf39acac6
commit adf8ba85da
5 changed files with 22 additions and 20 deletions

View File

@@ -16,7 +16,7 @@ namespace Contrib.Cache.Database {
.Column<int>("GraceTime", c => c.Nullable())
.Column<DateTime>("ValidUntilUtc")
.Column<DateTime>("StoredUntilUtc")
.Column<string>("Output", column => column.Unlimited())
.Column<byte[]>("Output", column => column.Unlimited().WithType(DbType.Binary))
.Column<string>("ContentType")
.Column<string>("QueryString", column => column.WithLength(2048))
.Column<string>("CacheKey", column => column.WithLength(2048))
@@ -31,7 +31,7 @@ namespace Contrib.Cache.Database {
.CreateIndex("IDX_CacheItemRecord_CacheKey", "CacheKey")
);
return 2;
return 3;
}
public int UpdateFrom1() {
@@ -45,5 +45,14 @@ namespace Contrib.Cache.Database {
return 2;
}
public int UpdateFrom2() {
SchemaBuilder.AlterTable("CacheItemRecord",
table => {
table.AlterColumn("Output", c => c.Unlimited().WithType(DbType.Binary));
});
return 3;
}
}
}

View File

@@ -7,14 +7,12 @@ using System.Web;
namespace Orchard.OutputCache.Filters {
public class CaptureStream : Stream {
public CaptureStream(Stream innerStream, Encoding encoding) {
public CaptureStream(Stream innerStream) {
_innerStream = innerStream;
_encoding = encoding;
_captureStream = new MemoryStream();
}
private readonly Stream _innerStream;
private readonly Encoding _encoding;
private readonly MemoryStream _captureStream;
public override bool CanRead {
@@ -64,15 +62,14 @@ namespace Orchard.OutputCache.Filters {
}
public override void Write(byte[] buffer, int offset, int count) {
_captureStream.Write(buffer, 0, count);
_innerStream.Write(buffer, offset, buffer.Length);
_captureStream.Write(buffer, offset, count);
_innerStream.Write(buffer, offset, count);
}
public event Action<string> Captured;
public event Action<byte[]> Captured;
protected virtual void OnCaptured() {
var content = _encoding.GetString(_captureStream.ToArray());
Captured(content);
Captured(_captureStream.ToArray());
}
}
}

View File

@@ -197,15 +197,15 @@ namespace Orchard.OutputCache.Filters {
// Capture the response output using a custom filter stream.
var response = filterContext.HttpContext.Response;
var captureStream = new CaptureStream(response.Filter, response.Output.Encoding);
var captureStream = new CaptureStream(response.Filter);
response.Filter = captureStream;
captureStream.Captured += (content) => {
captureStream.Captured += (output) => {
try {
var cacheItem = new CacheItem() {
CachedOnUtc = _now,
Duration = cacheDuration,
GraceTime = cacheGraceTime,
Output = content,
Output = output,
ContentType = response.ContentType,
QueryString = filterContext.HttpContext.Request.Url.Query,
CacheKey = _cacheKey,
@@ -439,7 +439,6 @@ namespace Orchard.OutputCache.Filters {
private void ServeCachedItem(ActionExecutingContext filterContext, CacheItem cacheItem) {
var response = filterContext.HttpContext.Response;
var output = cacheItem.Output;
// Adds some caching information to the output if requested.
if (CacheSettings.DebugMode) {
@@ -448,10 +447,7 @@ namespace Orchard.OutputCache.Filters {
}
// Shorcut action execution.
filterContext.Result = new ContentResult {
Content = output,
ContentType = cacheItem.ContentType
};
filterContext.Result = new FileContentResult(cacheItem.Output, cacheItem.ContentType);
response.StatusCode = cacheItem.StatusCode;

View File

@@ -6,7 +6,7 @@ namespace Orchard.OutputCache.Models {
public DateTime CachedOnUtc { get; set; }
public int Duration { get; set; }
public int GraceTime { get; set; }
public string Output { get; set; }
public byte[] Output { get; set; }
public string ContentType { get; set; }
public string QueryString { get; set; }
public string CacheKey { get; set; }

View File

@@ -12,7 +12,7 @@ namespace Orchard.OutputCache.Models {
public virtual int GraceTime { get; set; }
public virtual DateTime ValidUntilUtc { get; set; }
public virtual DateTime StoredUntilUtc { get; set; }
[StringLengthMax] public virtual string Output { get; set; }
public virtual byte[] Output { get; set; }
public virtual string ContentType { get; set; }
[StringLength(2048)] public virtual string QueryString { get; set; }
[StringLength(2048)] public virtual string CacheKey { get; set; }