Skip to content

Parse the host argument once and validate the endpoint - #634

Open
hashhar wants to merge 9 commits into
trinodb:masterfrom
hashhar:hashhar/dedup-scheme-inference
Open

Parse the host argument once and validate the endpoint#634
hashhar wants to merge 9 commits into
trinodb:masterfrom
hashhar:hashhar/dedup-scheme-inference

Conversation

@hashhar

@hashhar hashhar commented Aug 21, 2026

Copy link
Copy Markdown
Member

Description

Connection parsed the host argument by hand on top of a urlparse call that returns no hostname for a scheme-less value. An IPv6 literal, a bare host:port and a host carrying a path each built a malformed request URL that failed at connect time with an error naming neither the argument nor the problem.

The http_scheme and port arguments were not validated either. A wrongly cased scheme, a scheme or port contradicting one given in host, and a port outside the valid range all went through unchecked.

Parse the argument once and reject what cannot be represented. The scheme and port rules move out of Connection and TrinoRequest into helpers both call.

A path in host is now rejected rather than carried. The port landed after the path, so no such setup ever reached the wire intact. The gateway-prefix use case behind it is real and still unserved. A dedicated path_prefix argument is the shape to add if we want it.

Release notes

( ) This is not user-visible or docs only and no release notes are required.
(x) Release notes are required, please propose a release note for me.
( ) Release notes are required, with the following suggested text:

* Fix some things. ({issue}`issuenumber`)

Connection and TrinoRequest stored the argument as given and compared it
against the lowercase constants so a differently cased scheme silently
skipped the TLS check and the port inference. Neither rejected a scheme
that is not http or https.
The host URL used to win silently.
urlparse reads a scheme-less argument as a path so a bare hostname
yielded no hostname and the code fell back to the raw string. Brackets,
ports and paths were then added on top of that fallback which built
unusable URLs for an IPv6 literal, for a path in the host and for a bare
host:port.

Prefixing // when the argument carries no scheme makes urlsplit read
every accepted form as an authority so one parse handles all cases. A
path and credentials are rejected rather than carried - neither ever
reached the wire even before this change.

Hostnames now come back lowercased, which also fixes the coordinator
comparison in SpooledSegment that silently dropped custom headers for a
mixed-case host.
The port argument was never validated so an out-of-range value built an
unusable URL. Check the resolved port so one check covers a port from
either argument.

A port in the host that contradicts the port argument now raises,
matching how a contradicting scheme is treated. It used to win silently.
_assert_valid_host reimplemented the parsing that _parse_host now owns.
Call it and layer the stricter policy on top because this host goes into
a URL that already has its own scheme and port.
Comment thread trino/dbapi.py
try:
scheme = trino.client.normalize_http_scheme(host_scheme)
except ValueError:
raise ValueError(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A bit awkward. Maybe have normalize_http_scheme() accept an optional context argument and, if provided, use it to add "in {context!r}" to the error message?

Comment thread README.md
Comment on lines +36 to +37
missing port from the scheme. Wrap an IPv6 literal in brackets when it carries
a port, as in `[::1]:8080`.

@azawlocki-sbdt azawlocki-sbdt Aug 25, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

To me it reads as if it referred to IPv6 literal. Maybe

Suggested change
missing port from the scheme. Wrap an IPv6 literal in brackets when it carries
a port, as in `[::1]:8080`.
missing port from the scheme. Wrap an IPv6 literal in brackets when a port
is also present, as in `[::1]:8080`.

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

Development

Successfully merging this pull request may close these issues.

2 participants