{"id":13713941,"url":"https://github.com/schnoddelbotz/uds-proxy","last_synced_at":"2025-10-16T00:36:48.064Z","repository":{"id":57553931,"uuid":"188707338","full_name":"schnoddelbotz/uds-proxy","owner":"schnoddelbotz","description":"uds-proxy provides a UNIX domain socket that acts as HTTP(S) connection-pooling forward proxy","archived":false,"fork":false,"pushed_at":"2019-06-05T00:17:28.000Z","size":62,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-19T15:52:28.451Z","etag":null,"topics":["connection-pooling","domain-socket","go","http","https","prometheus-metrics","proxy","unix"],"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/schnoddelbotz.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}},"created_at":"2019-05-26T16:34:10.000Z","updated_at":"2024-12-09T04:12:26.000Z","dependencies_parsed_at":"2022-09-26T19:30:48.616Z","dependency_job_id":null,"html_url":"https://github.com/schnoddelbotz/uds-proxy","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/schnoddelbotz/uds-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schnoddelbotz%2Fuds-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schnoddelbotz%2Fuds-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schnoddelbotz%2Fuds-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schnoddelbotz%2Fuds-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/schnoddelbotz","download_url":"https://codeload.github.com/schnoddelbotz/uds-proxy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schnoddelbotz%2Fuds-proxy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273523047,"owners_count":25120859,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"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":["connection-pooling","domain-socket","go","http","https","prometheus-metrics","proxy","unix"],"created_at":"2024-08-02T23:01:48.231Z","updated_at":"2025-10-16T00:36:47.989Z","avatar_url":"https://github.com/schnoddelbotz.png","language":"Go","readme":"# uds-proxy [![goreportcard](https://goreportcard.com/badge/github.com/schnoddelbotz/uds-proxy)](https://goreportcard.com/report/github.com/schnoddelbotz/uds-proxy) [![GoDoc](https://godoc.org/github.com/PuerkitoBio/rehttp?status.png)](https://godoc.org/github.com/schnoddelbotz/uds-proxy/proxy)\n\nuds-proxy provides a UNIX domain socket and forwards traffic to HTTP(S) remotes\nthrough a customizable connection pool (i.e. using persistent connections).\n\n## what for? why? how?\nInteracting with microservices often involves communication overhead: Every contact\nwith another service may involve DNS lookups and establishment of a TCP connection\nplus, most likely, a HTTPS handshake.\n\nThis overhead can be costly and especially hard to circumvent for legacy applications -- thus uds-proxy.\n\nuds-proxy creates a UNIX domain socket and forwards communication to one or more\nremote web servers. In a way, uds-proxy aims a bit at reducing application/API complexity by\nproviding a generic and simple solution for connection pooling.\n\nuds-proxy is implemented in Go, so it runs as native application on any\nOS supporting Go and UNIX domain sockets (i.e. not on Windows). Critical\nperformance metrics of uds-proxy (request latencies, response codes...)\nand Go process statistics are exposed through Prometheus client library.\n\n## building / installing uds-proxy\n\nBuilding requires a local Go 1.11+ installation:\n\n```bash\ngo get -v github.com/schnoddelbotz/uds-proxy/cmd/uds-proxy\n```\n\n... or just grab a [uds-proxy binary release](https://github.com/schnoddelbotz/uds-proxy/releases).\n\nSee [usage-example-for-an-https-endpoint](#usage-example-for-an-https-endpoint) for Docker usage.\n\nTo start uds-proxy at system boot, create e.g. a systemd unit.\nDon't try to run uds-proxy as root. It won't start.\n\n## usage\n\n```\nUsage of ./uds-proxy:\n  -client-timeout int\n      http client connection timeout [ms] for proxy requests (default 5000)\n  -idle-timeout int\n      connection timeout [ms] for idle backend connections (default 90000)\n  -max-conns-per-host int\n      maximum number of connections per backend host (default 20)\n  -max-idle-conns int\n      maximum number of idle HTTP(S) connections (default 100)\n  -max-idle-conns-per-host int\n      maximum number of idle conns per backend (default 25)\n  -no-access-log\n    \tdisable proxy access logging\n  -no-log-timestamps\n      disable timestamps in log messages\n  -pid-file string\n      pid file to use, none if empty\n  -prometheus-port string\n      Prometheus monitoring port, e.g. :18080\n  -remote-https\n      remote uses https://\n  -socket string\n      path of socket to create\n  -socket-read-timeout int\n      read timeout [ms] for -socket (default 5000)\n  -socket-write-timeout int\n      write timeout [ms] for -socket (default 5000)\n  -version\n      print uds-proxy version\n```\n\n## monitoring / testing / development\n\nClone this repository and check the [Makefile](Makefile) targets.\n\nMost relevant `make` targets:\n\n- `make monitoring_test` spins up Prometheus, grafana and uds-proxy using Docker and\n  starts another uds-proxy instance locally (outside Docker, on Mac only). The uds-proxy instances will be\n  scraped by dockerized Prometheus and Grafana will provide dashboards.\n  See [monitoring/README.md](monitoring/README.md) for details.\n- `make run_proxy` starts a local uds-proxy instance for testing purposes.\n  `TEST_SOCKET` environment variable controls socket location, defaults\n  to `uds-proxy-test.socket`.\n- `make test` runs unit and functional tests from [proxy_test](proxy_test) directory.\n- `make coverage` generates code test coverage statistics.\n- `make test_integration` starts a local uds-proxy and runs some proxied-vs-non-proxied perf tests.\n- `make realclean` removes leftovers from tests or builds.\n\n### usage example for an HTTPS endpoint\nStart the proxy:\n\n```bash\nuds-proxy -socket /tmp/proxied-svc.sock -prometheus-port :28080 -remote-https\n```\n\nDocker users:\n\n```bash\nmkdir -p /tmp/mysock_dir\ndocker run --rm -it -p28080:28080 -v/tmp/mysock_dir:/tmp schnoddelbotz/uds-proxy\n```\n\nFor both cases, metrics should be available at http://localhost:28080/metrics while uds-proxy is running.\n\n#### using bash / curl\n```bash\n# without uds-proxy, you would...\ntime curl -I https://www.google.com/\n\n# with uds-proxy, always ...\n# a) talk through socket and\n# b) use http:// and let `-remote-https` ensure https is used to connect to remote hosts\ntime curl -I --unix-socket /tmp/proxied-svc.sock http://www.google.com/\n# ... or using socket provided by dockerized uds-proxy:\ntime curl -I --unix-socket /tmp/mysock_dir/uds-proxy-docker.sock http://www.google.com/\n```\n\n#### using php / curl\n```php\n\u003c?php\n// without uds-proxy\n$ch = curl_init();\ncurl_setopt($ch, CURLOPT_URL, \"https://www.google.com/\");\ncurl_exec($ch);\n\n// with uds-proxy\n$ch = curl_init();\ncurl_setopt($ch, CURLOPT_URL, \"http://www.google.com/\");\ncurl_setopt($ch, CURLOPT_UNIX_SOCKET_PATH, \"/tmp/proxied-svc.sock\");\ncurl_exec($ch);\n```\n\n### further socket testing\n\nMac's (i.e. BSD's) netcat allows to talk to unix domain sockets.\nIt can be used to e.g. ensure correct behaviour of uds-proxy's\n`-socket-(read|write)-timeout` options. Try `nc -U /path/to/uds-proxy.sock`.\n\n## todo ...\n\n- fix/drop sudo nobody for dockerized tests\n- fixme: add option [-dont-follow-redirects](https://stackoverflow.com/questions/23297520/how-can-i-make-the-go-http-client-not-follow-redirects-automatically)\n- for http/s client:\n  - wrap in circuit breaker?\n  - wrap in retry /w exponential backoff? consider api consumer constraints (i.e. timeout - worth it?)\n- travis-ci + github release push\n- example systemd unit\n- sock umask / cli opt\n- support magic uds request headers...?\n  - X-udsproxy-timeout: 250ms\n  - X-udsproxy-debug: true\n\n## links\n\n- https://godoc.org/gotest.tools/assert\n- https://golang.org/pkg/net/#hdr-Name_Resolution\n- https://stackoverflow.com/questions/17948827/reusing-http-connections-in-golang\n- https://medium.com/@povilasve/go-advanced-tips-tricks-a872503ac859\n- https://github.com/bouk/monkey/blob/master/monkey_test.go\n- https://github.com/prometheus/client_golang/blob/master/prometheus/examples_test.go\n- https://github.com/prometheus/client_golang/blob/master/prometheus/promhttp/instrument_server.go\n\n## alternatives\n\nObviously, uds-proxy is a kludge. Simply use connection pooling if available!\n\n- for Python and HTTP, simply reuse [requests library's session objects](https://2.python-requests.org/en/master/user/advanced/#session-objects) and you're set\n- for Python and Redis, use a [redis.py connection pool](https://github.com/andymccurdy/redis-py#connection-pools)\n- for Redis and PHP, [phpredis](https://github.com/phpredis/phpredis) supports connection pooling since v4.2.1\n- a potentially more sophisticated solution can be found in\n  [this TCP vs UDS speed comparison stackoverflow thread](https://stackoverflow.com/questions/14973942/performance-tcp-loopback-connection-vs-unix-domain-socket):\n  [Speedus](http://speedus.torusware.com/) intercepts relevant system calls, which avoids\n  need for any code changes. However, if I understood correctly, Speedus only helps if\n  services actually sit on the same host system (?).\n\nMaybe look at [phantom](https://github.com/Flipkart/phantom)?\n\nYou can also use NGINX [to create a UDS HTTP/S pooling forward proxy](https://serverfault.com/questions/899109/universal-persistent-connection-pool-proxy-with-nginx) like uds-proxy.\nIt seems that neither [Apache](https://bz.apache.org/bugzilla/show_bug.cgi?id=55898)\nnor Squid (?) are able to do that.\n\n## license\n\nMIT\n","funding_links":[],"categories":["Repositories"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschnoddelbotz%2Fuds-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschnoddelbotz%2Fuds-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschnoddelbotz%2Fuds-proxy/lists"}