{"id":25425138,"url":"https://github.com/cperez08/h2-proxy","last_synced_at":"2025-06-22T19:05:42.051Z","repository":{"id":57600113,"uuid":"285663138","full_name":"cperez08/h2-proxy","owner":"cperez08","description":"h2 proxy is a proxy handled via HTTP2 server and client useful for gRPC and http2","archived":false,"fork":false,"pushed_at":"2020-09-23T20:10:47.000Z","size":118,"stargazers_count":17,"open_issues_count":0,"forks_count":3,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-07T21:23:09.251Z","etag":null,"topics":["go-grpc","grpc","grpc-proxy","http2","http2-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/cperez08.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":"2020-08-06T20:16:16.000Z","updated_at":"2024-09-25T12:51:59.000Z","dependencies_parsed_at":"2022-09-16T18:51:17.613Z","dependency_job_id":null,"html_url":"https://github.com/cperez08/h2-proxy","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/cperez08/h2-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cperez08%2Fh2-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cperez08%2Fh2-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cperez08%2Fh2-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cperez08%2Fh2-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cperez08","download_url":"https://codeload.github.com/cperez08/h2-proxy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cperez08%2Fh2-proxy/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261348267,"owners_count":23145304,"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","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":["go-grpc","grpc","grpc-proxy","http2","http2-proxy","proxy"],"created_at":"2025-02-16T23:19:39.406Z","updated_at":"2025-06-22T19:05:37.039Z","avatar_url":"https://github.com/cperez08.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# H2-PROXY\n\n[![GoDoc](https://godoc.org/github.com/cperez08/h2-proxy?status.svg)](https://godoc.org/github.com/cperez08/h2-proxy)\n[![codebeat](https://codebeat.co/badges/715a7aa0-2746-450e-9afd-6c8da289bfe7)](https://codebeat.co/projects/github-com-cperez08-h2-proxy-master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/cperez08/h2-proxy)](https://goreportcard.com/report/github.com/cperez08/h2-proxy)\n[![codecov](https://codecov.io/gh/cperez08/h2-proxy/branch/master/graph/badge.svg)](https://codecov.io/gh/cperez08/h2-proxy)\n\nH2-Proxy is a light way proxy yet useful for proxying http2 and gRPC traffic\n\n# Table of Contents\n- [H2-PROXY](#h2-proxy)\n- [Table of Contents](#table-of-contents)\n  - [Features](#features)\n    - [Connection](#connection)\n    - [Load balancing](#load-balancing)\n        - [Algorithms available](#algorithms-available)\n    - [Domain Refresh](#domain-refresh)\n  - [Configuration](#configuration)\n    - [YAML configuration](#yaml-configuration)\n    - [Configuration by environment variables](#configuration-by-environment-variables)\n  - [Launch](#launch)\n    - [Offical Docker image](#offical-docker-image)\n    - [Customer Docker file](#customer-docker-file)\n    - [Binary](#binary)\n  - [Bonus](#bonus)\n  - [Usage with gRPC + Kuberentes](#usage-with-grpc--kuberentes)\n  - [Graphical representation](#graphical-representation)\n  - [TODOs](#todos)\n\n\n## Features\n\n### Connection\nh2-proxy supports http2 and gRPC servers/clients for proxying the request/responses, so far without support for SSL (in TODO list).\n\n### Load balancing\nThe proxy is able to balance the requests against the target defined (if there are multiple IP associated with the same domain) according to the load balancing algorithm defined. Before returning any connection the balancer makes sure the connection selected is active, otherwise, a maximum of 10 retries is done before returning an error. \n\n##### Algorithms available\n- none (default): No balancer means that h2-proxy grabs from the connection pool the first available connection, always in the same order the connections were stored.\n- random: grabs in a random way any of the available connections.\n- round_robin: based in the round-robin algorithm pick an available connection from the pool.\n\n### Domain Refresh\nThe domain refresh helps the proxy to have the latest status of the domain, is useful to keep the load balancer up to date when instances are created, rotated, or deleted.\n\nThe domain refresh is enabled by configuration but also depends if the target is a domain in case of IP it is disabled automatically, also there is a configuration for the refresh rate where the default value is 60 seconds.\n\n## Configuration\nh2-proxy can be set up in two ways via yaml file or environment variables\n\n### YAML configuration\nIf yaml configuration wants to be used then the file needs to be placed inside `/etc/h2-proxy/config.yaml` or set the env var `H2_PROXY_CFG_LOCATION` for a new location.\n\n```yaml\nproxy_address: '0.0.0.0:50060'\nproxy_name: 'h2-proxy'\ntarget_host: 'my-target-domain'\ntarget_port: '50051'\nidle_timeout: 300\nprint_logs: true\ncompact_logs: true\ndns_config:\n  refresh_rate: 45\n  need_refresh: true\n  balancer_alg: round_robin\n```\n\n- `proxy_address:` proxy address is the interface and the port the proxy will be listening on, for docker the ports exposed by the container are 8080 8090 50060 50061, default value is `0.0.0.0:50060`\n- `proxy_name`: is the proxy name, default value is `h2-proxy` this name will be sent in the `X-Proxied-By` header\n- `target_host:` is the server host you want to redirect the call to, this value is mandatory\n- `target_port:` is the target server port, this value is mandatory\n- `idle_timeout:` is the time in seconds the proxy will keep the connection alive if does not receive any request, default value is 300 (5 minutes) \n- `print_logs:` indicates if want basic logs to be printed, so far a very basic functionality is enabled and the logs arenprinted in stdout, default value is `false`\n- `compact_logs:` indicates if some values are shortened when the log is printed to help to reduce the log size\n\nlogs with compact logs disabled:\n\n```log\n2020/01/01 10:10:55 {\"rq_id\": \"c1824516-48e9-4540-9ca3-8720754e145e\", \"rq_path\": \"/user.UserService/CreateUser\", \"rq_proto\": \"HTTP/2.0\", \"elapsed_time_ms\": 2, \"rq_length\": 58, \"rs_length\": 256}\n```\nlogs with compact logs enabled:\n\n```log\n2020/01/01 10:10:14 id:4ef01a36-2ba6-4922-9519-cf63567d68f1 | p: /user.UserService/CreateUser | pr: HTTP/2.0 | ms: 2 | rq_ln: 58 | rs_ln: 256\n```\n\n- `dns_config.refresh_rate:` value in seconds that indicates how often the resolver needs to check the domain in order to update the set of IPs associated with one domain, default value 60 seconds\n- `dns_config.need_refresh:` useful to disable the domain refresh feature, default value is true but in case the target is an IP then this value is set as false\n- `dns_config.balancer_alg:` indicates the load balancing algorithm, the default value is none, possible values are: none, random and round_robin. \n\n### Configuration by environment variables\n\nIn the case the default values in the YAML suits all the needs then a configuration by environment variables can be done.\n\nIf YAML file is not provided the next environment variables are required:\n\n- `H2_PROXY_TARGET_HOST`  - host where the proxy needs to redirect the calls\n- `H2_PROXY_TARGET_PORT`  - target port\n- `H2_PROXY_PRINT_LOGS`   - optional value that indiates if want logs to be printed\n- `H2_PROXY_COMPACT_LOGS` - an optional value that indicates if some keys can be shortened in the logs\n\n## Launch\n\nAfter defining the [configuration](#configuration) strategy is time to start up the project:\n\n### Offical Docker image\n\npull the docker image `docker pull cperez08/h2-proxy` then `docker run -d --name h2-proxy -p 50060:50060 -e H2_PROXY_TARGET_HOST=127.0.0.1 -e H2_PROXY_TARGET_PORT=8080 -e H2_PROXY_PRINT_LOGS=true cperez08/h2-proxy`\n\nchange the values for the real ones\n\n### Customer Docker file\n\n```docker\nFROM cperez08/h2-proxy\nCOPY config.yaml /etc/h2-proxy/config.yaml\n```\n\n`docker build -t my-h2-proxy .`\n\n`docker run -d --name h2-proxy -p 50060:50060 my-h2-proxy`\n\n### Binary\n\ndownload the binary via go get, for this option make sure you have your `$GOPATH/bin` set up in your PATH otherwise copy and paste from that location the binary into the desired destination.\n\n- downlaod `go get -u github.com/cperez08/h2-proxy`\n- run `h2-proxy` (in case the `$GOPATH/bin` is set up in PATH\n- cp `$GOPATH/bin/h2-proxy` my-location/ \u0026\u0026  `./my-location/h2-proxy`\n\nremember either load the environment variables and/or place the config file in an appropriate location.\n\n## Bonus\n\n## Usage with gRPC + Kuberentes\nIn order to proxy gRPC services properly inside a Kubernetes cluster follow these steps:\n\n- Set up the gRPC server, then deploy and create a headless service.\n- Set up the proxy to create the deployment and service.\n- Set up the client gRPC pointing to the proxy, also you need to set up the client in a way this can balance the requests to the different proxy instances, for this support you can follow this [guideline](https://github.com/cperez08/dm-resolver) which explains how to set up properly the client gRPC based in a custom resolver (the one used in this project)\n- Test and start testing with requests\n\n__note: the most important part of this set up is the [headless service](https://kubernetes.io/docs/concepts/services-networking/service/#headless-services)__ that needs to be done for the server and for the proxy (in the aforementioned example), with this configuration Kubernetes keeps up to date all the pod's IP related to the service, so the resolver keeps in sync all the IPs where the calls need to be redirected.\n\n## Graphical representation\n\n![Basic Diagram](./docs/images/basic_diagram.png)\n\n## TODOs\n\n- [ ] Add support for SSL\n- [ ] Add circuit break\n- [ ] Add support for multiple IPs\n- [ ] Add more load balancing alghoritms\n- [ ] Improve logging\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcperez08%2Fh2-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcperez08%2Fh2-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcperez08%2Fh2-proxy/lists"}