Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

Commit 15687ab

Browse files
committed
Fix #343 - Avoid going to disk when reading the form
This change tries to avoid looking up the TEMP directory for most reads of the form data. We'll now only hit the disk when necessary.
1 parent 516a435 commit 15687ab

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

src/Microsoft.AspNet.Http/BufferingHelper.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,30 @@ public static class BufferingHelper
1212
{
1313
internal const int DefaultBufferThreshold = 1024 * 30;
1414

15+
private readonly static Func<string> _getTempDirectory = () => TempDirectory;
16+
17+
private static string _tempDirectory;
18+
1519
public static string TempDirectory
1620
{
1721
get
1822
{
19-
// Look for folders in the following order.
20-
var temp = Environment.GetEnvironmentVariable("ASPNET_TEMP") ?? // ASPNET_TEMP - User set temporary location.
21-
Path.GetTempPath(); // Fall back.
22-
23-
if (!Directory.Exists(temp))
23+
if (_tempDirectory == null)
2424
{
25-
// TODO: ???
26-
throw new DirectoryNotFoundException(temp);
25+
// Look for folders in the following order.
26+
var temp = Environment.GetEnvironmentVariable("ASPNET_TEMP") ?? // ASPNET_TEMP - User set temporary location.
27+
Path.GetTempPath(); // Fall back.
28+
29+
if (!Directory.Exists(temp))
30+
{
31+
// TODO: ???
32+
throw new DirectoryNotFoundException(temp);
33+
}
34+
35+
_tempDirectory = temp;
2736
}
2837

29-
return temp;
38+
return _tempDirectory;
3039
}
3140
}
3241

@@ -37,7 +46,7 @@ public static HttpRequest EnableRewind([NotNull] this HttpRequest request, int b
3746
{
3847
// TODO: Register this buffer for disposal at the end of the request to ensure the temp file is deleted.
3948
// Otherwise it won't get deleted until GC closes the stream.
40-
request.Body = new FileBufferingReadStream(body, bufferThreshold, TempDirectory);
49+
request.Body = new FileBufferingReadStream(body, bufferThreshold, _getTempDirectory);
4150
}
4251
return request;
4352
}

src/Microsoft.AspNet.WebUtilities/FileBufferingReadStream.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Diagnostics;
56
using System.IO;
67
using System.Threading;
78
using System.Threading.Tasks;
@@ -18,14 +19,26 @@ public class FileBufferingReadStream : Stream
1819
{
1920
private readonly Stream _inner;
2021
private readonly int _memoryThreshold;
21-
private readonly string _tempFileDirectory;
22+
private string _tempFileDirectory;
23+
private readonly Func<string> _tempFileDirectoryAccessor;
2224

2325
private Stream _buffer = new MemoryStream(); // TODO: We could have a more efficiently expanding buffer stream.
2426
private bool _inMemory = true;
2527
private bool _completelyBuffered;
2628

2729
private bool _disposed;
2830

31+
// TODO: allow for an optional buffer size limit to prevent filling hard disks. 1gb?
32+
public FileBufferingReadStream(
33+
[NotNull] Stream inner,
34+
int memoryThreshold,
35+
[NotNull] Func<string> tempFileDirectoryAccessor)
36+
{
37+
_inner = inner;
38+
_memoryThreshold = memoryThreshold;
39+
_tempFileDirectoryAccessor = tempFileDirectoryAccessor;
40+
}
41+
2942
// TODO: allow for an optional buffer size limit to prevent filling hard disks. 1gb?
3043
public FileBufferingReadStream([NotNull] Stream inner, int memoryThreshold, [NotNull] string tempFileDirectory)
3144
{
@@ -88,6 +101,13 @@ public override long Seek(long offset, SeekOrigin origin)
88101

89102
private Stream CreateTempFile()
90103
{
104+
if (_tempFileDirectory == null)
105+
{
106+
Debug.Assert(_tempFileDirectoryAccessor != null);
107+
_tempFileDirectory = _tempFileDirectoryAccessor();
108+
Debug.Assert(_tempFileDirectory != null);
109+
}
110+
91111
var fileName = Path.Combine(_tempFileDirectory, "ASPNET_" + Guid.NewGuid().ToString() + ".tmp");
92112
return new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Delete, 1024 * 16,
93113
FileOptions.Asynchronous | FileOptions.DeleteOnClose | FileOptions.SequentialScan);

0 commit comments

Comments
 (0)