Short answers
What is the format of an authenticated proxy URL?
A common client format is scheme://username:password@host:port. The scheme describes the connection to the proxy. The username and password need component encoding when embedded in that URL; the client must support that proxy protocol and authentication method.
Should I encode the whole proxy URL?
No. Keep its structural separators and host intact. Encode the original username and password components individually, then assemble the URL. Encoding a completed URL would also encode the separators the parser needs.
Should a separate password field contain percent escapes?
Enter the original password in a client’s separate authentication field unless its documentation explicitly says otherwise. A literal percent sequence can be part of the original password. Do not automatically decode it or treat an already encoded URL as the raw source.
Does an HTTPS website require an https:// proxy URL?
No. The proxy URL identifies the connection to the gateway. An HTTP proxy can carry an HTTPS destination through CONNECT. Use https:// for the proxy hop only when that gateway and client support a TLS connection to the proxy.
Identify the four fields before joining them
Copy the connection values as one set. For Portproof, the connection builder supplies the host, protocol-specific port, complete generated username and proxy password. Keep the full username: its pool, country, rotation and session settings are part of the connection choice. Your account password and API key are different credentials.
This shows structure, not a usable credential. A complete credential-bearing URL is a secret; keep it out of screenshots, logs and source control.
http://ENCODED_USER:ENCODED_PASSWORD@gw.portproof.org:7000| Part | What it describes | Common mistake |
|---|---|---|
| http:// | Protocol used to contact the proxy gateway | Changing it because the destination uses HTTPS |
| Username and password | Authentication for that gateway | Using a website login or dropping username options |
| Host | The gateway’s DNS name or address | Pasting an account dashboard URL |
| Port | The endpoint for the selected protocol | Reusing a SOCKS port with an HTTP configuration |
A colon-separated export such as host:port:user:pass is a particular application’s import format, not a general URL. Passwords can contain colons, so a blind split on every colon is ambiguous. Prefer the four original fields or the exporter’s documented parser. IPv6 addresses also contain colons and need brackets when placed in a URL’s host position.
Choose the gateway protocol first
For the HTTP gateway use http://gw.portproof.org:7000. The destination URL remains a separate input. An HTTPS request can travel through that HTTP gateway using CONNECT while retaining the destination’s TLS certificate verification. Do not disable certificate checks to fix a parsing or authentication problem.
The curl proxy reference documents proxy schemes and credential decoding. SOCKS schemes can differ in DNS handling and client support, so follow HTTP vs SOCKS5 when choosing one. Changing the scheme and port together is a protocol change, not an encoding repair.
Encode raw username and password components once
Inside a URL, separators such as @, / and # have structural meaning. Component encoding preserves those characters as credential data. Python’s URL quoting reference documents quote; using safe="" also encodes slashes. Form-query encoding with quote_plus has different space handling and is not the operation used here.
| Original password | Encoded password component | Meaning |
|---|---|---|
| p@ss/#: word | p%40ss%2F%23%3A%20word | Separators and the space remain part of the password |
| literal%40 | literal%2540 | The original contains the three characters %40, not an @ |
| café+pass | caf%C3%A9%2Bpass | UTF-8 bytes and the plus sign are encoded |
“Once” means once from the original value. If the original password is literal%40, the percent sign must become %25. If you take an already encoded password and encode it again by accident, the next client can send a different value. Keep raw values and assembled URLs in separate variables rather than guessing their state from whether a percent sign appears.
This checks string construction and a local parse round trip. It sends no network request and does not establish that a gateway or particular client accepted the credentials.
from urllib.parse import quote, unquote, urlsplit
raw_user = "user:name"
raw_password = "p@ss/#:%40 +"
host = "gw.portproof.org"
port = 7000
proxy_url = (
f"http://{quote(raw_user, safe='')}:"
f"{quote(raw_password, safe='')}@{host}:{port}"
)
parts = urlsplit(proxy_url)
assert unquote(parts.username) == raw_user
assert unquote(parts.password) == raw_password
assert parts.hostname == host
assert parts.port == port
# Pass proxy_url privately to a client that accepts this format.
# Do not print a URL assembled from real credentials.
Keep separate authentication fields raw
Some clients take the server and authentication separately. Playwright’s proxy settings show a server plus username and password. Supply the original credential strings to those separate fields; do not move an encoded password from the completed URL into the password field.
Set and validate both environment values before creating the browser. Environment storage is not permission to log the object. See the full Playwright guide for a bounded request and cleanup.
// Configuration fragment; credentials are original values from your environment.
const proxy = {
server: "http://gw.portproof.org:7000",
username: process.env.PROXY_USER,
password: process.env.PROXY_PASS,
};
Do not assume every client accepts embedded credentials. A URL that parses locally can still be rejected by an application’s proxy configuration. Follow the Playwright guide for that client, or the matching setup guide for yours. A password entered at curl’s interactive prompt is also the original value; the curl test avoids placing it in the command.
Check format before making a controlled request
- Confirm the scheme, host and protocol-specific port against the connection builder.
- Check that the complete original username and current password came from the same connection set.
- Determine whether the client expects one URL or separate authentication fields.
- For a URL, encode each original credential component once; preserve the URL separators.
- Use the client’s documented bounded test, without logging secrets or adding automatic retries.
An invalid URL and a rejected authentication exchange are different observations. For a returned 407 or failed CONNECT authentication, use 407 Proxy Authentication Required. If curl works but another application does not, use client routing and environment checks. Once configured, proxy traffic uses the current account balance and limits.
Sources and verification scope
References checked 30 October 2026: RFC 3986 URI components, Python URL quoting, curl proxy options and Playwright proxy configuration. Four synthetic Python raw-value round trips passed, including a literal percent sequence and non-ASCII text. These are serialization checks, not a live gateway or browser authentication test.
What is not allowed
Connect only to destinations you are permitted to use, protect gateway credentials and follow the acceptable-use policy.
Read next
Fix 407 Proxy Authentication Required
Read the gateway code, check credentials and balance, then separate a rejected HTTPS tunnel from an HTTP response.
Read the guide
Proxy requires a username and password
Identify the proxy asking for credentials, check the network setting and separate gateway sign-in from your device or website password.
Read the guide