Skip to content

geotiff: close HTTP source when COG tile fetch raises#1819

Merged
brendancol merged 4 commits into
mainfrom
issue-1816
May 14, 2026
Merged

geotiff: close HTTP source when COG tile fetch raises#1819
brendancol merged 4 commits into
mainfrom
issue-1816

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Closes #1816.

Wraps the tile fetch and post-processing block in _read_cog_http in try/finally so source.close() runs even when _fetch_decode_cog_http_tiles raises. _HTTPSource.close() is currently a no-op so the fix is structural: a future resource-holding source would otherwise leak on the error path.

Tested: pytest xrspatial/geotiff/tests/test_cog_http_close_on_error_1816.py

@github-actions github-actions Bot added the performance PR touches performance-sensitive code label May 13, 2026
@brendancol brendancol requested a review from Copilot May 13, 2026 16:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses issue #1816 by ensuring the HTTP COG reader path closes its _HTTPSource even when tile fetching/decoding or subsequent post-processing raises, preventing future resource leaks if _HTTPSource.close() later becomes non-trivial.

Changes:

  • Wrap _fetch_decode_cog_http_tiles + post-processing in _read_cog_http with try/finally to guarantee source.close().
  • Add regression tests that wrap _HTTPSource to track close() calls on both success and exception paths (fetch failure + post-processing failure).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
xrspatial/geotiff/_reader.py Adds try/finally around the HTTP tile fetch and post-processing so source.close() runs on exceptions.
xrspatial/geotiff/tests/test_cog_http_close_on_error_1816.py Introduces regression tests validating source.close() is invoked on both success and failure paths.
Comments suppressed due to low confidence (1)

xrspatial/geotiff/tests/test_cog_http_close_on_error_1816.py:206

  • Same continuation-indentation issue as above: this wrapped function signature uses an 8-space indent on the continuation line and may fail flake8/pycodestyle continuation-indent checks. Reformat the parameters using a 4-space hanging indent (or alignment) to match PEP8/flake8 expectations.
def test_http_source_closed_when_post_processing_raises(
        single_band_cog, monkeypatch):
    """An exception from the orientation/photometric step also runs

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread xrspatial/geotiff/_reader.py Outdated
Comment on lines +1938 to +1946
# Issue #1816: wrap the tile fetch and post-processing in try/finally
# so ``source.close()`` runs even when the fetch/decode or the
# orientation/photometric step raises. ``_HTTPSource.close()`` is a
# no-op today, but a future resource-holding source would leak on
# the error path without this. The explicit ``source.close()`` calls
# in the validation block above stay as-is; ``close()`` is idempotent.
try:
arr = _fetch_decode_cog_http_tiles(
source, header, ifd, max_pixels=max_pixels, window=window)
Comment on lines +171 to +173
def test_http_source_closed_when_tile_fetch_raises(
single_band_cog, monkeypatch):
"""When ``_fetch_decode_cog_http_tiles`` raises, ``_read_cog_http``
PR #1803 forwarded the caller's max_pixels to read_to_array inside
read_vrt's source loop so a tiny VRT output cannot force a huge source
decode (#1796). The output-window check at the source read enforces that
correctly. A separate per-tile dimension check at the same call sites
also consumed the caller's max_pixels, so a caller setting max_pixels as
an output budget (e.g. 10_000) failed the per-tile sanity check on any
normal source whose default tile size is 256x256 (= 65_536 pixels).

Use MAX_PIXELS_DEFAULT for the per-tile dim check at the two call sites
in _read_tiles (local) and _read_tiles_cog_http (HTTP). The output-window
check at the same functions continues to enforce the user-supplied
max_pixels, preserving the #1796 protection.
@brendancol
Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

Co-authored-by: brendancol <433221+brendancol@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented May 13, 2026

@copilot resolve the merge conflicts in this pull request

Resolved and pushed in commit 7f2d2ec by merging origin/main into this branch and fixing the _read_cog_http conflict so both branches’ behavior is preserved. No UI changes were made in this PR.

@brendancol brendancol merged commit 41ccc2a into main May 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

geotiff: _read_cog_http skips source.close() when tile fetch raises

3 participants