Skip to content

Commit

Permalink
Merge PR #390: Override Ensure GZipOutputStream headers are written b…
Browse files Browse the repository at this point in the history
…efore flush

* Add unit tests to repro #382
* Add an override of Flush() to GZipOutputStream to ensure the headers is writen before flushing
  • Loading branch information
Numpsy authored Jun 19, 2020
1 parent 73aa23a commit 1a130a0
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/ICSharpCode.SharpZipLib/GZip/GzipOutputStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,20 @@ protected override void Dispose(bool disposing)
}
}

/// <summary>
/// Flushes the stream by ensuring the header is written, and then calling <see cref="DeflaterOutputStream.Flush">Flush</see>
/// on the deflater.
/// </summary>
public override void Flush()
{
if (state_ == OutputState.Header)
{
WriteHeader();
}

base.Flush();
}

#endregion Stream overrides

#region DeflaterOutputStream overrides
Expand Down
63 changes: 63 additions & 0 deletions test/ICSharpCode.SharpZipLib.Tests/GZip/GZipTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,37 @@ public void DelayedHeaderWriteNoData()
Assert.IsTrue(data.Length > 0);
}


/// <summary>
/// Variant of DelayedHeaderWriteNoData testing flushing for https://github.com/icsharpcode/SharpZipLib/issues/382
/// </summary>
[Test]
[Category("GZip")]
public void DelayedHeaderWriteFlushNoData()
{
var ms = new MemoryStream();
Assert.AreEqual(0, ms.Length);

using (GZipOutputStream outStream = new GZipOutputStream(ms) { IsStreamOwner = false })
{
// #382 - test flushing the stream before writing to it.
outStream.Flush();
}

ms.Seek(0, SeekOrigin.Begin);

// Test that the gzip stream can be read
var readStream = new MemoryStream();
using (GZipInputStream inStream = new GZipInputStream(ms))
{
inStream.CopyTo(readStream);
}

byte[] data = readStream.ToArray();

Assert.That(data, Is.Empty, "Should not have any decompressed data");
}

/// <summary>
/// Writing GZip headers is delayed so that this stream can be used with HTTP/IIS.
/// </summary>
Expand All @@ -99,6 +130,38 @@ public void DelayedHeaderWriteWithData()
Assert.IsTrue(data.Length > 0);
}

/// <summary>
/// variant of DelayedHeaderWriteWithData to test https://github.com/icsharpcode/SharpZipLib/issues/382
/// </summary>
[Test]
[Category("GZip")]
public void DelayedHeaderWriteFlushWithData()
{
var ms = new MemoryStream();
Assert.AreEqual(0, ms.Length);
using (GZipOutputStream outStream = new GZipOutputStream(ms) { IsStreamOwner = false })
{
Assert.AreEqual(0, ms.Length);

// #382 - test flushing the stream before writing to it.
outStream.Flush();
outStream.WriteByte(45);
}

ms.Seek(0, SeekOrigin.Begin);

// Test that the gzip stream can be read
var readStream = new MemoryStream();
using (GZipInputStream inStream = new GZipInputStream(ms))
{
inStream.CopyTo(readStream);
}

// Check that the data was read
byte[] data = readStream.ToArray();
CollectionAssert.AreEqual(new byte[] { 45 }, data, "Decompressed data should match initial data");
}

[Test]
[Category("GZip")]
public void ZeroLengthInputStream()
Expand Down

0 comments on commit 1a130a0

Please sign in to comment.