{"id":40990046,"url":"https://github.com/ichiban/httpproxyfailover","last_synced_at":"2026-01-22T07:38:36.046Z","repository":{"id":47778112,"uuid":"295089404","full_name":"ichiban/httpproxyfailover","owner":"ichiban","description":"Create a fault-tolerant HTTP proxy out of multiple somewhat unreliable HTTP proxies.","archived":false,"fork":false,"pushed_at":"2023-09-14T06:04:25.000Z","size":59,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-06-19T15:17:02.390Z","etag":null,"topics":["failover","fault-tolerance","http","http-proxies","http-proxy","proxy"],"latest_commit_sha":null,"homepage":"","language":"Go","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/ichiban.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}},"created_at":"2020-09-13T06:06:40.000Z","updated_at":"2023-09-14T06:03:53.000Z","dependencies_parsed_at":"2024-06-19T15:11:34.429Z","dependency_job_id":null,"html_url":"https://github.com/ichiban/httpproxyfailover","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/ichiban/httpproxyfailover","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ichiban%2Fhttpproxyfailover","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ichiban%2Fhttpproxyfailover/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ichiban%2Fhttpproxyfailover/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ichiban%2Fhttpproxyfailover/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ichiban","download_url":"https://codeload.github.com/ichiban/httpproxyfailover/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ichiban%2Fhttpproxyfailover/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28658107,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T01:17:37.254Z","status":"online","status_checked_at":"2026-01-22T02:00:07.137Z","response_time":144,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["failover","fault-tolerance","http","http-proxies","http-proxy","proxy"],"created_at":"2026-01-22T07:38:35.557Z","updated_at":"2026-01-22T07:38:36.041Z","avatar_url":"https://github.com/ichiban.png","language":"Go","readme":"# httpproxyfailover\n\nCreate a fault-tolerant HTTP proxy out of multiple somewhat unreliable HTTP proxies.\n\n## Installation\n\n```console\ngo get github.com/ichiban/httpproxyfailover/cmd/httpproxyfailover\n```\n\n## Usage\n\n```console\n$ httpproxyfailover --help\nUsage: httpproxyfailover [options...] \u003cbackend proxy URI template\u003e...\n  -p, --port int           Specify port number to listen on (random if not specified)\n  -t, --timeout duration   Set timeout for each trial\n  -T, --tls                Check TLS handshake\npflag: help requested\n```\n\n## Features\n\n### Fail over\n\nLet's say we have 2 HTTP proxies running, namely `http://localhost:8081` and `http://localhost:8082`.\nThe first one is currently unavailable and returns 502 on CONNECT.\n\n```console\n$ curl -w \"%{http_code}\\n\" -px http://localhost:8081 https://httpbin.org/status/200\n000\ncurl: (56) Received HTTP code 502 from proxy after CONNECT\n```\n\nWhile the second one works fine.\n\n```console\n$ curl -w \"%{http_code}\\n\" -px http://localhost:8082 https://httpbin.org/status/200\n200\n```\n\nBy using `httpproxyfailover`, the trial and error shown above can be done automatically.\n\n```console\n$ httpproxyfailover -p 8080 http://localhost:8081 http://localhost:8082\nINFO[0000] start                                         addr=\"[::]:8080\" timeout=0s tlsHandshake=false\nWARN[0005] fail-over                                     error=\"502 Bad Gateway\" from=\"[::1]:62453\" to=\"httpbin.org:443\" via=\"http://localhost:8081\"\nINFO[0005] connect                                       from=\"[::1]:62453\" to=\"httpbin.org:443\" via=\"http://localhost:8082\"\n```\n\n```console\n$ curl -w \"%{http_code}\\n\" -px http://localhost:8080 https://httpbin.org/status/200\n200\n```\n\n### TLS handshake\n\nIf you're working with untrustworthy proxies, they might try MITM attacks. In that case, HTTPS requests over the proxy\nconnection always fail because of unsuccessful TLS handshakes.\n\nWith `--tls`(`-T`) option, `httpproxyfailover` will skip those proxies with unsuccessful TLS handshakes.\n\n### favicon\n\nEven though you have established a proxy connection, it may not be able to actually access the contents of the origin\nserver through it.\n\nWith `--favicon`(`-f`) option, `httpproxyfailover` will skip those proxies which can't GET `/favicon.ico`.\n\n### GET\n\nYou may want to check if the proxy is working by requesting a server under your control.\n\nWith `--get URL`(`-g`) option, `httpproxyfailover` will skip those proxies which can't GET `URL` successfully.\n\nYou can provide as many URLs as you want by repeating the option `--get https://example.com/foo --get https://example.org/bar`.\nThen, `httpproxyfailover` will consider the proxy is working if it GETs at least one of the URLs successfully.\n\n### Tags\n\nBy prepending curly-bracketed words in front of the URLs, you can assign tags to the backend proxies.\n\n```console\n$ httpproxyfailover -p 8080 '{foo}http://localhost:8081' '{bar}http://localhost:8082' '{foo}{bar}http://localhost:8083' 'http://localhost:8084'\n```\n\nYou can specify a tag in username part of the `httpproxyfailover` URL.\n\n`httpproxyfailover` tries a backend proxy if the tags in the template are all provided in the username part.\n\nSo, if you provide `foo`, `httpproxyfailover` will try proxies without tags other than `foo`.\n\n```console\n$ curl -w \"%{http_code}\\n\" -px http://foo@localhost:8080 https://httpbin.org/status/200\n200\n```\n\n```console\n$ httpproxyfailover -p 8080 '{foo}http://localhost:8081' '{bar}http://localhost:8082' '{foo}{bar}http://localhost:8083' 'http://localhost:8084'\nINFO[0000] start                                         addr=\"[::]:8080\" timeout=0s tlsHandshake=false\nWARN[0007] fail-over                                     error=\"502 Bad Gateway\" from=\"[::1]:62578\" to=\"httpbin.org:443\" via=\"http://localhost:8081\"\nINFO[0008] connect                                       from=\"[::1]:62578\" to=\"httpbin.org:443\" via=\"http://localhost:8084\"\n```\n\nOr if you provide `bar`, then it'll try proxies without tags other than `bar`.\n\n```console\n$ curl -w \"%{http_code}\\n\" -px http://bar@localhost:8080 https://httpbin.org/status/200\n200\n```\n\n```console\n$ httpproxyfailover -p 8080 '{foo}http://localhost:8081' '{bar}http://localhost:8082' '{foo}{bar}http://localhost:8083' 'http://localhost:8084'\nINFO[0000] start                                         addr=\"[::]:8080\" timeout=0s tlsHandshake=false\nWARN[0002] fail-over                                     error=\"502 Bad Gateway\" from=\"[::1]:62601\" to=\"httpbin.org:443\" via=\"http://localhost:8082\"\nINFO[0003] connect                                       from=\"[::1]:62601\" to=\"httpbin.org:443\" via=\"http://localhost:8084\"\n```\n\nYou can also specify multiple tags. If you provide `foo,bar`, then it'll try proxies without tags other than `foo` or `bar`.\n\n```console\n$ curl -w \"%{http_code}\\n\" -px http://foo,bar@localhost:8080 https://httpbin.org/status/200\n200\n```\n\n```console\n$ httpproxyfailover -p 8080 '{foo}http://localhost:8081' '{bar}http://localhost:8082' '{foo}{bar}http://localhost:8083' 'http://localhost:8084'\nINFO[0000] start                                         addr=\"[::]:8080\" timeout=0s tlsHandshake=false\nWARN[0010] fail-over                                     error=\"502 Bad Gateway\" from=\"[::1]:62610\" to=\"httpbin.org:443\" via=\"http://localhost:8081\"\nWARN[0010] fail-over                                     error=\"502 Bad Gateway\" from=\"[::1]:62610\" to=\"httpbin.org:443\" via=\"http://localhost:8082\"\nWARN[0010] fail-over                                     error=\"502 Bad Gateway\" from=\"[::1]:62610\" to=\"httpbin.org:443\" via=\"http://localhost:8083\"\nINFO[0010] connect                                       from=\"[::1]:62610\" to=\"httpbin.org:443\" via=\"http://localhost:8084\"\n```\n\n### Variables\n\nSimilar to tags, you can also use variables in the backend URLs.\nActually tags are shorthand for variables with empty string values.\n\n```console\n$ httpproxyfailover -p 8080 'http://{domain}:8081' 'http://{domain}:8082'\n```\n\n```console\n$ curl -w \"%{http_code}\\n\" -px http://domain=localhost@localhost:8080 https://httpbin.org/status/200\n200\n```\n\n```console\n$ httpproxyfailover -p 8080 'http://{domain}:8081' 'http://{domain}:8082'\nINFO[0000] start                                         addr=\"[::]:8080\" timeout=0s tlsHandshake=false\nWARN[0012] fail-over                                     error=\"502 Bad Gateway\" from=\"[::1]:62672\" to=\"httpbin.org:443\" via=\"http://localhost:8081\"\nINFO[0012] connect                                       from=\"[::1]:62672\" to=\"httpbin.org:443\" via=\"http://localhost:8082\"\n```\n\n## License\n\nDistributed under the MIT license. See ``LICENSE`` for more information.\n\n## Contributing\n\n1. Fork it (\u003chttps://github.com/ichiban/httpproxyfailover/fork\u003e)\n2. Create your feature branch (`git checkout -b feature/fooBar`)\n3. Commit your changes (`git commit -am 'Add some fooBar'`)\n4. Push to the branch (`git push origin feature/fooBar`)\n5. Create a new Pull Request","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fichiban%2Fhttpproxyfailover","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fichiban%2Fhttpproxyfailover","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fichiban%2Fhttpproxyfailover/lists"}