Skip to content

fix: use percent-placeholder args in HTTPError to prevent Tornado from doubling percent signs in gateway URLs - #1642

Merged
Carreau merged 1 commit into
jupyter-server:mainfrom
terminalchai:fix/gateway-httperror-percent-encoding
May 28, 2026
Merged

fix: use percent-placeholder args in HTTPError to prevent Tornado from doubling percent signs in gateway URLs#1642
Carreau merged 1 commit into
jupyter-server:mainfrom
terminalchai:fix/gateway-httperror-percent-encoding

Conversation

@terminalchai

Copy link
Copy Markdown
Contributor

Problem

Tornado's web.HTTPError escapes % as %% in the log_message string when no positional args are provided. This is by design — Tornado passes log_message % args through Python's %-formatting, so any literal % in the message must be doubled to survive.

The three HTTPError raises in send_request_to_gateway() used f-strings as log_message with no args. When the gateway URL contains percent-encoded characters like http%3A%2F%2F, Tornado's escaping doubled every %:

"ConnectionError was received from Gateway server url 'http%%3A%%2F%%2Fexample.com'."

Closes #1503.

Fix

Replace f-string log_message arguments with %s placeholder strings and pass the URL/message values through the args parameter. Tornado only escapes log_message when args is empty, so URL percent characters are preserved correctly:

# Before
raise web.HTTPError(503, f"...url '{gateway_client.url}'.")

# After
raise web.HTTPError(503, "...url '%s'.", gateway_client.url)

Applied to all three HTTPError raises in gateway_request().

Test

Added test_gateway_httperror_percent_not_doubled() that:

  1. Creates an HTTPError the old way (f-string, no args) and asserts Tornado does double % — proves the old code was buggy.
  2. Creates an HTTPError the new way (%s placeholder + args) and asserts %% is not present in log_message and the URL is intact in args.

…g % in gateway URLs

Tornado's HTTPError escapes '%' as '%%' in the log_message string when no
positional args are provided. This caused gateway URLs containing percent-
encoded characters (e.g. 'http%3A%2F%2F') to appear doubled in error
responses and logs.

Replace f-string log_message arguments in the three web.HTTPError raises in
send_request_to_gateway() with '%s' placeholder strings and pass URL/message
values through the args parameter. Tornado only escapes log_message when args
is empty, so URL percent characters are preserved correctly.

Add test_gateway_httperror_percent_not_doubled() to demonstrate the old
f-string path doubles '%' and the new placeholder+args path does not.

Closes jupyter-server#1503

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.

I this usually the '%s' is a code small that one should use %r instead but it's pure improvement

@Carreau Carreau added this to the 2.19 milestone May 28, 2026
@Carreau
Carreau merged commit aaddd4b into jupyter-server:main May 28, 2026
70 of 77 checks passed
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.

% in error message being encoded into %% (by Tornado HTTPError)

2 participants