Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
1cb3880966 | |||
eabb52a6c0 |
7 changed files with 119 additions and 2 deletions
32
README.md
32
README.md
|
@ -68,6 +68,38 @@ Logs are the privileged place to get information about what Tricot is doing. You
|
|||
- `RUST_LOG=tricot=debug`: Tricot will show for each request the backend to which it is routed. It will also show all of its interactions with Consul
|
||||
- `RUST_LOG=tricot=trace`: Tricot will show details such as the request's headers for all request at all stages of proxying.
|
||||
|
||||
## For developers
|
||||
|
||||
Build Tricot:
|
||||
|
||||
```bash
|
||||
git clone https://git.deuxfleurs.fr/Deuxfleurs/tricot
|
||||
cd tricot
|
||||
cargo build
|
||||
```
|
||||
|
||||
Start Tricot:
|
||||
|
||||
```bash
|
||||
consul agent -dev
|
||||
cargo run -- --letsencrypt-email you@example.com --http-bind-addr [::1]:8080 --https-bind-addr [::1]:4443
|
||||
```
|
||||
|
||||
Register services:
|
||||
|
||||
```bash
|
||||
cd examples/node
|
||||
npm install
|
||||
node server.mjs
|
||||
consul services register -name=localhost -tag="tricot localhost" -address [::1] -port 3000
|
||||
```
|
||||
|
||||
Test it:
|
||||
|
||||
```
|
||||
node client.mjs
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
|
|
1
examples/.gitignore
vendored
Normal file
1
examples/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules
|
11
examples/node/client.mjs
Normal file
11
examples/node/client.mjs
Normal file
|
@ -0,0 +1,11 @@
|
|||
import WebSocket from 'ws';
|
||||
|
||||
const u = 'wss://localhost:4443';
|
||||
//const u = 'ws://localhost:3000';
|
||||
|
||||
const ws = new WebSocket(u, {
|
||||
rejectUnauthorized: false,
|
||||
});
|
||||
|
||||
ws.on('open', () => ws.send('something'))
|
||||
ws.on('message', msg => console.log('received: %s', msg))
|
44
examples/node/package-lock.json
generated
Normal file
44
examples/node/package-lock.json
generated
Normal file
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "nodeserver",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "nodeserver",
|
||||
"version": "1.0.0",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"ws": "^8.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.6.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz",
|
||||
"integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"ws": {
|
||||
"version": "8.6.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz",
|
||||
"integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==",
|
||||
"requires": {}
|
||||
}
|
||||
}
|
||||
}
|
14
examples/node/package.json
Normal file
14
examples/node/package.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "nodeserver",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Quentin Dufour <quentin@deuxfleurs.fr>",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"ws": "^8.6.0"
|
||||
}
|
||||
}
|
9
examples/node/server.mjs
Normal file
9
examples/node/server.mjs
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { WebSocketServer } from 'ws';
|
||||
|
||||
const wss = new WebSocketServer({ port: 3000 });
|
||||
|
||||
wss.on('connection', ws =>
|
||||
ws.on('message', msg => {
|
||||
console.log('received: %s', msg)
|
||||
ws.send(msg)
|
||||
}))
|
10
src/https.rs
10
src/https.rs
|
@ -153,14 +153,20 @@ async fn handle(
|
|||
.ok_or_else(|| anyhow!("Missing host header"))?
|
||||
.to_str()?
|
||||
};
|
||||
let domain = match host.split_once(':') {
|
||||
Some((domain, _port)) => domain,
|
||||
_ => host,
|
||||
};
|
||||
debug!("Matching on domain {}", domain);
|
||||
|
||||
let path = req.uri().path();
|
||||
let accept_encoding = accept_encoding_fork::encodings(req.headers()).unwrap_or_else(|_| vec![]);
|
||||
|
||||
let best_match = proxy_config
|
||||
.entries
|
||||
.iter()
|
||||
.filter(|ent| {
|
||||
ent.host.matches(host)
|
||||
.filter(|ent| {
|
||||
ent.host.matches(domain)
|
||||
&& ent
|
||||
.path_prefix
|
||||
.as_ref()
|
||||
|
|
Loading…
Reference in a new issue