This repository was archived by the owner on Nov 22, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 39
Implement Http cache #15
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,14 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
|
||
namespace Microsoft.AspNetCore.ResponseCaching | ||
{ | ||
public interface IResponseCache | ||
{ | ||
object Get(string key); | ||
// TODO: Set expiry policy in the underlying cache? | ||
void Set(string key, object entry); | ||
void Set(string key, object entry, TimeSpan validFor); | ||
void Remove(string key); | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
src/Microsoft.AspNetCore.ResponseCaching/Internal/CachedResponse.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
src/Microsoft.AspNetCore.ResponseCaching/Internal/ISystemClock.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
|
||
namespace Microsoft.AspNetCore.ResponseCaching.Internal | ||
{ | ||
/// <summary> | ||
/// Abstracts the system clock to facilitate testing. | ||
/// </summary> | ||
internal interface ISystemClock | ||
{ | ||
/// <summary> | ||
/// Retrieves the current system time in UTC. | ||
/// </summary> | ||
DateTimeOffset UtcNow { get; } | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
164 changes: 164 additions & 0 deletions
164
src/Microsoft.AspNetCore.ResponseCaching/Internal/ResponseCacheStream.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.IO; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace Microsoft.AspNetCore.ResponseCaching.Internal | ||
{ | ||
internal class ResponseCacheStream : Stream | ||
{ | ||
private readonly Stream _innerStream; | ||
|
||
public ResponseCacheStream(Stream innerStream) | ||
{ | ||
_innerStream = innerStream; | ||
} | ||
|
||
public MemoryStream BufferedStream { get; } = new MemoryStream(); | ||
|
||
public bool BufferingEnabled { get; set; } = true; | ||
|
||
public override bool CanRead => _innerStream.CanRead; | ||
|
||
public override bool CanSeek => _innerStream.CanSeek; | ||
|
||
public override bool CanWrite => _innerStream.CanWrite; | ||
|
||
public override long Length => _innerStream.Length; | ||
|
||
public override long Position | ||
{ | ||
get { return _innerStream.Position; } | ||
set { _innerStream.Position = value; } | ||
} | ||
|
||
public void DisableBuffering() | ||
{ | ||
BufferingEnabled = false; | ||
BufferedStream.Dispose(); | ||
} | ||
|
||
public override void SetLength(long value) | ||
{ | ||
DisableBuffering(); | ||
_innerStream.SetLength(value); | ||
} | ||
|
||
public override long Seek(long offset, SeekOrigin origin) | ||
{ | ||
DisableBuffering(); | ||
return _innerStream.Seek(offset, origin); | ||
} | ||
|
||
public override void Flush() | ||
=> _innerStream.Flush(); | ||
|
||
public override Task FlushAsync(CancellationToken cancellationToken) | ||
=> _innerStream.FlushAsync(); | ||
|
||
// Underlying stream is write-only, no need to override other read related methods | ||
public override int Read(byte[] buffer, int offset, int count) | ||
=> _innerStream.Read(buffer, offset, count); | ||
|
||
public override void Write(byte[] buffer, int offset, int count) | ||
{ | ||
try | ||
{ | ||
_innerStream.Write(buffer, offset, count); | ||
} | ||
catch | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These try/catch's only need to be around the _innerStream operations. |
||
{ | ||
DisableBuffering(); | ||
throw; | ||
} | ||
|
||
if (BufferingEnabled) | ||
{ | ||
BufferedStream.Write(buffer, offset, count); | ||
} | ||
} | ||
|
||
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You must override Begin/End Write as well, #if net451. |
||
{ | ||
try | ||
{ | ||
await _innerStream.WriteAsync(buffer, offset, count, cancellationToken); | ||
} | ||
catch | ||
{ | ||
DisableBuffering(); | ||
throw; | ||
} | ||
|
||
if (BufferingEnabled) | ||
{ | ||
await BufferedStream.WriteAsync(buffer, offset, count, cancellationToken); | ||
} | ||
} | ||
|
||
public override void WriteByte(byte value) | ||
{ | ||
try | ||
{ | ||
_innerStream.WriteByte(value); | ||
} | ||
catch | ||
{ | ||
DisableBuffering(); | ||
throw; | ||
} | ||
|
||
if (BufferingEnabled) | ||
{ | ||
BufferedStream.WriteByte(value); | ||
} | ||
} | ||
|
||
#if NETSTANDARD1_3 | ||
public IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) | ||
#else | ||
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) | ||
#endif | ||
{ | ||
return ToIAsyncResult(WriteAsync(buffer, offset, count), callback, state); | ||
} | ||
#if NETSTANDARD1_3 | ||
public void EndWrite(IAsyncResult asyncResult) | ||
#else | ||
public override void EndWrite(IAsyncResult asyncResult) | ||
#endif | ||
{ | ||
if (asyncResult == null) | ||
{ | ||
throw new ArgumentNullException(nameof(asyncResult)); | ||
} | ||
((Task)asyncResult).GetAwaiter().GetResult(); | ||
} | ||
|
||
private static IAsyncResult ToIAsyncResult(Task task, AsyncCallback callback, object state) | ||
{ | ||
var tcs = new TaskCompletionSource<int>(state); | ||
task.ContinueWith(t => | ||
{ | ||
if (t.IsFaulted) | ||
{ | ||
tcs.TrySetException(t.Exception.InnerExceptions); | ||
} | ||
else if (t.IsCanceled) | ||
{ | ||
tcs.TrySetCanceled(); | ||
} | ||
else | ||
{ | ||
tcs.TrySetResult(0); | ||
} | ||
|
||
callback?.Invoke(tcs.Task); | ||
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default); | ||
return tcs.Task; | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/Microsoft.AspNetCore.ResponseCaching/Internal/SendFileFeatureWrapper.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Http.Features; | ||
|
||
namespace Microsoft.AspNetCore.ResponseCaching.Internal | ||
{ | ||
internal class SendFileFeatureWrapper : IHttpSendFileFeature | ||
{ | ||
private readonly IHttpSendFileFeature _originalSendFileFeature; | ||
private readonly ResponseCacheStream _responseCacheStream; | ||
|
||
public SendFileFeatureWrapper(IHttpSendFileFeature originalSendFileFeature, ResponseCacheStream responseCacheStream) | ||
{ | ||
_originalSendFileFeature = originalSendFileFeature; | ||
_responseCacheStream = responseCacheStream; | ||
} | ||
|
||
// Flush and disable the buffer if anyone tries to call the SendFile feature. | ||
public Task SendFileAsync(string path, long offset, long? length, CancellationToken cancellation) | ||
{ | ||
_responseCacheStream.DisableBuffering(); | ||
return _originalSendFileFeature.SendFileAsync(path, offset, length, cancellation); | ||
} | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/Microsoft.AspNetCore.ResponseCaching/Internal/SystemClock.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
|
||
namespace Microsoft.AspNetCore.ResponseCaching.Internal | ||
{ | ||
/// <summary> | ||
/// Provides access to the normal system clock. | ||
/// </summary> | ||
internal class SystemClock : ISystemClock | ||
{ | ||
/// <summary> | ||
/// Retrieves the current system time in UTC. | ||
/// </summary> | ||
public DateTimeOffset UtcNow | ||
{ | ||
get | ||
{ | ||
return DateTimeOffset.UtcNow; | ||
} | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might need a context object here. What other things will we need to pass?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do we need in the context object? Should we add that when we actually need it?