Skip to content

HttpHook: double slash in URL when connection host has trailing slash and endpoint has leading slash #71658

Description

@cliam23

Under which category would you file this issue?

Providers

Apache Airflow version

main (development)

What happened and how to reproduce it?

HttpHook._url_from_endpoint() (in providers/http/src/airflow/providers/http/hooks/http.py) only guards against a missing slash between base_url and endpoint — it doesn't guard against a double one. If a connection's host is configured with a trailing / (common) and an endpoint is passed with a leading / (also common REST convention), the resulting URL has // in it.

Repro:

from airflow.providers.http.hooks.http import HttpHook

hook = HttpHook()
hook.base_url = "https://api.example.com/v1/"
hook._base_url_initialized = True
print(hook.url_from_endpoint("/users"))
# https://api.example.com/v1//users  <- double slash

Many API frameworks (Flask, FastAPI, Django) do not normalize // in a path and will 404 on it, so this produces a silent, confusing failure for anyone hitting this combination. Affects both HttpHook and HttpAsyncHook, since both call the shared _url_from_endpoint() helper.

What you think should happen instead?

Exactly one / should separate the base URL and endpoint regardless of which side(s) already have a slash. _url_from_endpoint() should strip the trailing slash from base_url and the leading slash from endpoint before joining, rather than only checking for the missing-slash case.

Happy to open a PR with the fix and a test covering this slash combination — will link it here.

Operating System

No response

Deployment

None

Apache Airflow Provider(s)

http

Versions of Apache Airflow Providers

No response

Official Helm Chart version

Not Applicable

Kubernetes Version

No response

Helm Chart configuration

No response

Docker Image customizations

No response

Anything else?

No response

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions