{"id":19365355,"url":"https://github.com/jsdw/weave","last_synced_at":"2025-04-23T14:31:20.358Z","repository":{"id":93343524,"uuid":"183910405","full_name":"jsdw/weave","owner":"jsdw","description":"A simple CLI router for wiring together several sources behind a single HTTP endpoint","archived":false,"fork":false,"pushed_at":"2020-01-25T14:21:17.000Z","size":201,"stargazers_count":145,"open_issues_count":7,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-02T15:51:12.196Z","etag":null,"topics":["cli","router","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/jsdw.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2019-04-28T13:15:01.000Z","updated_at":"2025-01-19T11:29:06.000Z","dependencies_parsed_at":"2023-04-26T07:16:53.654Z","dependency_job_id":null,"html_url":"https://github.com/jsdw/weave","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdw%2Fweave","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdw%2Fweave/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdw%2Fweave/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdw%2Fweave/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jsdw","download_url":"https://codeload.github.com/jsdw/weave/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250451710,"owners_count":21432877,"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":["cli","router","rust"],"created_at":"2024-11-10T07:39:52.192Z","updated_at":"2025-04-23T14:31:20.351Z","avatar_url":"https://github.com/jsdw.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/jsdw/weave.svg?branch=master)](https://travis-ci.org/jsdw/weave)\n\n# Weave\n\nA simple CLI based HTTP/TCP router/proxy. Useful if you need to wire together a few things and expose them behind a single host/port, or just as a fast, single-binary alternative to `php -s` or `static-server`. Also useful if you need to proxy TCP traffic to another location.\n\n# Examples\n\nForward TCP connections from `localhost:2222` to `1.2.3.4:22`:\n```\nweave tcp://localhost:2222 to 1.2.3.4:22\n```\n\nServe static files from the current directory on `localhost:8080`:\n```\nweave 8080 to .\n```\n\nServe static files from `./client/files` on `localhost:8080`, and redirect HTTP requests starting with `localhost:8080/api` to `localhost:9090`:\n```\nweave 8080 to ./client/files and 8080/api to 9090\n# Examples of routing given the above:\n# http://localhost:8080/api/foo =\u003e http://localhost:9090/foo\n# http://localhost:8080/api/bar/wibble =\u003e http://localhost:9090/bar/wibble\n# http://localhost:8080/ =\u003e ./client/files/index.html\n# http://localhost:8080/somefile =\u003e ./client/files/somefile\n# http://localhost:8080/path/to/somefile =\u003e ./client/files/path/to/somefile\n```\n\nVisit google by navigating to `localhost:8080`:\n```\nweave 8080 to https://www.google.com\n# Examples of routing given the above:\n# http://localhost:8080/ =\u003e https://www.google.com/\n# http://localhost:8080/favicon.ico =\u003e https://www.google.com/favicon.ico\n# http://localhost:8080/favicon.ico/bar =\u003e https://www.google.com/favicon.ico/bar\n```\n\nVisit google by navigating to `localhost:8080/foo`:\n```\nweave 8080/foo to https://www.google.com\n# Examples of routing given the above:\n# http://localhost:8080/ =\u003e No route matches this\n# http://localhost:8080/foo =\u003e https://www.google.com\n# http://localhost:8080/foo/favicon.ico =\u003e https://www.google.com/favicon.ico\n```\n\nServe files in your cwd by navigating to `0.0.0.0:8080` (makes them available to anything that can see your machine):\n```\nweave 0.0.0.0:8080 to ./\n# Examples of routing given the above:\n# http://0.0.0.0:8080/ =\u003e ./index.html\n# http://0.0.0.0:8080/somefile =\u003e ./somefile\n# http://0.0.0.0:8080/path/to/somefile =\u003e ./path/to/somefile\n```\n\nServe exactly `/favicon.ico` using a local file, but the rest of the site via `localhost:9000`:\n```\nweave =8080/favicon.ico to ./favicon.ico and 8080 to 9090\n# Examples of routing given the above:\n# http://localhost:8080/ =\u003e http://localhost:9090\n# http://localhost:8080/favicon.ico =\u003e ./favicon.ico\n# http://localhost:8080/favicon.ico/bar =\u003e http://localhost:9090/favicon.ico/bar\n```\n\nMatch any API version provided and move it to the end of the destination path:\n```\nweave '8080/(version)/api' to 'https://some.site/api/(version)'\n# Examples of routing given the above:\n# http://localhost:8080/v1/api =\u003e https://some.site/api/v1\n# http://localhost:8080/v1/api/foo =\u003e https://some.site/api/v1/foo\n# http://localhost:8080/wibble/api/foo =\u003e https://some.site/api/wibble/foo\n```\n\nServe JSON files in a local folder as exactly `api/(filename)/v1` to mock a simple API:\n```\nweave '=8080/api/(filename)/v1' to './files/(filename).json'\n# Examples of routing given the above:\n# http://localhost:8080/api/foo/v1 =\u003e ./files/foo.json\n# http://localhost:8080/api/bar/v1 =\u003e ./files/bar.json\n# http://localhost:8080/api/bar/v1/wibble =\u003e No route matches this\n```\n\nMatch paths ending in `/api/(filename)` and serve up JSON files from a local folder:\n```\nweave '=8080/(base..)/api/(filename)' to './files/(filename).json'\n# Examples of routing given the above:\n# http://localhost:8080/1/2/3/api/foo =\u003e ./files/foo.json\n# http://localhost:8080/wibble/api/foo =\u003e ./files/foo.json\n# http://localhost:8080/bar/api/foo =\u003e ./files/foo.json\n# http://localhost:8080/api/foo =\u003e No route matches this\n```\n\nReturn HTTP status codes for some paths:\n```\n# Pick a specific status code (only valid HTTP status codes are allowed):\nweave 8080 to statuscode://403\n# The alias \"nothing\" returns a 404 Not Found status:\nweave 8080 to nothing\n```\n\nDeclare routes that do nothing using \"nothing\" (can be useful for scripted use):\n```\nweave nothing and 8080 to 9090\n```\n\n`and` can be used to serve any number of routes simultaneously. Keep reading for more information on the different types of routes, and how they are prioritised.\n\n# Installation\n\n## From pre-built binaries\n\nPrebuilt compressed binaries are available [here](https://github.com/jsdw/weave/releases/latest). Download the compressed `.tar.gz` file for your OS/architecture and decompress it (on MacOS, this is automatic if you double-click the downloaded file).\n\nIf you like, you can download and decompress the latest release on the commandline. On **MacOS**, run:\n\n```\ncurl -L https://github.com/jsdw/weave/releases/download/v0.5.1/weave-v0.5.1-x86_64-apple-darwin.tar.gz | tar -xz\n```\n\nFor **Linux**, run:\n\n```\ncurl -L https://github.com/jsdw/weave/releases/download/v0.5.1/weave-v0.5.1-x86_64-unknown-linux-musl.tar.gz | tar -xz\n```\n\nIn either case, you'll end up with a `weave` binary in your current folder. The examples assume that you have placed this into your `$PATH` so that it can be called from anywhere.\n\n## From source\n\nAlternately, you can compile `weave` from source.\n\nFirst, go to [https://www.rust-lang.org/tools/install](https://www.rust-lang.org/tools/install) and install Rust.\n\nThen to install a release of `weave` (here, v0.5.1), run the following:\n\n```\ncargo install --git https://github.com/jsdw/weave.git --tag v0.5.1 --force\n```\n\nThis installs the latest version of `weave` into a local `.cargo/bin` folder that the rust installation will have prompted you to add to your `$PATH`. The `--force` command overwrites any existing `weave` binary in this folder; you can ditch it if you don't want this behaviour.\n\n# More Information on routing\n\n## Prefix routes\n\nBasic routes like `8080/foo` will match any incoming path whose _prefix_ is the same. Thus, `8080/foo` matches requests to `/foo`, but also `/foo/bar`, `/foo/bar/wibble` and so on.\n\n## Exact routes\n\nIf you'd like to match an exact path only, prefix the source route with `=`. `=8080/foo` matches requests to exactly `/foo` and nothing else.\n\n## Route patterns\n\nTo match on any path fragment provided, you can declare a variable using parentheses. `8080/(foo)/bar` matches `/lark/bar`, `/wibble/bar`, `/lark/bar/foo` and so on. To force exact matching only, as above we can prefix the route with `=`. `=8080/(foo)/bar` will match `/lark/bar` and `/wibble/bar` but not `/lark/bar/foo`. Variables must be basic alphanumeric strings beginning with an ascii letter (numbers, '-' and '_' are allowed in the rest of the string).\n\nTo capture as much of the route as possible, including separating `/`s, you can use a _dotdot_ variable in a path. `8080/(foo..)/bar` will match `/1/bar`, `/1/2/3/bar`, `/1/2/3/bar/4/5` and so on. Once again, prefix the route with `=` for exact matching only. `=8080/(foo..)/bar` will match `/1/bar` and `/1/2/3/bar` but not `/1/2/3/bar/4/5`.\n\nThe variables declared in parentheses in these source paths can be used in the destination paths too, as you might expect. See the examples for some uses of this.\n\nYou can combine uses of `(var1..)` and `(var2)`, and have multiple of each in a given route, but be aware that if there is ambiguity in which part of the route matches which variable, you cannot rely on the variabels containing what you expect.\n\n## Route ordering\n\nIf you combine multiple routes using `and`, they will be sorted in this order:\n\n1. Exact match routes\n2. Exact match routes with route patterns\n3. Prefix routes\n4. Prefix routes with route patterns\n\nWithin these groups, exact match routes and prefix routes are then sorted longest (most specific) first. routes with route patterns are sorted by the order in which they were declared.\n\nWhen matching an incoming request, the first route that matches wins, and the request is redirected to the destination given with that route. This should generally lead to requests being redirected as you would expect; more specific matches will tend to win over less specific matches.\n\n# Known Issues\n\n- Untested on windows, so (at the very least) serving from file paths may not work as expected.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsdw%2Fweave","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjsdw%2Fweave","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsdw%2Fweave/lists"}