Skip to content

fix(client): sanitize newlines in proxy env vars before httpx sees them - #3631

Open
Xsidz wants to merge 1 commit into
openai:mainfrom
Xsidz:fix/no-proxy-newline
Open

fix(client): sanitize newlines in proxy env vars before httpx sees them#3631
Xsidz wants to merge 1 commit into
openai:mainfrom
Xsidz:fix/no-proxy-newline

Conversation

@Xsidz

@Xsidz Xsidz commented Aug 16, 2026

Copy link
Copy Markdown

Summary

Fixes #3303.

Docker, .env files, and some shell scripts can produce proxy env vars with embedded newlines (e.g. NO_PROXY=localhost\n192.168.1.1). httpx splits NO_PROXY only on ,, so the newline character becomes part of a hostname string, which triggers httpx.InvalidURL: Invalid non-printable ASCII character in URL.

A fix in httpx upstream is blocked (project not accepting external PRs). The fix here sanitizes HTTP_PROXY, HTTPS_PROXY, NO_PROXY, and their lowercase equivalents in os.environ before the httpx client is constructed — both in OpenAI.__init__ and AsyncOpenAI.__init__.

Test plan

  • Smoke test: os.environ['NO_PROXY'] = 'localhost\n192.168.1.1' then OpenAI(api_key='...') no longer raises InvalidURL; env var is cleaned to 'localhost,192.168.1.1'.
  • tests/test_client.py: 198 passed, 2 skipped, 0 failures.
  • Ruff lint: all checks passed.

Fixes openai#3303: NO_PROXY (and other proxy env vars) can contain newline
characters in Docker/dotenv environments. httpx splits NO_PROXY only by
comma, so a newline becomes part of the hostname and triggers
InvalidURL. Replace newlines with commas at client construction time.
@Xsidz
Xsidz requested a review from a team as a code owner August 16, 2026 18:09
Copilot AI lite review requested due to automatic review settings August 16, 2026 18:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9c2fe85791

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/openai/_client.py

WORKLOAD_IDENTITY_API_KEY_PLACEHOLDER = "workload-identity-auth"

_PROXY_ENV_VARS = ("HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY", "http_proxy", "https_proxy", "no_proxy")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include ALL_PROXY in the sanitizer

When ALL_PROXY or all_proxy is the configured fallback proxy and contains a trailing or embedded newline, it remains untouched and HTTPX2 still receives the invalid character during default client construction. The existing proxy tests explicitly clear both spellings because HTTPX2 recognizes them, so include them alongside the other supported proxy environment variables.

Useful? React with 👍 / 👎.

Comment thread src/openai/_client.py
parsed[line[:colon].strip()] = line[colon + 1 :].strip()
default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})}

_sanitize_proxy_env_vars()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Sanitize before constructing custom HTTP clients

When callers follow the documented OpenAI(http_client=DefaultHttpx2Client(...)) pattern, Python constructs the HTTPX2 client before entering OpenAI.__init__, so a malformed listed proxy variable raises InvalidURL before this call can sanitize it. The same ordering affects DefaultAsyncHttpx2Client; sanitization therefore also needs to occur in the exported client helpers or otherwise before those clients consume the environment.

Useful? React with 👍 / 👎.

Comment thread src/openai/_client.py
Comment on lines +103 to +104
if val is not None and "\n" in val:
os.environ[key] = ",".join(p.strip() for p in val.splitlines() if p.strip())

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Sanitize carriage-return line endings

When a proxy value contains a lone \r, this guard skips sanitization even though splitlines() would remove it and HTTPX2 rejects it as a non-printable ASCII character. This can occur when shell command substitution reads a CRLF-terminated file and strips the final \n while retaining \r, so the check should recognize carriage returns as well as line feeds.

Useful? React with 👍 / 👎.

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.

InvalidURL error when NO_PROXY environment variable contains newline characters

2 participants