{"id":48234865,"url":"https://github.com/proxymesh/javascript-proxy-headers","last_synced_at":"2026-04-04T19:54:07.612Z","repository":{"id":345316815,"uuid":"1168935943","full_name":"proxymesh/javascript-proxy-headers","owner":"proxymesh","description":"Extensions for JavaScript HTTP libraries to support custom proxy headers during HTTPS CONNECT tunneling","archived":false,"fork":false,"pushed_at":"2026-03-18T23:48:25.000Z","size":80,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-19T05:38:39.661Z","etag":null,"topics":["axios","got","http-proxy","javascript","node-fetch","nodejs","proxy","proxy-headers","superagent","undici","webscraping"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/javascript-proxy-headers","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/proxymesh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-28T00:54:31.000Z","updated_at":"2026-03-18T23:48:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/proxymesh/javascript-proxy-headers","commit_stats":null,"previous_names":["proxymesh/javascript-proxy-headers"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/proxymesh/javascript-proxy-headers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/proxymesh%2Fjavascript-proxy-headers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/proxymesh%2Fjavascript-proxy-headers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/proxymesh%2Fjavascript-proxy-headers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/proxymesh%2Fjavascript-proxy-headers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/proxymesh","download_url":"https://codeload.github.com/proxymesh/javascript-proxy-headers/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/proxymesh%2Fjavascript-proxy-headers/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31411351,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T19:29:44.979Z","status":"ssl_error","status_checked_at":"2026-04-04T19:29:11.535Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["axios","got","http-proxy","javascript","node-fetch","nodejs","proxy","proxy-headers","superagent","undici","webscraping"],"created_at":"2026-04-04T19:54:07.040Z","updated_at":"2026-04-04T19:54:07.604Z","avatar_url":"https://github.com/proxymesh.png","language":"JavaScript","readme":"# JavaScript Proxy Headers\n\nExtensions for JavaScript HTTP libraries to support **sending and receiving custom proxy headers** during HTTPS CONNECT tunneling.\n\n## The Problem\n\nWhen making HTTPS requests through a proxy, the connection is established via a CONNECT tunnel. During this process:\n\n1. **Sending headers to the proxy** - Most JavaScript HTTP libraries don't provide a way to send custom headers (like `X-ProxyMesh-Country`) to the proxy server during the CONNECT handshake.\n\n2. **Receiving headers from the proxy** - The proxy's response headers from the CONNECT request are typically discarded, making it impossible to read custom headers (like `X-ProxyMesh-IP`) that the proxy sends back.\n\nThis library solves both problems for popular JavaScript HTTP libraries.\n\n## Supported Libraries\n\n| Library | Subpath export | Notes |\n|---------|----------------|--------|\n| [axios](https://axios-http.com/) | `javascript-proxy-headers/axios` | Widely used client |\n| [node-fetch](https://github.com/node-fetch/node-fetch) | `javascript-proxy-headers/node-fetch` | Fetch API on Node |\n| [got](https://github.com/sindresorhus/got) | `javascript-proxy-headers/got` | Ergonomic API |\n| [undici](https://undici.nodejs.org/) | `javascript-proxy-headers/undici` | Node’s fast HTTP stack |\n| [superagent](https://github.com/ladjs/superagent) | `javascript-proxy-headers/superagent` | Chaining API |\n| [ky](https://github.com/sindresorhus/ky) | `javascript-proxy-headers/ky` | Tiny fetch wrapper |\n| [wretch](https://github.com/elbywan/wretch) | `javascript-proxy-headers/wretch` | Fetch wrapper (sets wretch’s global fetch polyfill) |\n| [make-fetch-happen](https://github.com/npm/make-fetch-happen) | `javascript-proxy-headers/make-fetch-happen` | npm-style fetch (cache, retries, proxy) |\n| [needle](https://github.com/tomas/needle) | `javascript-proxy-headers/needle` | Lean HTTP client |\n| [typed-rest-client](https://github.com/microsoft/typed-rest-client) | `javascript-proxy-headers/typed-rest-client` | Azure / DevOps–style REST client |\n\n**urllib** is not integrated yet: it expects an [undici](https://undici.nodejs.org/) `Dispatcher`, not a Node `Agent`. See `notes/urllib-integration-deferred.md` in this repo for a possible approach.\n\n## Installation\n\n```bash\nnpm install javascript-proxy-headers\n```\n\nThen install the HTTP client(s) you use (for example `axios`, `got`, `ky`, `wretch`, `make-fetch-happen`, `needle`, or `typed-rest-client`). Each is an optional peer dependency.\n\n\u003e **Note:** This package has no runtime dependencies by default—install only the adapters you need.\n\n## Quick Start\n\n### axios\n\n```javascript\nimport { createProxyAxios } from 'javascript-proxy-headers/axios';\n\nconst client = createProxyAxios({\n    proxy: 'http://user:pass@proxy.example.com:8080',\n    proxyHeaders: { 'X-ProxyMesh-Country': 'US' }\n});\n\nconst response = await client.get('https://httpbin.org/ip');\n\n// Proxy headers are merged into response.headers\nconsole.log(response.headers['x-proxymesh-ip']);\n```\n\n### node-fetch\n\n```javascript\nimport { proxyFetch } from 'javascript-proxy-headers/node-fetch';\n\nconst response = await proxyFetch('https://httpbin.org/ip', {\n    proxy: 'http://user:pass@proxy.example.com:8080',\n    proxyHeaders: { 'X-ProxyMesh-Country': 'US' }\n});\n\n// Proxy headers available on response\nconsole.log(response.proxyHeaders.get('x-proxymesh-ip'));\n```\n\n### got\n\n```javascript\nimport { createProxyGot } from 'javascript-proxy-headers/got';\n\nconst client = createProxyGot({\n    proxy: 'http://user:pass@proxy.example.com:8080',\n    proxyHeaders: { 'X-ProxyMesh-Country': 'US' }\n});\n\nconst response = await client('https://httpbin.org/ip');\nconsole.log(response.headers['x-proxymesh-ip']);\n```\n\n### undici\n\n```javascript\nimport { request } from 'javascript-proxy-headers/undici';\n\nconst { statusCode, headers, body, proxyHeaders } = await request(\n    'https://httpbin.org/ip',\n    {\n        proxy: 'http://user:pass@proxy.example.com:8080',\n        proxyHeaders: { 'X-ProxyMesh-Country': 'US' }\n    }\n);\n\nconsole.log(proxyHeaders.get('x-proxymesh-ip'));\n```\n\n### ky\n\nUses a custom `fetch` built from node-fetch + `ProxyHeadersAgent` (`ky.create({ fetch })`).\n\n```javascript\nimport { createProxyKy } from 'javascript-proxy-headers/ky';\n\nconst api = await createProxyKy({\n    proxy: 'http://user:pass@proxy.example.com:8080',\n    proxyHeaders: { 'X-ProxyMesh-Country': 'US' }\n});\n\nconst response = await api('https://httpbin.org/ip');\nconsole.log(response.proxyHeaders.get('x-proxymesh-ip'));\n```\n\n### wretch\n\nRegisters the same custom `fetch` as wretch’s fetch polyfill. Use the normal wretch chain (for example `.get().res()`).\n\n```javascript\nimport { createProxyWretch } from 'javascript-proxy-headers/wretch';\n\nconst wretch = await createProxyWretch({\n    proxy: 'http://user:pass@proxy.example.com:8080',\n    proxyHeaders: { 'X-ProxyMesh-Country': 'US' }\n});\n\nconst response = await wretch('https://httpbin.org/ip').get().res();\nconsole.log(response.proxyHeaders.get('x-proxymesh-ip'));\n```\n\n### make-fetch-happen\n\nPasses a `ProxyHeadersAgent` as `agent`; `@npmcli/agent` uses it as-is when set.\n\n```javascript\nimport { createProxyMakeFetchHappen } from 'javascript-proxy-headers/make-fetch-happen';\n\nconst fetch = createProxyMakeFetchHappen({\n    proxy: 'http://user:pass@proxy.example.com:8080',\n    proxyHeaders: { 'X-ProxyMesh-Country': 'US' }\n});\n\nconst response = await fetch('https://httpbin.org/ip');\nconsole.log(response.proxyHeaders.get('x-proxymesh-ip'));\n```\n\n### needle\n\n```javascript\nimport { proxyNeedleGet } from 'javascript-proxy-headers/needle';\n\nconst res = await proxyNeedleGet('https://httpbin.org/ip', {\n    proxy: 'http://user:pass@proxy.example.com:8080',\n    proxyHeaders: { 'X-ProxyMesh-Country': 'US' }\n});\n\n// CONNECT response headers merged onto res.headers where missing\nconsole.log(res.headers['x-proxymesh-ip']);\n```\n\n### typed-rest-client\n\nUses a subclass of `HttpClient` that routes HTTPS through `ProxyHeadersAgent` (no `tunnel` agent).\n\n```javascript\nimport { createProxyRestClient } from 'javascript-proxy-headers/typed-rest-client';\n\nconst client = createProxyRestClient({\n    userAgent: 'my-app',\n    proxy: 'http://user:pass@proxy.example.com:8080',\n    proxyHeaders: { 'X-ProxyMesh-Country': 'US' }\n});\n\nawait client.get('https://httpbin.org/ip');\nconsole.log(client.proxyAgent.lastProxyHeaders?.get('x-proxymesh-ip'));\n```\n\n### Core Agent (Advanced)\n\nFor direct control, use the core `ProxyHeadersAgent`:\n\n```javascript\nimport { ProxyHeadersAgent } from 'javascript-proxy-headers';\nimport https from 'https';\n\nconst agent = new ProxyHeadersAgent('http://proxy.example.com:8080', {\n    proxyHeaders: { 'X-ProxyMesh-Country': 'US' },\n    onProxyConnect: (headers) =\u003e {\n        console.log('Proxy IP:', headers.get('x-proxymesh-ip'));\n    }\n});\n\nhttps.get('https://httpbin.org/ip', { agent }, (res) =\u003e {\n    // Handle response\n});\n```\n\n## Testing\n\nIntegration tests need a real proxy (set `PROXY_URL` or `HTTPS_PROXY`):\n\n```bash\nexport PROXY_URL='http://user:pass@proxy.example.com:8080'\n\nnpm test                              # all adapters (see package.json \"test\")\nnode run_tests.js -v                  # same harness from repo root\nnpm run test:ts                       # same checks via tsx + TypeScript harness\nnpm run test:types                    # `tsc --noEmit` only (no network)\n\n# Limit modules\nnode test/test_proxy_headers.js -v axios ky\n```\n\nVerbose (`-v`) prints captured header values. See `test/test_proxy_headers.js --help`.\n\n## Requirements\n\n- Node.js \u003e= 18.0.0\n- One or more supported HTTP libraries\n\n## Related Projects\n\n- **[python-proxy-headers](https://github.com/proxymesh/python-proxy-headers)** - Same functionality for Python\n- **[proxy-examples](https://github.com/proxymesh/proxy-examples)** - Example code for using proxies\n\n## About\n\nCreated by [ProxyMesh](https://proxymesh.com) to help our customers use custom headers to control proxy behavior. Works with any proxy that supports custom headers.\n\n## License\n\nMIT License\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fproxymesh%2Fjavascript-proxy-headers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fproxymesh%2Fjavascript-proxy-headers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fproxymesh%2Fjavascript-proxy-headers/lists"}