Skip to content

fix: validate URL scheme in build_github_request#2449

Open
ayesha-aziz123 wants to merge 6 commits intogithub:mainfrom
ayesha-aziz123:fix/validate-url-in-build-github-request
Open

fix: validate URL scheme in build_github_request#2449
ayesha-aziz123 wants to merge 6 commits intogithub:mainfrom
ayesha-aziz123:fix/validate-url-in-build-github-request

Conversation

@ayesha-aziz123
Copy link
Copy Markdown
Contributor

What does this PR do?

build_github_request() accepted any string as a url parameter and
passed it directly to urllib.request.Request(). When an empty string
or a non-HTTP URL was passed, the error originated deep inside urllib
with a confusing message (unknown url type: '') rather than at the
call site with a clear explanation.

This PR adds early validation that raises a descriptive ValueError
before the request object is constructed.

Changes

  • Raise ValueError("url must not be empty") when url is empty or whitespace-only
  • Raise ValueError when url does not start with http:// or https://
  • Add tests/test_github_http.py covering URL validation and auth header behaviour

Closes

Fixes the confusing unknown url type error raised by urllib internals
when an invalid URL is passed to build_github_request().

Testing

uv run python -m pytest tests/test_github_http.py -v
# 10 passed in 0.90s

AI Disclosure

I used Claude (Anthropic) to help identify this issue via static analysis of the repository.
The fix and tests were manually verified and applied by me.

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 improves specify_cli._github_http.build_github_request() by validating the url argument up-front so invalid/empty URLs fail fast with a clear ValueError, rather than surfacing confusing errors from deep inside urllib.

Changes:

  • Add early ValueError validation for empty/whitespace-only URLs and non-HTTP(S) schemes in build_github_request().
  • Add a new pytest module covering URL validation and Authorization header behavior for GitHub vs non-GitHub hosts.
Show a summary per file
File Description
src/specify_cli/_github_http.py Adds early URL validation before constructing a urllib.request.Request.
tests/test_github_http.py Adds test coverage for URL validation and token-based Authorization header behavior.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment thread src/specify_cli/_github_http.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment thread src/specify_cli/_github_http.py
Copy link
Copy Markdown
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

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

Please address Copilot feedback

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.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment thread src/specify_cli/_github_http.py Outdated
Comment thread tests/test_github_http.py Outdated
@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented May 4, 2026

Please address Copilot feedback

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.

Copilot's findings

Tip

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

Comments suppressed due to low confidence (1)

tests/test_github_http.py:75

  • There is trailing whitespace on the blank line here (line appears to contain spaces). Please remove the extra whitespace to avoid lint/format churn.
            req = build_github_request("https://github.com/github/spec-kit")
        assert req.get_header("Authorization") is None
        
    def test_missing_hostname_raises_value_error(self):
  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment thread src/specify_cli/_github_http.py Outdated
Comment on lines +35 to +42
if not url or not url.strip():
raise ValueError("url must not be empty")
url = url.strip()
parsed = urlparse(url)
if parsed.scheme not in {"http", "https"}:
raise ValueError(f"url must start with http:// or https://, got: {url!r}")
if not parsed.hostname:
raise ValueError(f"url must include a hostname, got: {url!r}")
Comment thread tests/test_github_http.py
Comment on lines +3 to +9
import os
from unittest.mock import patch
import pytest

from specify_cli._github_http import (
build_github_request,
)
@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented May 4, 2026

Please address Copilot feedback

@ayesha-aziz123 ayesha-aziz123 force-pushed the fix/validate-url-in-build-github-request branch from 4b4360e to 64d2624 Compare May 4, 2026 22:03
@mnriem mnriem requested a review from Copilot May 4, 2026 22:10
@ayesha-aziz123
Copy link
Copy Markdown
Contributor Author

@mnriem Thanks, I’ve addressed the feedback and updated the PR. CI should be passing now—please take another look.

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.

Copilot's findings

Tip

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

Comments suppressed due to low confidence (1)

tests/test_github_http.py:74

  • Most existing tests in this repo use pytest’s monkeypatch fixture for environment variables (e.g., the GitHub token tests in tests/test_extensions.py). Using patch.dict(os.environ, ...) here is slightly inconsistent and (without clear=True) can allow unrelated env vars to leak into the test context. Consider switching these env var tests to monkeypatch.setenv/delenv for consistency and isolation.
    def test_github_token_added_for_github_host(self):
        """Authorization header is set when GITHUB_TOKEN is present."""
        with patch.dict(os.environ, {"GITHUB_TOKEN": "test-token", "GH_TOKEN": ""}):
            req = build_github_request("https://github.com/github/spec-kit")
        assert req.get_header("Authorization") == "Bearer test-token"

    def test_gh_token_used_as_fallback(self):
        """GH_TOKEN is used when GITHUB_TOKEN is absent."""
        with patch.dict(os.environ, {"GITHUB_TOKEN": "", "GH_TOKEN": "fallback-token"}):
            req = build_github_request("https://github.com/github/spec-kit")
        assert req.get_header("Authorization") == "Bearer fallback-token"

    def test_no_auth_header_for_non_github_host(self):
        """Authorization header must NOT be set for non-GitHub URLs."""
        with patch.dict(os.environ, {"GITHUB_TOKEN": "test-token"}):
            req = build_github_request("https://example.com/file")
        assert req.get_header("Authorization") is None

    def test_no_auth_header_when_no_token(self):
        """No Authorization header when no token is set in environment."""
        with patch.dict(os.environ, {}, clear=True):
            req = build_github_request("https://github.com/github/spec-kit")
        assert req.get_header("Authorization") is None
  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment thread src/specify_cli/_github_http.py Outdated
Comment on lines +40 to +43
if not url or not url.strip():
raise ValueError("url must not be empty")
url = url.strip()
parsed = urlparse(url)
Comment thread tests/test_github_http.py Outdated
Comment on lines +13 to +14
class TestBuildGithubRequest:
"""Tests for build_github_request() URL validation and auth handling."""
@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented May 4, 2026

Please address Copilot feedback

@ayesha-aziz123
Copy link
Copy Markdown
Contributor Author

Addressed all Copilot feedback. Ready for re-review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants