tangled
alpha
login
or
join now
directxman12.dev
/
proxy-in-anger
a (hacky, wip) multi-tenant oidc-terminating reverse proxy, written in anger on top of pingora
0
fork
atom
overview
issues
pulls
pipelines
Compare changes
Choose any two refs to compare.
base:
wip/primary
main
no tags found
compare:
wip/primary
main
no tags found
go
+905
-10
7 changed files
expand all
collapse all
unified
split
Cargo.lock
Cargo.toml
build.rs
flake.nix
src
config
format.proto
config.rs
main.rs
+390
-7
Cargo.lock
···
117
117
]
118
118
119
119
[[package]]
120
120
+
name = "anyhow"
121
121
+
version = "1.0.101"
122
122
+
source = "registry+https://github.com/rust-lang/crates.io-index"
123
123
+
checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea"
124
124
+
125
125
+
[[package]]
120
126
name = "arc-swap"
121
127
version = "1.8.1"
122
128
source = "registry+https://github.com/rust-lang/crates.io-index"
···
192
198
version = "0.1.0"
193
199
dependencies = [
194
200
"async-trait",
201
201
+
"color-eyre",
202
202
+
"http",
195
203
"pingora",
204
204
+
"prost",
205
205
+
"prost-reflect",
206
206
+
"prost-reflect-build",
207
207
+
"rustls",
208
208
+
"tokio",
209
209
+
"tracing",
210
210
+
"tracing-subscriber",
196
211
]
197
212
198
213
[[package]]
···
243
258
version = "0.22.1"
244
259
source = "registry+https://github.com/rust-lang/crates.io-index"
245
260
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
261
261
+
262
262
+
[[package]]
263
263
+
name = "beef"
264
264
+
version = "0.5.2"
265
265
+
source = "registry+https://github.com/rust-lang/crates.io-index"
266
266
+
checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
246
267
247
268
[[package]]
248
269
name = "bitflags"
···
423
444
]
424
445
425
446
[[package]]
447
447
+
name = "color-eyre"
448
448
+
version = "0.6.5"
449
449
+
source = "registry+https://github.com/rust-lang/crates.io-index"
450
450
+
checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d"
451
451
+
dependencies = [
452
452
+
"backtrace",
453
453
+
"color-spantrace",
454
454
+
"eyre",
455
455
+
"indenter",
456
456
+
"once_cell",
457
457
+
"owo-colors",
458
458
+
"tracing-error",
459
459
+
]
460
460
+
461
461
+
[[package]]
462
462
+
name = "color-spantrace"
463
463
+
version = "0.3.0"
464
464
+
source = "registry+https://github.com/rust-lang/crates.io-index"
465
465
+
checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427"
466
466
+
dependencies = [
467
467
+
"once_cell",
468
468
+
"owo-colors",
469
469
+
"tracing-core",
470
470
+
"tracing-error",
471
471
+
]
472
472
+
473
473
+
[[package]]
426
474
name = "colorchoice"
427
475
version = "1.0.4"
428
476
source = "registry+https://github.com/rust-lang/crates.io-index"
···
644
692
]
645
693
646
694
[[package]]
695
695
+
name = "eyre"
696
696
+
version = "0.6.12"
697
697
+
source = "registry+https://github.com/rust-lang/crates.io-index"
698
698
+
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
699
699
+
dependencies = [
700
700
+
"indenter",
701
701
+
"once_cell",
702
702
+
]
703
703
+
704
704
+
[[package]]
705
705
+
name = "fastrand"
706
706
+
version = "2.3.0"
707
707
+
source = "registry+https://github.com/rust-lang/crates.io-index"
708
708
+
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
709
709
+
710
710
+
[[package]]
647
711
name = "find-msvc-tools"
648
712
version = "0.1.9"
649
713
source = "registry+https://github.com/rust-lang/crates.io-index"
650
714
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
715
715
+
716
716
+
[[package]]
717
717
+
name = "fixedbitset"
718
718
+
version = "0.5.7"
719
719
+
source = "registry+https://github.com/rust-lang/crates.io-index"
720
720
+
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
651
721
652
722
[[package]]
653
723
name = "flate2"
···
665
735
version = "1.0.7"
666
736
source = "registry+https://github.com/rust-lang/crates.io-index"
667
737
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
738
738
+
739
739
+
[[package]]
740
740
+
name = "foldhash"
741
741
+
version = "0.1.5"
742
742
+
source = "registry+https://github.com/rust-lang/crates.io-index"
743
743
+
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
668
744
669
745
[[package]]
670
746
name = "foldhash"
···
845
921
846
922
[[package]]
847
923
name = "hashbrown"
924
924
+
version = "0.15.5"
925
925
+
source = "registry+https://github.com/rust-lang/crates.io-index"
926
926
+
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
927
927
+
dependencies = [
928
928
+
"foldhash 0.1.5",
929
929
+
]
930
930
+
931
931
+
[[package]]
932
932
+
name = "hashbrown"
848
933
version = "0.16.1"
849
934
source = "registry+https://github.com/rust-lang/crates.io-index"
850
935
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
851
936
dependencies = [
852
937
"allocator-api2",
853
938
"equivalent",
854
854
-
"foldhash",
939
939
+
"foldhash 0.2.0",
855
940
]
856
941
857
942
[[package]]
···
912
997
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
913
998
914
999
[[package]]
1000
1000
+
name = "indenter"
1001
1001
+
version = "0.3.4"
1002
1002
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1003
1003
+
checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5"
1004
1004
+
1005
1005
+
[[package]]
915
1006
name = "indexmap"
916
1007
version = "1.9.3"
917
1008
source = "registry+https://github.com/rust-lang/crates.io-index"
···
938
1029
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
939
1030
940
1031
[[package]]
1032
1032
+
name = "itertools"
1033
1033
+
version = "0.14.0"
1034
1034
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1035
1035
+
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
1036
1036
+
dependencies = [
1037
1037
+
"either",
1038
1038
+
]
1039
1039
+
1040
1040
+
[[package]]
941
1041
name = "itoa"
942
1042
version = "1.0.17"
943
1043
source = "registry+https://github.com/rust-lang/crates.io-index"
···
976
1076
]
977
1077
978
1078
[[package]]
1079
1079
+
name = "linux-raw-sys"
1080
1080
+
version = "0.11.0"
1081
1081
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1082
1082
+
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
1083
1083
+
1084
1084
+
[[package]]
979
1085
name = "local-ip-address"
980
1086
version = "0.6.10"
981
1087
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1002
1108
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
1003
1109
1004
1110
[[package]]
1111
1111
+
name = "logos"
1112
1112
+
version = "0.15.1"
1113
1113
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1114
1114
+
checksum = "ff472f899b4ec2d99161c51f60ff7075eeb3097069a36050d8037a6325eb8154"
1115
1115
+
dependencies = [
1116
1116
+
"logos-derive",
1117
1117
+
]
1118
1118
+
1119
1119
+
[[package]]
1120
1120
+
name = "logos-codegen"
1121
1121
+
version = "0.15.1"
1122
1122
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1123
1123
+
checksum = "192a3a2b90b0c05b27a0b2c43eecdb7c415e29243acc3f89cc8247a5b693045c"
1124
1124
+
dependencies = [
1125
1125
+
"beef",
1126
1126
+
"fnv",
1127
1127
+
"lazy_static",
1128
1128
+
"proc-macro2",
1129
1129
+
"quote",
1130
1130
+
"regex-syntax",
1131
1131
+
"rustc_version",
1132
1132
+
"syn 2.0.114",
1133
1133
+
]
1134
1134
+
1135
1135
+
[[package]]
1136
1136
+
name = "logos-derive"
1137
1137
+
version = "0.15.1"
1138
1138
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1139
1139
+
checksum = "605d9697bcd5ef3a42d38efc51541aa3d6a4a25f7ab6d1ed0da5ac632a26b470"
1140
1140
+
dependencies = [
1141
1141
+
"logos-codegen",
1142
1142
+
]
1143
1143
+
1144
1144
+
[[package]]
1005
1145
name = "lru"
1006
1146
version = "0.16.3"
1007
1147
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1011
1151
]
1012
1152
1013
1153
[[package]]
1154
1154
+
name = "matchers"
1155
1155
+
version = "0.2.0"
1156
1156
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1157
1157
+
checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
1158
1158
+
dependencies = [
1159
1159
+
"regex-automata",
1160
1160
+
]
1161
1161
+
1162
1162
+
[[package]]
1014
1163
name = "memchr"
1015
1015
-
version = "2.7.6"
1164
1164
+
version = "2.8.0"
1016
1165
source = "registry+https://github.com/rust-lang/crates.io-index"
1017
1017
-
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
1166
1166
+
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
1018
1167
1019
1168
[[package]]
1020
1169
name = "memoffset"
···
1051
1200
"wasi",
1052
1201
"windows-sys 0.61.2",
1053
1202
]
1203
1203
+
1204
1204
+
[[package]]
1205
1205
+
name = "multimap"
1206
1206
+
version = "0.10.1"
1207
1207
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1208
1208
+
checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
1054
1209
1055
1210
[[package]]
1056
1211
name = "neli"
···
1110
1265
]
1111
1266
1112
1267
[[package]]
1268
1268
+
name = "nu-ansi-term"
1269
1269
+
version = "0.50.3"
1270
1270
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1271
1271
+
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
1272
1272
+
dependencies = [
1273
1273
+
"windows-sys 0.61.2",
1274
1274
+
]
1275
1275
+
1276
1276
+
[[package]]
1113
1277
name = "num-bigint"
1114
1278
version = "0.4.6"
1115
1279
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1204
1368
]
1205
1369
1206
1370
[[package]]
1371
1371
+
name = "owo-colors"
1372
1372
+
version = "4.2.3"
1373
1373
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1374
1374
+
checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52"
1375
1375
+
1376
1376
+
[[package]]
1207
1377
name = "parking_lot"
1208
1378
version = "0.12.5"
1209
1379
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1231
1401
version = "2.3.2"
1232
1402
source = "registry+https://github.com/rust-lang/crates.io-index"
1233
1403
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
1404
1404
+
1405
1405
+
[[package]]
1406
1406
+
name = "petgraph"
1407
1407
+
version = "0.8.3"
1408
1408
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1409
1409
+
checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
1410
1410
+
dependencies = [
1411
1411
+
"fixedbitset",
1412
1412
+
"hashbrown 0.15.5",
1413
1413
+
"indexmap 2.13.0",
1414
1414
+
]
1234
1415
1235
1416
[[package]]
1236
1417
name = "pin-project-lite"
···
1526
1707
]
1527
1708
1528
1709
[[package]]
1710
1710
+
name = "prettyplease"
1711
1711
+
version = "0.2.37"
1712
1712
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1713
1713
+
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
1714
1714
+
dependencies = [
1715
1715
+
"proc-macro2",
1716
1716
+
"syn 2.0.114",
1717
1717
+
]
1718
1718
+
1719
1719
+
[[package]]
1529
1720
name = "proc-macro-error-attr2"
1530
1721
version = "2.0.0"
1531
1722
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1585
1776
]
1586
1777
1587
1778
[[package]]
1779
1779
+
name = "prost"
1780
1780
+
version = "0.14.3"
1781
1781
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1782
1782
+
checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
1783
1783
+
dependencies = [
1784
1784
+
"bytes",
1785
1785
+
"prost-derive",
1786
1786
+
]
1787
1787
+
1788
1788
+
[[package]]
1789
1789
+
name = "prost-build"
1790
1790
+
version = "0.14.3"
1791
1791
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1792
1792
+
checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7"
1793
1793
+
dependencies = [
1794
1794
+
"heck 0.5.0",
1795
1795
+
"itertools",
1796
1796
+
"log",
1797
1797
+
"multimap",
1798
1798
+
"petgraph",
1799
1799
+
"prettyplease",
1800
1800
+
"prost",
1801
1801
+
"prost-types",
1802
1802
+
"regex",
1803
1803
+
"syn 2.0.114",
1804
1804
+
"tempfile",
1805
1805
+
]
1806
1806
+
1807
1807
+
[[package]]
1808
1808
+
name = "prost-derive"
1809
1809
+
version = "0.14.3"
1810
1810
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1811
1811
+
checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
1812
1812
+
dependencies = [
1813
1813
+
"anyhow",
1814
1814
+
"itertools",
1815
1815
+
"proc-macro2",
1816
1816
+
"quote",
1817
1817
+
"syn 2.0.114",
1818
1818
+
]
1819
1819
+
1820
1820
+
[[package]]
1821
1821
+
name = "prost-reflect"
1822
1822
+
version = "0.16.3"
1823
1823
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1824
1824
+
checksum = "b89455ef41ed200cafc47c76c552ee7792370ac420497e551f16123a9135f76e"
1825
1825
+
dependencies = [
1826
1826
+
"logos",
1827
1827
+
"prost",
1828
1828
+
"prost-reflect-derive",
1829
1829
+
"prost-types",
1830
1830
+
]
1831
1831
+
1832
1832
+
[[package]]
1833
1833
+
name = "prost-reflect-build"
1834
1834
+
version = "0.16.0"
1835
1835
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1836
1836
+
checksum = "8214ae2c30bbac390db0134d08300e770ef89b6d4e5abf855e8d300eded87e28"
1837
1837
+
dependencies = [
1838
1838
+
"prost-build",
1839
1839
+
"prost-reflect",
1840
1840
+
]
1841
1841
+
1842
1842
+
[[package]]
1843
1843
+
name = "prost-reflect-derive"
1844
1844
+
version = "0.16.0"
1845
1845
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1846
1846
+
checksum = "7b6d90e29fa6c0d13c2c19ba5e4b3fb0efbf5975d27bcf4e260b7b15455bcabe"
1847
1847
+
dependencies = [
1848
1848
+
"proc-macro2",
1849
1849
+
"quote",
1850
1850
+
"syn 2.0.114",
1851
1851
+
]
1852
1852
+
1853
1853
+
[[package]]
1854
1854
+
name = "prost-types"
1855
1855
+
version = "0.14.3"
1856
1856
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1857
1857
+
checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7"
1858
1858
+
dependencies = [
1859
1859
+
"prost",
1860
1860
+
]
1861
1861
+
1862
1862
+
[[package]]
1588
1863
name = "protobuf"
1589
1864
version = "2.28.0"
1590
1865
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1752
2027
checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"
1753
2028
1754
2029
[[package]]
2030
2030
+
name = "rustc_version"
2031
2031
+
version = "0.4.1"
2032
2032
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2033
2033
+
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
2034
2034
+
dependencies = [
2035
2035
+
"semver",
2036
2036
+
]
2037
2037
+
2038
2038
+
[[package]]
1755
2039
name = "rusticata-macros"
1756
2040
version = "4.1.0"
1757
2041
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1761
2045
]
1762
2046
1763
2047
[[package]]
2048
2048
+
name = "rustix"
2049
2049
+
version = "1.1.3"
2050
2050
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2051
2051
+
checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34"
2052
2052
+
dependencies = [
2053
2053
+
"bitflags 2.10.0",
2054
2054
+
"errno",
2055
2055
+
"libc",
2056
2056
+
"linux-raw-sys",
2057
2057
+
"windows-sys 0.61.2",
2058
2058
+
]
2059
2059
+
2060
2060
+
[[package]]
1764
2061
name = "rustls"
1765
2062
version = "0.23.36"
1766
2063
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1826
2123
1827
2124
[[package]]
1828
2125
name = "ryu"
1829
1829
-
version = "1.0.22"
2126
2126
+
version = "1.0.23"
1830
2127
source = "registry+https://github.com/rust-lang/crates.io-index"
1831
1831
-
checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984"
2128
2128
+
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
1832
2129
1833
2130
[[package]]
1834
2131
name = "schannel"
···
1869
2166
]
1870
2167
1871
2168
[[package]]
2169
2169
+
name = "semver"
2170
2170
+
version = "1.0.27"
2171
2171
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2172
2172
+
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
2173
2173
+
2174
2174
+
[[package]]
1872
2175
name = "serde"
1873
2176
version = "1.0.228"
1874
2177
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1920
2223
"base64",
1921
2224
"indexmap 2.13.0",
1922
2225
"rust_decimal",
2226
2226
+
]
2227
2227
+
2228
2228
+
[[package]]
2229
2229
+
name = "sharded-slab"
2230
2230
+
version = "0.1.7"
2231
2231
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2232
2232
+
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
2233
2233
+
dependencies = [
2234
2234
+
"lazy_static",
1923
2235
]
1924
2236
1925
2237
[[package]]
···
2040
2352
]
2041
2353
2042
2354
[[package]]
2355
2355
+
name = "tempfile"
2356
2356
+
version = "3.24.0"
2357
2357
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2358
2358
+
checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c"
2359
2359
+
dependencies = [
2360
2360
+
"fastrand",
2361
2361
+
"getrandom 0.3.4",
2362
2362
+
"once_cell",
2363
2363
+
"rustix",
2364
2364
+
"windows-sys 0.61.2",
2365
2365
+
]
2366
2366
+
2367
2367
+
[[package]]
2043
2368
name = "thiserror"
2044
2369
version = "1.0.69"
2045
2370
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2188
2513
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
2189
2514
dependencies = [
2190
2515
"pin-project-lite",
2516
2516
+
"tracing-attributes",
2191
2517
"tracing-core",
2192
2518
]
2193
2519
2194
2520
[[package]]
2521
2521
+
name = "tracing-attributes"
2522
2522
+
version = "0.1.31"
2523
2523
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2524
2524
+
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
2525
2525
+
dependencies = [
2526
2526
+
"proc-macro2",
2527
2527
+
"quote",
2528
2528
+
"syn 2.0.114",
2529
2529
+
]
2530
2530
+
2531
2531
+
[[package]]
2195
2532
name = "tracing-core"
2196
2533
version = "0.1.36"
2197
2534
source = "registry+https://github.com/rust-lang/crates.io-index"
2198
2535
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
2199
2536
dependencies = [
2200
2537
"once_cell",
2538
2538
+
"valuable",
2539
2539
+
]
2540
2540
+
2541
2541
+
[[package]]
2542
2542
+
name = "tracing-error"
2543
2543
+
version = "0.2.1"
2544
2544
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2545
2545
+
checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db"
2546
2546
+
dependencies = [
2547
2547
+
"tracing",
2548
2548
+
"tracing-subscriber",
2549
2549
+
]
2550
2550
+
2551
2551
+
[[package]]
2552
2552
+
name = "tracing-log"
2553
2553
+
version = "0.2.0"
2554
2554
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2555
2555
+
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
2556
2556
+
dependencies = [
2557
2557
+
"log",
2558
2558
+
"once_cell",
2559
2559
+
"tracing-core",
2560
2560
+
]
2561
2561
+
2562
2562
+
[[package]]
2563
2563
+
name = "tracing-subscriber"
2564
2564
+
version = "0.3.22"
2565
2565
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2566
2566
+
checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e"
2567
2567
+
dependencies = [
2568
2568
+
"matchers",
2569
2569
+
"nu-ansi-term",
2570
2570
+
"once_cell",
2571
2571
+
"regex-automata",
2572
2572
+
"sharded-slab",
2573
2573
+
"smallvec",
2574
2574
+
"thread_local",
2575
2575
+
"tracing",
2576
2576
+
"tracing-core",
2577
2577
+
"tracing-log",
2201
2578
]
2202
2579
2203
2580
[[package]]
···
2233
2610
2234
2611
[[package]]
2235
2612
name = "unicode-ident"
2236
2236
-
version = "1.0.22"
2613
2613
+
version = "1.0.23"
2237
2614
source = "registry+https://github.com/rust-lang/crates.io-index"
2238
2238
-
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
2615
2615
+
checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e"
2239
2616
2240
2617
[[package]]
2241
2618
name = "unsafe-libyaml"
···
2254
2631
version = "0.2.2"
2255
2632
source = "registry+https://github.com/rust-lang/crates.io-index"
2256
2633
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
2634
2634
+
2635
2635
+
[[package]]
2636
2636
+
name = "valuable"
2637
2637
+
version = "0.1.1"
2638
2638
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2639
2639
+
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
2257
2640
2258
2641
[[package]]
2259
2642
name = "version_check"
+14
-1
Cargo.toml
···
5
5
6
6
[dependencies]
7
7
async-trait = "0.1.89"
8
8
-
pingora = { version = "0.7.0", features = ["rustls", "proxy"] }
8
8
+
color-eyre = "0.6.5"
9
9
+
http = "1.4.0"
10
10
+
pingora = { version = "0.7.0", features = ["rustls", "proxy", "lb"] }
11
11
+
prost = "0.14.3"
12
12
+
prost-reflect = { version = "0.16.3", features = ["derive", "text-format"] }
13
13
+
rustls = { version = "0.23.36", features = ["aws-lc-rs"] }
14
14
+
tokio = { version = "1.49.0", features = ["fs"] }
15
15
+
tracing = "0.1.44"
16
16
+
tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
17
17
+
18
18
+
[build-dependencies]
19
19
+
# use prost-reflect-build & prost-reflect so that we can deserialize
20
20
+
# textprotos, cause prost can't natively
21
21
+
prost-reflect-build = "0.16.0"
+6
build.rs
···
1
1
+
fn main() -> std::io::Result<()> {
2
2
+
prost_reflect_build::Builder::new()
3
3
+
.descriptor_pool("crate::config::DESCRIPTOR_POOL")
4
4
+
.compile_protos(&["src/config/format.proto"], &["src/"])?;
5
5
+
Ok(())
6
6
+
}
+1
flake.nix
···
46
46
# rustdoc, rustfmt, and other tools.
47
47
cmake
48
48
rustToolchain
49
49
+
protobuf
49
50
]) ++ pkgs.lib.optionals pkgs.stdenv.isDarwin (with pkgs; [ libiconv ]);
50
51
};
51
52
});
+156
src/config/format.proto
···
1
1
+
syntax = "proto3";
2
2
+
3
3
+
package config.format;
4
4
+
5
5
+
// the root config
6
6
+
message Config {
7
7
+
// the domains to serve
8
8
+
map<string, Domain> domains = 1;
9
9
+
10
10
+
// bind to tcp ports, with optional tls
11
11
+
repeated TCPBinding bind_to_tcp = 2;
12
12
+
// bind to unix domain sockets
13
13
+
repeated UDSBinding bind_to_uds = 4;
14
14
+
15
15
+
// lower-level pingora config
16
16
+
Pingora pingora = 3;
17
17
+
}
18
18
+
19
19
+
message Domain {
20
20
+
// require oidc auth if this is set
21
21
+
optional OIDC oidc_auth = 1;
22
22
+
23
23
+
// TODO: ACME challenge hosting support natively?
24
24
+
25
25
+
// https backends
26
26
+
repeated HTTPSBackend https = 3;
27
27
+
// http backends
28
28
+
repeated HTTPSBackend http = 7;
29
29
+
// unix domain socket backends
30
30
+
repeated UDSBackend uds = 4;
31
31
+
32
32
+
enum TLSMode {
33
33
+
// don't support redirects, they can be _very_ unsafe. just use hsts
34
34
+
35
35
+
// only allow https, no redirect
36
36
+
TLS_MODE_ONLY = 0;
37
37
+
// allow http, for testing purposes
38
38
+
TLS_MODE_UNSAFE_ALLOW_HTTP = 1;
39
39
+
}
40
40
+
41
41
+
TLSMode tls_mode = 5;
42
42
+
43
43
+
// set or clear headers on the backend request
44
44
+
ManageHeaders manage_headers = 6;
45
45
+
}
46
46
+
47
47
+
message OIDC {
48
48
+
// the base oidc discovery url, without the `.well-known/openid-configuration` part
49
49
+
//
50
50
+
// per [OIDC Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html)
51
51
+
string discovery_url_base = 1;
52
52
+
53
53
+
string client_id = 2;
54
54
+
string client_secret_path = 3;
55
55
+
56
56
+
Scopes scopes = 4;
57
57
+
Claims claims = 5;
58
58
+
}
59
59
+
60
60
+
message Scopes {
61
61
+
repeated string optional = 1;
62
62
+
repeated string required = 2;
63
63
+
}
64
64
+
65
65
+
// information on how to process returned claims
66
66
+
message Claims {
67
67
+
// map the given claims to a header in the backend request
68
68
+
//
69
69
+
// headers specified here with no corresponding claim value will be wiped
70
70
+
map<string, string> claim_to_header = 1;
71
71
+
}
72
72
+
73
73
+
// a standard https backend
74
74
+
message HTTPSBackend {
75
75
+
// full ipv4 or v6 address, including port
76
76
+
string addr = 1;
77
77
+
// weight of this backend, if load-balancing
78
78
+
optional uint64 weight = 2;
79
79
+
}
80
80
+
81
81
+
// a unix domain socket backend
82
82
+
message UDSBackend {
83
83
+
// path to the uds socket
84
84
+
string path = 1;
85
85
+
// weight of this backend, if load-balancing
86
86
+
optional uint64 weight = 2;
87
87
+
}
88
88
+
89
89
+
// these headers will be set if they are set to something
90
90
+
//
91
91
+
// either way, they will be wiped if the client tries to send them
92
92
+
message ManageHeaders {
93
93
+
// set the given header to be the request host
94
94
+
optional string host = 1;
95
95
+
// set an `X-Forwarded-For`-style header, appending `,<remote_addr>` to any existing value
96
96
+
optional string x_forwarded_for = 2;
97
97
+
// set an `X-Forwarded-Proto`-style header to the original scheme of the request
98
98
+
optional string x_forwarded_proto = 3;
99
99
+
// set an `X-Real-IP`-style header (i.e. _just_ the remote address)
100
100
+
repeated string remote_addr = 4;
101
101
+
102
102
+
// always clear these headers
103
103
+
repeated string always_clear = 5;
104
104
+
}
105
105
+
106
106
+
// equivalent to [`pingora::server::configuration::Config`]
107
107
+
message Pingora {
108
108
+
uint64 version = 1;
109
109
+
bool daemon = 2;
110
110
+
optional string error_log = 3;
111
111
+
string pid_file = 4;
112
112
+
string upgrade_sock = 5;
113
113
+
optional string user = 6;
114
114
+
optional string group = 7;
115
115
+
uint64 threads = 8;
116
116
+
uint64 listener_tasks_per_fd = 9;
117
117
+
bool work_stealing = 10;
118
118
+
optional string ca_file = 11;
119
119
+
optional uint64 grace_period_seconds = 12;
120
120
+
optional uint64 graceful_shutdown_timeout_seconds = 13;
121
121
+
repeated string client_bind_to_ipv4 = 14;
122
122
+
repeated string client_bind_to_ipv6 = 15;
123
123
+
uint64 upstream_keepalive_pool_size = 16;
124
124
+
optional uint64 upstream_connect_offload_threadpools = 17;
125
125
+
optional uint64 upstream_connect_offload_thread_per_pool = 18;
126
126
+
bool upstream_debug_ssl_keylog = 19;
127
127
+
uint64 max_retries = 20;
128
128
+
optional uint64 upgrade_sock_connect_accept_max_retries = 21;
129
129
+
130
130
+
}
131
131
+
132
132
+
message TCPBinding {
133
133
+
// configure used tls settings
134
134
+
message TLS {
135
135
+
// path to the (public) tls certificate, with all intermediate certificates (fullchain.pem for most acme clients)
136
136
+
string cert_path = 1;
137
137
+
// path to the (privat) tls key
138
138
+
string key_path = 2;
139
139
+
}
140
140
+
141
141
+
// host an port to bind to
142
142
+
string addr = 1;
143
143
+
// tls, if desired
144
144
+
optional TLS tls = 2;
145
145
+
146
146
+
// TODO: surface tcp options from pingora
147
147
+
}
148
148
+
message UDSBinding {
149
149
+
message Permissions {
150
150
+
uint32 mode = 1;
151
151
+
}
152
152
+
// socket path
153
153
+
string path = 1;
154
154
+
// permissions to set on the socket path
155
155
+
optional Permissions permissions = 2;
156
156
+
}
+65
src/config.rs
···
1
1
+
use std::path::Path;
2
2
+
use std::sync::LazyLock;
3
3
+
4
4
+
use color_eyre::eyre::Context as _;
5
5
+
use prost_reflect::DescriptorPool;
6
6
+
7
7
+
#[allow(unused, reason = "for prost-reflect-build")]
8
8
+
static DESCRIPTOR_POOL: LazyLock<DescriptorPool> = LazyLock::new(|| {
9
9
+
DescriptorPool::decode(
10
10
+
include_bytes!(concat!(env!("OUT_DIR"), "/file_descriptor_set.bin")).as_ref(),
11
11
+
)
12
12
+
.unwrap()
13
13
+
});
14
14
+
15
15
+
pub mod format {
16
16
+
include!(concat!(env!("OUT_DIR"), "/config.format.rs"));
17
17
+
18
18
+
impl From<&Pingora> for pingora::server::configuration::ServerConf {
19
19
+
fn from(raw: &Pingora) -> Self {
20
20
+
Self {
21
21
+
version: raw.version as usize,
22
22
+
daemon: raw.daemon,
23
23
+
error_log: raw.error_log.clone(),
24
24
+
pid_file: raw.pid_file.clone(),
25
25
+
upgrade_sock: raw.upgrade_sock.clone(),
26
26
+
user: raw.user.clone(),
27
27
+
group: raw.group.clone(),
28
28
+
threads: raw.threads as usize,
29
29
+
listener_tasks_per_fd: raw.listener_tasks_per_fd as usize,
30
30
+
work_stealing: raw.work_stealing,
31
31
+
ca_file: raw.ca_file.clone(),
32
32
+
grace_period_seconds: raw.grace_period_seconds,
33
33
+
graceful_shutdown_timeout_seconds: raw.graceful_shutdown_timeout_seconds,
34
34
+
client_bind_to_ipv4: raw.client_bind_to_ipv4.clone(),
35
35
+
client_bind_to_ipv6: raw.client_bind_to_ipv6.clone(),
36
36
+
upstream_keepalive_pool_size: raw.upstream_keepalive_pool_size as usize,
37
37
+
upstream_connect_offload_threadpools: raw
38
38
+
.upstream_connect_offload_threadpools
39
39
+
.map(|x| x as usize),
40
40
+
upstream_connect_offload_thread_per_pool: raw
41
41
+
.upstream_connect_offload_thread_per_pool
42
42
+
.map(|x| x as usize),
43
43
+
upstream_debug_ssl_keylog: raw.upstream_debug_ssl_keylog,
44
44
+
max_retries: raw.max_retries as usize,
45
45
+
upgrade_sock_connect_accept_max_retries: raw
46
46
+
.upgrade_sock_connect_accept_max_retries
47
47
+
.map(|x| x as usize),
48
48
+
}
49
49
+
}
50
50
+
}
51
51
+
}
52
52
+
53
53
+
/// load the config from the given file
54
54
+
pub fn load(src: impl AsRef<Path>) -> color_eyre::Result<format::Config> {
55
55
+
use prost_reflect::{DynamicMessage, ReflectMessage as _};
56
56
+
57
57
+
let dynamic = DynamicMessage::parse_text_format(
58
58
+
format::Config::default().descriptor(),
59
59
+
&std::fs::read_to_string(src)
60
60
+
.context("reading config file")?,
61
61
+
)
62
62
+
.context("parsing config")?;
63
63
+
64
64
+
dynamic.transcode_to().context("validating config")
65
65
+
}
+273
-2
src/main.rs
···
1
1
-
fn main() {
2
2
-
println!("Hello, world!");
1
1
+
use std::collections::HashMap;
2
2
+
use std::sync::Arc;
3
3
+
4
4
+
use async_trait::async_trait;
5
5
+
use color_eyre::eyre::Context as _;
6
6
+
use http::status::StatusCode;
7
7
+
use pingora::lb;
8
8
+
use pingora::lb::selection::consistent::KetamaHashing;
9
9
+
use pingora::modules::http::HttpModules;
10
10
+
use pingora::modules::http::compression::ResponseCompressionBuilder;
11
11
+
use pingora::prelude::*;
12
12
+
13
13
+
mod config;
14
14
+
15
15
+
struct BackendInfo {
16
16
+
balancer: Arc<LoadBalancer<KetamaHashing>>,
17
17
+
tls_mode: config::format::domain::TlsMode,
18
18
+
name: String,
19
19
+
// TODO: force ssl
20
20
+
}
21
21
+
22
22
+
pub struct AuthGateway {
23
23
+
backends: HashMap<String, BackendInfo>,
24
24
+
}
25
25
+
26
26
+
fn status_error(why: &'static str, src: ErrorSource, status: http::StatusCode) -> impl FnOnce() -> Box<Error> {
27
27
+
move || Error::create(ErrorType::HTTPStatus(status.into()), src, Some(why.into()), None)
28
28
+
}
29
29
+
30
30
+
impl AuthGateway {
31
31
+
fn backend_info<'s>(&'s self, session: &Session) -> Result<&'s BackendInfo> {
32
32
+
let req = session.req_header();
33
33
+
// TODO: afaict, right now, afaict, pingora a) does not check that SNI matches the `Host`
34
34
+
// header, b) does not support extracting the SNI info on rustls, so we'll have to switch
35
35
+
// to boringssl and implement that ourselves T_T
36
36
+
let host = req
37
37
+
.headers
38
38
+
.get(http::header::HOST)
39
39
+
.ok_or_else(status_error("no host set", ErrorSource::Downstream, StatusCode::BAD_REQUEST))?
40
40
+
.to_str()
41
41
+
.map_err(|e| {
42
42
+
Error::because(
43
43
+
ErrorType::HTTPStatus(StatusCode::BAD_REQUEST.into()),
44
44
+
"no host",
45
45
+
e,
46
46
+
)
47
47
+
})?;
48
48
+
let info = self
49
49
+
.backends
50
50
+
.get(host)
51
51
+
.ok_or_else(status_error("unknown host", ErrorSource::Downstream, StatusCode::SERVICE_UNAVAILABLE))?;
52
52
+
53
53
+
Ok(info)
54
54
+
}
55
55
+
}
56
56
+
57
57
+
#[async_trait]
58
58
+
impl ProxyHttp for AuthGateway {
59
59
+
type CTX = ();
60
60
+
fn new_ctx(&self) -> Self::CTX {}
61
61
+
62
62
+
fn init_downstream_modules(&self, modules: &mut HttpModules) {
63
63
+
// TODO: make this configurable?
64
64
+
modules.add_module(ResponseCompressionBuilder::enable(1));
65
65
+
}
66
66
+
67
67
+
async fn request_filter(&self, session: &mut Session, _ctx: &mut Self::CTX) -> Result<bool> {
68
68
+
// check if this is http, and redirect
69
69
+
// TODO: maybe should be a module?
70
70
+
let is_https = session.digest().and_then(|d| d.ssl_digest.as_ref()).is_some();
71
71
+
if !is_https {
72
72
+
use config::format::domain::TlsMode;
73
73
+
let info = self.backend_info(session)?;
74
74
+
match info.tls_mode {
75
75
+
TlsMode::Only => {
76
76
+
// we should just drop the connection, although people should really just be
77
77
+
// using HSTS
78
78
+
session.shutdown().await;
79
79
+
return Ok(true);
80
80
+
},
81
81
+
TlsMode::UnsafeAllowHttp => {},
82
82
+
}
83
83
+
}
84
84
+
85
85
+
Ok(false)
86
86
+
}
87
87
+
88
88
+
async fn upstream_peer(&self, session: &mut Session, _ctx: &mut ()) -> Result<Box<HttpPeer>> {
89
89
+
fn client_addr_key(sock_addr: &pingora::protocols::l4::socket::SocketAddr) -> Vec<u8> {
90
90
+
use pingora::protocols::l4::socket::SocketAddr;
91
91
+
match sock_addr {
92
92
+
SocketAddr::Inet(socket_addr) => match socket_addr {
93
93
+
std::net::SocketAddr::V4(v4) => Vec::from(v4.ip().octets()),
94
94
+
std::net::SocketAddr::V6(v6) => Vec::from(v6.ip().octets()),
95
95
+
},
96
96
+
// TODO: this is... not a great key for hashing
97
97
+
SocketAddr::Unix(_socket_addr) => vec![],
98
98
+
}
99
99
+
}
100
100
+
101
101
+
let backends = self.backend_info(session)?;
102
102
+
let backend = backends.balancer
103
103
+
// NB: this means that CGNAT, other proxies, etc will? consistently hit the same
104
104
+
// backend, so we might wanna take that into consideration. fine for now, this is
105
105
+
// currently for personal use ;-)
106
106
+
.select(
107
107
+
&client_addr_key(
108
108
+
session
109
109
+
.client_addr()
110
110
+
.ok_or_else(status_error("no client address", ErrorSource::Downstream, StatusCode::BAD_REQUEST))?,
111
111
+
), /* lb on client address */
112
112
+
256,
113
113
+
)
114
114
+
.ok_or_else(status_error("no available backends", ErrorSource::Upstream, StatusCode::SERVICE_UNAVAILABLE))?;
115
115
+
116
116
+
let needs_tls = backend
117
117
+
.ext
118
118
+
.get::<BackendData>()
119
119
+
.map(|d| d.tls)
120
120
+
.unwrap_or(true);
121
121
+
122
122
+
Ok(Box::new(HttpPeer::new(
123
123
+
backend,
124
124
+
needs_tls,
125
125
+
backends.name.to_string(),
126
126
+
)))
127
127
+
}
128
128
+
129
129
+
// TODO: upstream_request_filter to insert the right headers
130
130
+
131
131
+
async fn response_filter(
132
132
+
&self,
133
133
+
_session: &mut Session,
134
134
+
_upstream_response: &mut ResponseHeader,
135
135
+
_ctx: &mut Self::CTX,
136
136
+
) -> Result<()>
137
137
+
where
138
138
+
Self::CTX: Send + Sync,
139
139
+
{
140
140
+
Ok(())
141
141
+
}
142
142
+
143
143
+
// TODO: logging
144
144
+
}
145
145
+
146
146
+
#[derive(Clone)]
147
147
+
struct BackendData {
148
148
+
tls: bool,
149
149
+
}
150
150
+
151
151
+
fn balancer(
152
152
+
domains: &HashMap<String, config::format::Domain>,
153
153
+
) -> color_eyre::Result<(
154
154
+
Vec<pingora::services::background::GenBackgroundService<LoadBalancer<KetamaHashing>>>,
155
155
+
HashMap<String, BackendInfo>,
156
156
+
)>
157
157
+
{
158
158
+
use lb::{self, Backend, discovery};
159
159
+
use pingora::protocols::l4::socket::SocketAddr;
160
160
+
161
161
+
let mut balancers = HashMap::with_capacity(domains.len());
162
162
+
let mut svcs = Vec::with_capacity(domains.len());
163
163
+
for (name, domain) in domains {
164
164
+
let backends = domain
165
165
+
.https
166
166
+
.iter()
167
167
+
.map(|backend| {
168
168
+
let mut ext = lb::Extensions::new();
169
169
+
ext.insert(BackendData { tls: true });
170
170
+
let mut backend = Backend::new_with_weight(
171
171
+
&backend.addr,
172
172
+
backend.weight.map(|w| w as usize).unwrap_or(1),
173
173
+
)
174
174
+
.context("parsing addr of https socket backend")?;
175
175
+
backend.ext = ext;
176
176
+
Ok(backend)
177
177
+
})
178
178
+
.chain(domain.http.iter().map(|backend| {
179
179
+
let mut ext = lb::Extensions::new();
180
180
+
ext.insert(BackendData { tls: false });
181
181
+
let mut backend = Backend::new_with_weight(
182
182
+
&backend.addr,
183
183
+
backend.weight.map(|w| w as usize).unwrap_or(1),
184
184
+
)
185
185
+
.context("parsing addr of http socket backend")?;
186
186
+
backend.ext = ext;
187
187
+
Ok(backend)
188
188
+
}))
189
189
+
.chain(domain.uds.iter().map(|backend| {
190
190
+
let mut ext = lb::Extensions::new();
191
191
+
ext.insert(BackendData { tls: false });
192
192
+
Ok(Backend {
193
193
+
addr: SocketAddr::Unix(
194
194
+
std::os::unix::net::SocketAddr::from_pathname(&backend.path)
195
195
+
.context("turning uds path into socketaddr")?,
196
196
+
),
197
197
+
weight: backend.weight.map(|w| w as usize).unwrap_or(1),
198
198
+
ext,
199
199
+
})
200
200
+
}))
201
201
+
.collect::<color_eyre::Result<_>>()
202
202
+
.context("constucting backends for domain")?;
203
203
+
let backends = lb::Backends::new(discovery::Static::new(backends));
204
204
+
// TODO: allow configuring healthchecks
205
205
+
let balancer = LoadBalancer::from_backends(backends);
206
206
+
let svc = background_service("health checking", balancer);
207
207
+
208
208
+
let info = BackendInfo {
209
209
+
balancer: svc.task(),
210
210
+
tls_mode: config::format::domain::TlsMode::try_from(domain.tls_mode).context("invalid tls mode")?,
211
211
+
name: name.clone(),
212
212
+
};
213
213
+
214
214
+
balancers.insert(name.clone(), info);
215
215
+
svcs.push(svc)
216
216
+
}
217
217
+
218
218
+
Ok((svcs, balancers))
219
219
+
}
220
220
+
221
221
+
fn main() -> color_eyre::Result<()> {
222
222
+
use color_eyre::eyre::eyre;
223
223
+
224
224
+
use std::os::unix::fs::PermissionsExt as _;
225
225
+
226
226
+
tracing_subscriber::fmt().init();
227
227
+
color_eyre::install()?;
228
228
+
rustls::crypto::aws_lc_rs::default_provider()
229
229
+
.install_default()
230
230
+
.expect("unable to install crypto provider");
231
231
+
232
232
+
let opts = Opt::parse_args();
233
233
+
234
234
+
let config = config::load(opts.conf.as_ref().ok_or_else(|| {
235
235
+
eyre!("no config file specified, refusing to do anything (try `-c FILE`?)")
236
236
+
})?)?;
237
237
+
238
238
+
let pingora_config = match config.pingora.as_ref().map(Into::into) {
239
239
+
Some(conf) => conf,
240
240
+
None => pingora::server::configuration::ServerConf::new_with_opt_override(&opts)
241
241
+
.ok_or_else(|| {
242
242
+
eyre!("could not create a base pingora config, and none was specified")
243
243
+
})?,
244
244
+
};
245
245
+
let mut server = Server::new_with_opt_and_conf(opts, pingora_config);
246
246
+
server.bootstrap();
247
247
+
248
248
+
let (balancer_svcs, balancers) =
249
249
+
balancer(&config.domains).context("setting up load balancing")?;
250
250
+
let mut gateway = http_proxy_service(&server.configuration, AuthGateway { backends: balancers });
251
251
+
for binding in config.bind_to_tcp {
252
252
+
match binding.tls {
253
253
+
Some(tls) => gateway
254
254
+
.add_tls(&binding.addr, &tls.cert_path, &tls.key_path)
255
255
+
.context("setting up tls")?,
256
256
+
None => gateway.add_tcp(&binding.addr),
257
257
+
}
258
258
+
}
259
259
+
for binding in config.bind_to_uds {
260
260
+
gateway.add_uds(
261
261
+
&binding.path,
262
262
+
binding
263
263
+
.permissions
264
264
+
.map(|p| std::fs::Permissions::from_mode(p.mode)),
265
265
+
);
266
266
+
}
267
267
+
268
268
+
balancer_svcs
269
269
+
.into_iter()
270
270
+
.for_each(|svc| server.add_service(svc));
271
271
+
server.add_service(gateway);
272
272
+
273
273
+
server.run_forever();
3
274
}