{"id":20454890,"url":"https://github.com/robb-j/goldiprox","last_synced_at":"2026-05-14T20:32:39.100Z","repository":{"id":187778921,"uuid":"676731118","full_name":"robb-j/goldiprox","owner":"robb-j","description":"A minimal proxy \u0026 redirect server with static and remote configuration","archived":false,"fork":false,"pushed_at":"2025-10-31T20:02:07.000Z","size":123,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-31T22:03:59.287Z","etag":null,"topics":["deno","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robb-j.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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}},"created_at":"2023-08-09T22:02:24.000Z","updated_at":"2025-10-31T20:02:11.000Z","dependencies_parsed_at":"2025-07-25T05:26:42.012Z","dependency_job_id":"beb44c1e-c922-4a99-a83b-3e2311b6d98b","html_url":"https://github.com/robb-j/goldiprox","commit_stats":null,"previous_names":["robb-j/goldiprox"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/robb-j/goldiprox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robb-j%2Fgoldiprox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robb-j%2Fgoldiprox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robb-j%2Fgoldiprox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robb-j%2Fgoldiprox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robb-j","download_url":"https://codeload.github.com/robb-j/goldiprox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robb-j%2Fgoldiprox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33042162,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"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":["deno","typescript"],"created_at":"2024-11-15T11:17:18.884Z","updated_at":"2026-05-14T20:32:39.092Z","avatar_url":"https://github.com/robb-j.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# goldiprox\n\nA little programmable proxy built with [Deno](https://deno.land/) and based on\n[URLPattern](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern)\n\n## About\n\nGoldiprox is a minimal reverse-proxy and redirection server with routing based\non the (semi) web-standards URLPattern. It is either configured with a static\nset of routes or it can pull down the routes to serve from a HTTP endpoint.\n\n### redirect\n\nRoutes are a URLPattern and a target to tell it how to process the request. This\nis a simple redirection endpoint:\n\n```json\n{\n  \"pattern\": \"https://example.com\",\n  \"type\": \"redirect\",\n  \"url\": \"https://r0b.io\"\n}\n```\n\nWhen the server gets a request for `https://example.com` it will return an HTTP\nredirect to `https://r0b.io`. This gets more interesting with the use of\nparameters or wildcards in the pattern:\n\n```json\n{\n  \"pattern\": \"https://example.com/*\",\n  \"type\": \"redirect\",\n  \"url\": \"https://r0b.io/example/{{ pathname.groups.0 }}\"\n}\n```\n\nHere we are starting to use the URLPattern more. In the pattern configuration,\nit now matches a wildcard pathname on the host `example.com` under the `https`\nprotocol is matched. Then in the target URL, it is using the match from the\nURLPattern to template a URL with the same path but prefixed with `/example/`.\nFor example:\n\n- `https://example.com/` → `https://r0b.io/example/`\n- `https://example.com/hello` → `https://r0b.io/example/hello`\n\nYou can even match on other parts of the request, such as the subdomain:\n\n```json\n{\n  \"pattern\": \"https://:subdomain.example.com/*\",\n  \"type\": \"redirect\",\n  \"url\": \"https://r0b.io/example/{{ hostname.groups.subdomain }}/{{ pathname.groups.0 }}\"\n}\n```\n\nHere it will use whatever subdomain you have visited and add it to the pathname\nin the redirection it generates. You can see here we've created a parameter\nnamed `subdomain` and we can reference that in the URL template. With wildcards,\nthey are numbered incrementally, but you can give them names instead.\n\nThe pattern doesn't have to be just a string too, you can specify it partwise to\nonly specify the bits that are interesting. The pattern is actually a subset of\nwhat you can pass to the first parameter of\n[URLPattern](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern/URLPattern).\nThe templating in the URL lets you reference anything from the result of\n[URLPattern#exec](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern/exec).\n\n\u003e There are some fields in the\n\u003e [input](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern/URLPattern#parameters)\n\u003e that don't make sense in this context so they are emitted, namely\n\u003e `username,password,baseURL,port`.\n\n```json\n{\n  \"pattern\": { \"hostname\": \"example.com\" },\n  \"type\": \"redirect\",\n  \"url\": \"https://r0b.io/example{{ pathname.groups.* }}\"\n}\n```\n\n\u003e I also made this tool,\n\u003e [URLPattern Editor](https://urlpattern.r0b.io/?ref=goldiprox), which helps\n\u003e construct patterns completely in the browser\n\nThis is the same as before but is set on a per-component basis, it will use a\nwildcard for any component not set, such as the protocol and pathname in this\ncase. Also note that the wildcard in pathname includes the `/` prefix, so you\ndon't need to put it in the URL template here.\n\n### proxy\n\nSo far this has all been about redirection, but the other power is in proxying\nrequests. This lets you rewrite requests to look a different way or access\nthings on networks not available to the client:\n\n```json\n{\n  \"pattern\": { \"hostname\": \":version.example.com\", \"pathname\": \"/:path*\" },\n  \"type\": \"proxy\",\n  \"url\": \"https://s3.r0b.io/{{ hostname.groups.version }}/{{ pathname.groups.path }}\"\n}\n```\n\nIn this example, it proxies the request to a fictional S3 server to serve\nversioned assets at a different location:\n\n- `https://v1.example.com/` → `https://s3.r0b.io/v1/`\n- `https://v1.example.com/index.html` → `https://s3.r0b.io/v1/index.html`\n- `https://v1.example.com/js/script.js` → `https://s3.r0b.io/v1/js/script.js`\n\nFrom the requester's perspective they won't see `s3.r0b.io` as the request is\nproxied by the server instead.\n\nYou can tell Goldiprox to inject headers or search parameters by adding\n`addHeaders` or `addSearchParams` fields to your route definitions. Headers\ninjected to `proxy` routes and search parameters are added to the query string\nfor `proxy` and `redirect` routes:\n\n```json\n{\n  \"pattern\": { \"pathname\": \"/\" },\n  \"type\": \"proxy\",\n  \"url\": \"https://example.com\",\n  \"addHeaders\": {\n    \"Authorization\": \"top_secret\"\n  },\n  \"addSearchParams\": {\n    \"ref\": \"goldiprox\"\n  },\n  \"redirects\": [\n    {\n      \"pattern\": \"https://example.com/*\",\n      \"url\": \"http://localhost:8080/{{ pathname.groups.0 }}\"\n    }\n  ]\n}\n```\n\nWhile proxying, the `Authorization` header will be injected into the proxy\nrequest and the `?ref=goldiprox` is added to the end of the URL. You can do the\nsame with a `redirect` route, but you can't set headers, that only works with\n`proxy` routes.\n\nWith a `proxy` route, you can also configure `redirects` which will process the\n`Location:` header to rewrite it to something else.\n\nGoldiproxy can periodically fetch the routes from an external HTTP endpoint to\nlet them change on demand to do cool and interesting things. See Configuration\nbelow.\n\n### website\n\nAnother type of route is for turning static assets into a website, this works\nlike nginx where it will look for\n[index](https://docs.nginx.com/nginx/admin-guide/web-server/serving-static-content/)\nfiles based on the URL being requested. Under the hood it uses the\n[proxy](#proxy) to perform requests and handle redirects in the same way.\n\nFor example, if you request `https://example.com/` it will try\n`https://example.com/index.html`.\n\n```json\n{\n  \"pattern\": { \"hostname\": \":domain.example.com\" },\n  \"type\": \"website\",\n  \"url\": \"https://s3.r0b.io/{{ hostname.groups.domain }}/{{ pathname.groups.path }}\",\n  \"index\": [\"index.html\", \"index.htm\"]\n}\n```\n\nYou can set the same parameters as [proxy](#proxy) with the extra optional\n`index` which is used to set which files to try and request. By default it will\njust try `index.html`.\n\n## Configuration\n\nRun Goldiprox with a JSON configuration, `config.json`, which is an array of the\n`routes`, as described above. You can also specify an `endpoint` which goldiprox\nwill use to periodically fetch routes and merge them with the static `routes`,\nboth `routes` and `endpoint` are optional so you can set one, both or neither.\nAlthough setting neither would be a pretty boring server.\n\n```json\n{\n  \"routes\": [\"…\"],\n  \"endpoint\": {\n    \"url\": \"https://r0b.io/goldiprox-routes\",\n    \"interval\": 10000\n  }\n}\n```\n\nIf `endpoint` is specified, Goldiprox will fetch the routes on start up then\nrefetch at the specified interval. The interval is in **milliseconds**.\n\n\u003e Routes are sorted in a rough way so that more-specific definitions are first\n\u003e and parameter-based or wildcard routes come later. This needs to be better\n\u003e tested.\n\n## Deployment\n\nGoldiprox is designed to be run as a container however you like to run your\ncontainers. It runs as a non-root user `id=1000`, it internally uses port `8000`\nand you should mount your config at `/app/config.json`.\n\n\u003e WIP\n\n## Release\n\n1. Ensure git is clean and the changelog is up-to-date\n2. Update the version in `app.json`\n3. Commit as `vX.Y.X`\n4. Tag as `vX.Y.Z`, signed with the same message\n5. Push to GitHub\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobb-j%2Fgoldiprox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobb-j%2Fgoldiprox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobb-j%2Fgoldiprox/lists"}