[PR #987] [MERGED] Fix GZip extraction NotSupportedException for non-seekable streams #1406

Closed
opened 2026-01-29 22:20:24 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/adamhathcock/sharpcompress/pull/987
Author: @Copilot
Created: 10/27/2025
Status: Merged
Merged: 10/27/2025
Merged by: @adamhathcock

Base: masterHead: copilot/fix-gzip-extract-not-supported-exception


📝 Commits (6)

  • cf55125 Initial plan
  • 51e22ce Initial plan for fixing GZip non-seekable stream support
  • 4067b6e Fix GZip extraction for non-seekable streams
  • 1a76710 Add explanatory comment for EntryStartPosition initialization
  • 9ebbc71 Merge branch 'master' into copilot/fix-gzip-extract-not-supported-exception
  • c550600 Merge branch 'master' into copilot/fix-gzip-extract-not-supported-exception

📊 Changes

3 files changed (+67 additions, -3 deletions)

View changed files

📝 src/SharpCompress/Archives/GZip/GZipArchiveEntry.cs (+3 -2)
📝 src/SharpCompress/Common/GZip/GZipFilePart.cs (+7 -1)
📝 tests/SharpCompress.Test/GZip/GZipArchiveTests.cs (+57 -0)

📄 Description

GZip decompression fails when reading from non-seekable streams (e.g., HttpClient.GetStreamAsync()) because GZipFilePart unconditionally accesses stream.Position, which throws NotSupportedException on HTTP streams.

Changes

  • GZipFilePart.cs: Check stream.CanSeek before accessing Position. Set EntryStartPosition = 0 for non-seekable streams since they read sequentially from current position.

  • GZipArchiveEntry.cs: Check CanSeek before attempting position reset in OpenEntryStream().

  • Test coverage: Added GZip_Archive_NonSeekableStream test using a NonSeekableStream wrapper to verify the fix.

Usage

// Now works with HTTP streams
using var httpStream = await httpClient.GetStreamAsync(gzipUrl);
using var reader = GZipReader.Open(httpStream);
while (reader.MoveToNextEntry())
{
    reader.WriteEntryTo(outputStream);
}

Note: GZipReader supports non-seekable streams. GZipArchive.Open() continues to require seekable streams by design.

Original prompt

This section details on the original issue you should resolve

<issue_title>HttpBaseStream Gzip extract - NotSupportedException</issue_title>
<issue_description>Hi, looks like when trying to decompress a gzip through httpStream it throws NotSupportedException on Position when setting EntryStartPosition. what is the purpose of settings this field? how can i mitigate the problem? Thanks!

System.NotSupportedException: Specified method is not supported.
   at System.Net.Http.HttpBaseStream.get_Position()
   at SharpCompress.IO.RewindableStream.get_Position()
   at SharpCompress.Common.GZip.GZipFilePart..ctor(Stream stream, ArchiveEncoding archiveEncoding)
   at SharpCompress.Common.GZip.GZipEntry.GetEntries(Stream stream, OptionsBase options)+MoveNext()

P.S i'd prefer to not save the file to disk and read it again as FileStream if possible
If that's not possible which types require random access? i know that .tar.gz works perfectly fine through http for example, Thanks in advance!</issue_description>

Comments on the Issue (you are @copilot in this section)

@adamhathcock You'll have to show me how you're calling things.

GZipFilePart does check CanSeek but Rewindable is meant to buffer unbufferable streams so shouldn't be used here.</comment_new>
<comment_new>@adamhathcock
Actually, I take that back, GZipFilePart has a usage of Position no matter seeking. That should be changed</comment_new>
<comment_new>@adamhathcock
you're right but I'm not sure why I'm doing that....I'd have to look and remember</comment_new>


Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/adamhathcock/sharpcompress/pull/987 **Author:** [@Copilot](https://github.com/apps/copilot-swe-agent) **Created:** 10/27/2025 **Status:** ✅ Merged **Merged:** 10/27/2025 **Merged by:** [@adamhathcock](https://github.com/adamhathcock) **Base:** `master` ← **Head:** `copilot/fix-gzip-extract-not-supported-exception` --- ### 📝 Commits (6) - [`cf55125`](https://github.com/adamhathcock/sharpcompress/commit/cf5512520242a1f5a5bf4b75b1b3fd633f96bc6b) Initial plan - [`51e22ce`](https://github.com/adamhathcock/sharpcompress/commit/51e22cea71e38c33dd61bcd1f8b9b964032322b6) Initial plan for fixing GZip non-seekable stream support - [`4067b6e`](https://github.com/adamhathcock/sharpcompress/commit/4067b6ed2c8284dc4d4467dca7bfc0bcb3d84a67) Fix GZip extraction for non-seekable streams - [`1a76710`](https://github.com/adamhathcock/sharpcompress/commit/1a767105e6cd95dd7ae2e3ca2c3bb2612b05c5a5) Add explanatory comment for EntryStartPosition initialization - [`9ebbc71`](https://github.com/adamhathcock/sharpcompress/commit/9ebbc718c5798ed4f8ddea1a3b7bd3b96451acf8) Merge branch 'master' into copilot/fix-gzip-extract-not-supported-exception - [`c550600`](https://github.com/adamhathcock/sharpcompress/commit/c55060039a336b26486ebfc6d6cb3f660ac87347) Merge branch 'master' into copilot/fix-gzip-extract-not-supported-exception ### 📊 Changes **3 files changed** (+67 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `src/SharpCompress/Archives/GZip/GZipArchiveEntry.cs` (+3 -2) 📝 `src/SharpCompress/Common/GZip/GZipFilePart.cs` (+7 -1) 📝 `tests/SharpCompress.Test/GZip/GZipArchiveTests.cs` (+57 -0) </details> ### 📄 Description GZip decompression fails when reading from non-seekable streams (e.g., `HttpClient.GetStreamAsync()`) because `GZipFilePart` unconditionally accesses `stream.Position`, which throws `NotSupportedException` on HTTP streams. ## Changes - **GZipFilePart.cs**: Check `stream.CanSeek` before accessing `Position`. Set `EntryStartPosition = 0` for non-seekable streams since they read sequentially from current position. - **GZipArchiveEntry.cs**: Check `CanSeek` before attempting position reset in `OpenEntryStream()`. - **Test coverage**: Added `GZip_Archive_NonSeekableStream` test using a `NonSeekableStream` wrapper to verify the fix. ## Usage ```csharp // Now works with HTTP streams using var httpStream = await httpClient.GetStreamAsync(gzipUrl); using var reader = GZipReader.Open(httpStream); while (reader.MoveToNextEntry()) { reader.WriteEntryTo(outputStream); } ``` Note: `GZipReader` supports non-seekable streams. `GZipArchive.Open()` continues to require seekable streams by design. <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>HttpBaseStream Gzip extract - NotSupportedException</issue_title> > <issue_description>Hi, looks like when trying to decompress a gzip through httpStream it throws NotSupportedException on Position when setting EntryStartPosition. what is the purpose of settings this field? how can i mitigate the problem? Thanks! > > ``` > System.NotSupportedException: Specified method is not supported. > at System.Net.Http.HttpBaseStream.get_Position() > at SharpCompress.IO.RewindableStream.get_Position() > at SharpCompress.Common.GZip.GZipFilePart..ctor(Stream stream, ArchiveEncoding archiveEncoding) > at SharpCompress.Common.GZip.GZipEntry.GetEntries(Stream stream, OptionsBase options)+MoveNext() > ``` > > P.S i'd prefer to not save the file to disk and read it again as FileStream if possible > If that's not possible which types require random access? i know that .tar.gz works perfectly fine through http for example, Thanks in advance!</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > <comment_new><author>@adamhathcock</author><body> > You'll have to show me how you're calling things. > > GZipFilePart does check CanSeek but Rewindable is meant to buffer unbufferable streams so shouldn't be used here.</body></comment_new> > <comment_new><author>@adamhathcock</author><body> > Actually, I take that back, GZipFilePart has a usage of Position no matter seeking. That should be changed</body></comment_new> > <comment_new><author>@adamhathcock</author><body> > you're right but I'm not sure why I'm doing that....I'd have to look and remember</body></comment_new> > </comments> > </details> - Fixes adamhathcock/sharpcompress#843 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/adamhathcock/sharpcompress/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-29 22:20:24 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/sharpcompress#1406