@push.rocks/smartproxy 19.3.2 → 19.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/forwarding/factory/forwarding-factory.js +29 -1
- package/dist_ts/http/index.d.ts +1 -3
- package/dist_ts/http/index.js +4 -10
- package/dist_ts/http/models/http-types.d.ts +4 -91
- package/dist_ts/http/models/http-types.js +5 -60
- package/dist_ts/http/router/proxy-router.d.ts +1 -1
- package/dist_ts/http/router/route-router.d.ts +1 -1
- package/dist_ts/index.d.ts +9 -7
- package/dist_ts/index.js +10 -7
- package/dist_ts/proxies/{network-proxy → http-proxy}/certificate-manager.d.ts +2 -2
- package/dist_ts/proxies/{network-proxy → http-proxy}/certificate-manager.js +1 -1
- package/dist_ts/proxies/{network-proxy → http-proxy}/connection-pool.d.ts +2 -2
- package/dist_ts/proxies/http-proxy/connection-pool.js +210 -0
- package/dist_ts/proxies/http-proxy/context-creator.js +108 -0
- package/dist_ts/proxies/{network-proxy → http-proxy}/function-cache.js +1 -1
- package/dist_ts/proxies/http-proxy/handlers/index.d.ts +5 -0
- package/dist_ts/proxies/http-proxy/handlers/index.js +6 -0
- package/dist_ts/proxies/http-proxy/handlers/redirect-handler.d.ts +18 -0
- package/dist_ts/proxies/http-proxy/handlers/redirect-handler.js +78 -0
- package/dist_ts/proxies/http-proxy/handlers/static-handler.d.ts +19 -0
- package/dist_ts/proxies/http-proxy/handlers/static-handler.js +203 -0
- package/dist_ts/proxies/{network-proxy/network-proxy.d.ts → http-proxy/http-proxy.d.ts} +10 -9
- package/dist_ts/proxies/{network-proxy/network-proxy.js → http-proxy/http-proxy.js} +13 -12
- package/dist_ts/proxies/{network-proxy → http-proxy}/http-request-handler.js +1 -1
- package/dist_ts/proxies/http-proxy/http2-request-handler.js +201 -0
- package/dist_ts/proxies/{network-proxy → http-proxy}/index.d.ts +2 -2
- package/dist_ts/proxies/http-proxy/index.js +12 -0
- package/dist_ts/proxies/http-proxy/models/http-types.d.ts +119 -0
- package/dist_ts/proxies/http-proxy/models/http-types.js +112 -0
- package/dist_ts/proxies/http-proxy/models/index.d.ts +5 -0
- package/dist_ts/proxies/http-proxy/models/index.js +6 -0
- package/dist_ts/proxies/{network-proxy → http-proxy}/models/types.d.ts +2 -2
- package/dist_ts/proxies/http-proxy/models/types.js +276 -0
- package/dist_ts/proxies/{network-proxy → http-proxy}/request-handler.d.ts +3 -3
- package/dist_ts/proxies/{network-proxy → http-proxy}/request-handler.js +2 -2
- package/dist_ts/proxies/http-proxy/security-manager.js +255 -0
- package/dist_ts/proxies/{network-proxy → http-proxy}/websocket-handler.d.ts +3 -3
- package/dist_ts/proxies/{network-proxy → http-proxy}/websocket-handler.js +2 -2
- package/dist_ts/proxies/index.d.ts +5 -5
- package/dist_ts/proxies/index.js +5 -5
- package/dist_ts/proxies/smart-proxy/certificate-manager.d.ts +4 -4
- package/dist_ts/proxies/smart-proxy/certificate-manager.js +11 -11
- package/dist_ts/proxies/smart-proxy/http-proxy-bridge.d.ts +41 -0
- package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +121 -0
- package/dist_ts/proxies/smart-proxy/index.d.ts +2 -1
- package/dist_ts/proxies/smart-proxy/index.js +4 -2
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +2 -2
- package/dist_ts/proxies/smart-proxy/port-manager.js +3 -3
- package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +3 -3
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +24 -265
- package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +1 -1
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +25 -25
- package/dist_ts/routing/index.d.ts +5 -0
- package/dist_ts/routing/index.js +8 -0
- package/dist_ts/routing/models/http-types.d.ts +6 -0
- package/dist_ts/routing/models/http-types.js +7 -0
- package/dist_ts/routing/router/index.d.ts +8 -0
- package/dist_ts/routing/router/index.js +7 -0
- package/dist_ts/{classes.router.d.ts → routing/router/proxy-router.d.ts} +14 -11
- package/dist_ts/{classes.router.js → routing/router/proxy-router.js} +2 -2
- package/dist_ts/routing/router/route-router.d.ts +108 -0
- package/dist_ts/routing/router/route-router.js +393 -0
- package/package.json +1 -1
- package/readme.md +18 -35
- package/readme.plan.md +173 -271
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/forwarding/factory/forwarding-factory.ts +28 -0
- package/ts/index.ts +13 -9
- package/ts/proxies/{network-proxy → http-proxy}/certificate-manager.ts +2 -2
- package/ts/proxies/{network-proxy → http-proxy}/connection-pool.ts +2 -2
- package/ts/proxies/http-proxy/handlers/index.ts +6 -0
- package/ts/proxies/http-proxy/handlers/redirect-handler.ts +105 -0
- package/ts/proxies/http-proxy/handlers/static-handler.ts +251 -0
- package/ts/proxies/{network-proxy/network-proxy.ts → http-proxy/http-proxy.ts} +15 -14
- package/ts/proxies/{network-proxy → http-proxy}/index.ts +3 -3
- package/ts/proxies/http-proxy/models/http-types.ts +165 -0
- package/ts/proxies/http-proxy/models/index.ts +5 -0
- package/ts/proxies/{network-proxy → http-proxy}/models/types.ts +2 -2
- package/ts/proxies/{network-proxy → http-proxy}/request-handler.ts +3 -3
- package/ts/proxies/{network-proxy → http-proxy}/websocket-handler.ts +3 -3
- package/ts/proxies/index.ts +7 -7
- package/ts/proxies/smart-proxy/certificate-manager.ts +10 -10
- package/ts/proxies/smart-proxy/{network-proxy-bridge.ts → http-proxy-bridge.ts} +44 -44
- package/ts/proxies/smart-proxy/index.ts +4 -1
- package/ts/proxies/smart-proxy/models/interfaces.ts +3 -3
- package/ts/proxies/smart-proxy/port-manager.ts +2 -2
- package/ts/proxies/smart-proxy/route-connection-handler.ts +23 -307
- package/ts/proxies/smart-proxy/smart-proxy.ts +25 -25
- package/ts/routing/index.ts +9 -0
- package/ts/routing/models/http-types.ts +6 -0
- package/ts/{http → routing}/router/proxy-router.ts +1 -1
- package/ts/{http → routing}/router/route-router.ts +1 -1
- package/dist_ts/certificate/acme/acme-factory.d.ts +0 -17
- package/dist_ts/certificate/acme/acme-factory.js +0 -40
- package/dist_ts/certificate/acme/challenge-handler.d.ts +0 -44
- package/dist_ts/certificate/acme/challenge-handler.js +0 -92
- package/dist_ts/certificate/acme/index.d.ts +0 -4
- package/dist_ts/certificate/acme/index.js +0 -5
- package/dist_ts/certificate/certificate-manager.d.ts +0 -150
- package/dist_ts/certificate/certificate-manager.js +0 -505
- package/dist_ts/certificate/events/certificate-events.d.ts +0 -33
- package/dist_ts/certificate/events/certificate-events.js +0 -38
- package/dist_ts/certificate/events/simplified-events.d.ts +0 -56
- package/dist_ts/certificate/events/simplified-events.js +0 -13
- package/dist_ts/certificate/index.d.ts +0 -30
- package/dist_ts/certificate/index.js +0 -37
- package/dist_ts/certificate/models/certificate-errors.d.ts +0 -69
- package/dist_ts/certificate/models/certificate-errors.js +0 -141
- package/dist_ts/certificate/models/certificate-strategy.d.ts +0 -60
- package/dist_ts/certificate/models/certificate-strategy.js +0 -73
- package/dist_ts/certificate/models/certificate-types.d.ts +0 -97
- package/dist_ts/certificate/models/certificate-types.js +0 -2
- package/dist_ts/certificate/providers/cert-provisioner.d.ts +0 -119
- package/dist_ts/certificate/providers/cert-provisioner.js +0 -422
- package/dist_ts/certificate/providers/index.d.ts +0 -4
- package/dist_ts/certificate/providers/index.js +0 -5
- package/dist_ts/certificate/simplified-certificate-manager.d.ts +0 -150
- package/dist_ts/certificate/simplified-certificate-manager.js +0 -501
- package/dist_ts/certificate/storage/file-storage.d.ts +0 -66
- package/dist_ts/certificate/storage/file-storage.js +0 -194
- package/dist_ts/certificate/storage/index.d.ts +0 -4
- package/dist_ts/certificate/storage/index.js +0 -5
- package/dist_ts/certificate/utils/certificate-helpers.d.ts +0 -17
- package/dist_ts/certificate/utils/certificate-helpers.js +0 -45
- package/dist_ts/classes.iptablesproxy.d.ts +0 -112
- package/dist_ts/classes.iptablesproxy.js +0 -765
- package/dist_ts/classes.networkproxy.d.ts +0 -243
- package/dist_ts/classes.networkproxy.js +0 -1424
- package/dist_ts/classes.nftablesproxy.d.ts +0 -219
- package/dist_ts/classes.nftablesproxy.js +0 -1542
- package/dist_ts/classes.port80handler.d.ts +0 -215
- package/dist_ts/classes.port80handler.js +0 -736
- package/dist_ts/classes.portproxy.d.ts +0 -171
- package/dist_ts/classes.portproxy.js +0 -1802
- package/dist_ts/classes.pp.acmemanager.d.ts +0 -34
- package/dist_ts/classes.pp.acmemanager.js +0 -123
- package/dist_ts/classes.pp.connectionhandler.d.ts +0 -39
- package/dist_ts/classes.pp.connectionhandler.js +0 -754
- package/dist_ts/classes.pp.connectionmanager.d.ts +0 -78
- package/dist_ts/classes.pp.connectionmanager.js +0 -378
- package/dist_ts/classes.pp.domainconfigmanager.d.ts +0 -55
- package/dist_ts/classes.pp.domainconfigmanager.js +0 -103
- package/dist_ts/classes.pp.interfaces.d.ts +0 -133
- package/dist_ts/classes.pp.interfaces.js +0 -2
- package/dist_ts/classes.pp.networkproxybridge.d.ts +0 -57
- package/dist_ts/classes.pp.networkproxybridge.js +0 -306
- package/dist_ts/classes.pp.portproxy.d.ts +0 -64
- package/dist_ts/classes.pp.portproxy.js +0 -567
- package/dist_ts/classes.pp.portrangemanager.d.ts +0 -56
- package/dist_ts/classes.pp.portrangemanager.js +0 -179
- package/dist_ts/classes.pp.securitymanager.d.ts +0 -47
- package/dist_ts/classes.pp.securitymanager.js +0 -126
- package/dist_ts/classes.pp.snihandler.d.ts +0 -153
- package/dist_ts/classes.pp.snihandler.js +0 -1053
- package/dist_ts/classes.pp.timeoutmanager.d.ts +0 -47
- package/dist_ts/classes.pp.timeoutmanager.js +0 -154
- package/dist_ts/classes.pp.tlsalert.d.ts +0 -149
- package/dist_ts/classes.pp.tlsalert.js +0 -225
- package/dist_ts/classes.pp.tlsmanager.d.ts +0 -57
- package/dist_ts/classes.pp.tlsmanager.js +0 -132
- package/dist_ts/classes.snihandler.d.ts +0 -198
- package/dist_ts/classes.snihandler.js +0 -1210
- package/dist_ts/classes.sslredirect.d.ts +0 -8
- package/dist_ts/classes.sslredirect.js +0 -28
- package/dist_ts/common/acmeFactory.d.ts +0 -9
- package/dist_ts/common/acmeFactory.js +0 -20
- package/dist_ts/common/port80-adapter.d.ts +0 -11
- package/dist_ts/common/port80-adapter.js +0 -87
- package/dist_ts/examples/forwarding-example.d.ts +0 -1
- package/dist_ts/examples/forwarding-example.js +0 -96
- package/dist_ts/forwarding/config/domain-config.d.ts +0 -12
- package/dist_ts/forwarding/config/domain-config.js +0 -12
- package/dist_ts/forwarding/config/domain-manager.d.ts +0 -86
- package/dist_ts/forwarding/config/domain-manager.js +0 -242
- package/dist_ts/helpers.certificates.d.ts +0 -5
- package/dist_ts/helpers.certificates.js +0 -23
- package/dist_ts/http/port80/acme-interfaces.d.ts +0 -108
- package/dist_ts/http/port80/acme-interfaces.js +0 -51
- package/dist_ts/http/port80/challenge-responder.d.ts +0 -53
- package/dist_ts/http/port80/challenge-responder.js +0 -203
- package/dist_ts/http/port80/index.d.ts +0 -6
- package/dist_ts/http/port80/index.js +0 -9
- package/dist_ts/http/port80/port80-handler.d.ts +0 -136
- package/dist_ts/http/port80/port80-handler.js +0 -592
- package/dist_ts/http/redirects/index.d.ts +0 -4
- package/dist_ts/http/redirects/index.js +0 -5
- package/dist_ts/networkproxy/classes.np.certificatemanager.d.ts +0 -77
- package/dist_ts/networkproxy/classes.np.certificatemanager.js +0 -372
- package/dist_ts/networkproxy/classes.np.connectionpool.d.ts +0 -47
- package/dist_ts/networkproxy/classes.np.connectionpool.js +0 -210
- package/dist_ts/networkproxy/classes.np.networkproxy.d.ts +0 -118
- package/dist_ts/networkproxy/classes.np.networkproxy.js +0 -387
- package/dist_ts/networkproxy/classes.np.requesthandler.d.ts +0 -56
- package/dist_ts/networkproxy/classes.np.requesthandler.js +0 -393
- package/dist_ts/networkproxy/classes.np.types.d.ts +0 -83
- package/dist_ts/networkproxy/classes.np.types.js +0 -35
- package/dist_ts/networkproxy/classes.np.websockethandler.d.ts +0 -38
- package/dist_ts/networkproxy/classes.np.websockethandler.js +0 -188
- package/dist_ts/networkproxy/index.d.ts +0 -1
- package/dist_ts/networkproxy/index.js +0 -4
- package/dist_ts/nfttablesproxy/classes.nftablesproxy.d.ts +0 -219
- package/dist_ts/nfttablesproxy/classes.nftablesproxy.js +0 -1542
- package/dist_ts/port80handler/classes.port80handler.d.ts +0 -10
- package/dist_ts/port80handler/classes.port80handler.js +0 -16
- package/dist_ts/proxies/network-proxy/connection-pool.js +0 -210
- package/dist_ts/proxies/network-proxy/context-creator.js +0 -108
- package/dist_ts/proxies/network-proxy/http2-request-handler.js +0 -201
- package/dist_ts/proxies/network-proxy/index.js +0 -12
- package/dist_ts/proxies/network-proxy/models/index.d.ts +0 -4
- package/dist_ts/proxies/network-proxy/models/index.js +0 -5
- package/dist_ts/proxies/network-proxy/models/types.js +0 -276
- package/dist_ts/proxies/network-proxy/security-manager.js +0 -255
- package/dist_ts/proxies/network-proxy/simplified-certificate-bridge.d.ts +0 -48
- package/dist_ts/proxies/network-proxy/simplified-certificate-bridge.js +0 -76
- package/dist_ts/proxies/smart-proxy/connection-handler.d.ts +0 -39
- package/dist_ts/proxies/smart-proxy/connection-handler.js +0 -894
- package/dist_ts/proxies/smart-proxy/domain-config-manager.d.ts +0 -110
- package/dist_ts/proxies/smart-proxy/domain-config-manager.js +0 -386
- package/dist_ts/proxies/smart-proxy/legacy-smart-proxy.d.ts +0 -168
- package/dist_ts/proxies/smart-proxy/legacy-smart-proxy.js +0 -642
- package/dist_ts/proxies/smart-proxy/models/simplified-smartproxy-config.d.ts +0 -65
- package/dist_ts/proxies/smart-proxy/models/simplified-smartproxy-config.js +0 -31
- package/dist_ts/proxies/smart-proxy/models/smartproxy-options.d.ts +0 -102
- package/dist_ts/proxies/smart-proxy/models/smartproxy-options.js +0 -73
- package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +0 -41
- package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +0 -121
- package/dist_ts/proxies/smart-proxy/port-range-manager.d.ts +0 -56
- package/dist_ts/proxies/smart-proxy/port-range-manager.js +0 -176
- package/dist_ts/proxies/smart-proxy/route-helpers/index.d.ts +0 -9
- package/dist_ts/proxies/smart-proxy/route-helpers/index.js +0 -11
- package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +0 -7
- package/dist_ts/proxies/smart-proxy/route-helpers.js +0 -9
- package/dist_ts/proxies/smart-proxy/simplified-smart-proxy.d.ts +0 -41
- package/dist_ts/proxies/smart-proxy/simplified-smart-proxy.js +0 -132
- package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.d.ts +0 -51
- package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.js +0 -124
- package/dist_ts/redirect/classes.redirect.d.ts +0 -96
- package/dist_ts/redirect/classes.redirect.js +0 -194
- package/dist_ts/smartproxy/classes.pp.certprovisioner.d.ts +0 -54
- package/dist_ts/smartproxy/classes.pp.certprovisioner.js +0 -179
- package/dist_ts/smartproxy/classes.pp.connectionhandler.d.ts +0 -39
- package/dist_ts/smartproxy/classes.pp.connectionhandler.js +0 -894
- package/dist_ts/smartproxy/classes.pp.connectionmanager.d.ts +0 -78
- package/dist_ts/smartproxy/classes.pp.connectionmanager.js +0 -378
- package/dist_ts/smartproxy/classes.pp.domainconfigmanager.d.ts +0 -94
- package/dist_ts/smartproxy/classes.pp.domainconfigmanager.js +0 -255
- package/dist_ts/smartproxy/classes.pp.interfaces.d.ts +0 -103
- package/dist_ts/smartproxy/classes.pp.interfaces.js +0 -2
- package/dist_ts/smartproxy/classes.pp.networkproxybridge.d.ts +0 -62
- package/dist_ts/smartproxy/classes.pp.networkproxybridge.js +0 -316
- package/dist_ts/smartproxy/classes.pp.portrangemanager.d.ts +0 -56
- package/dist_ts/smartproxy/classes.pp.portrangemanager.js +0 -176
- package/dist_ts/smartproxy/classes.pp.securitymanager.d.ts +0 -64
- package/dist_ts/smartproxy/classes.pp.securitymanager.js +0 -149
- package/dist_ts/smartproxy/classes.pp.snihandler.d.ts +0 -153
- package/dist_ts/smartproxy/classes.pp.snihandler.js +0 -1053
- package/dist_ts/smartproxy/classes.pp.timeoutmanager.d.ts +0 -47
- package/dist_ts/smartproxy/classes.pp.timeoutmanager.js +0 -154
- package/dist_ts/smartproxy/classes.pp.tlsalert.d.ts +0 -149
- package/dist_ts/smartproxy/classes.pp.tlsalert.js +0 -225
- package/dist_ts/smartproxy/classes.pp.tlsmanager.d.ts +0 -57
- package/dist_ts/smartproxy/classes.pp.tlsmanager.js +0 -132
- package/dist_ts/smartproxy/classes.smartproxy.d.ts +0 -63
- package/dist_ts/smartproxy/classes.smartproxy.js +0 -521
- package/dist_ts/smartproxy/forwarding/domain-config.d.ts +0 -12
- package/dist_ts/smartproxy/forwarding/domain-config.js +0 -12
- package/dist_ts/smartproxy/forwarding/domain-manager.d.ts +0 -86
- package/dist_ts/smartproxy/forwarding/domain-manager.js +0 -241
- package/dist_ts/smartproxy/forwarding/forwarding.factory.d.ts +0 -24
- package/dist_ts/smartproxy/forwarding/forwarding.factory.js +0 -137
- package/dist_ts/smartproxy/forwarding/forwarding.handler.d.ts +0 -55
- package/dist_ts/smartproxy/forwarding/forwarding.handler.js +0 -94
- package/dist_ts/smartproxy/forwarding/http.handler.d.ts +0 -25
- package/dist_ts/smartproxy/forwarding/http.handler.js +0 -123
- package/dist_ts/smartproxy/forwarding/https-passthrough.handler.d.ts +0 -24
- package/dist_ts/smartproxy/forwarding/https-passthrough.handler.js +0 -154
- package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.d.ts +0 -36
- package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.js +0 -229
- package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.d.ts +0 -35
- package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.js +0 -254
- package/dist_ts/smartproxy/forwarding/index.d.ts +0 -16
- package/dist_ts/smartproxy/forwarding/index.js +0 -23
- package/dist_ts/smartproxy/types/forwarding.types.d.ts +0 -104
- package/dist_ts/smartproxy/types/forwarding.types.js +0 -50
- package/dist_ts/smartproxy.classes.networkproxy.d.ts +0 -31
- package/dist_ts/smartproxy.classes.networkproxy.js +0 -305
- package/dist_ts/smartproxy.classes.router.d.ts +0 -13
- package/dist_ts/smartproxy.classes.router.js +0 -33
- package/dist_ts/smartproxy.classes.sslredirect.d.ts +0 -8
- package/dist_ts/smartproxy.classes.sslredirect.js +0 -28
- package/dist_ts/smartproxy.helpers.certificates.d.ts +0 -5
- package/dist_ts/smartproxy.helpers.certificates.js +0 -23
- package/dist_ts/smartproxy.plugins.d.ts +0 -18
- package/dist_ts/smartproxy.plugins.js +0 -23
- package/dist_ts/smartproxy.portproxy.d.ts +0 -26
- package/dist_ts/smartproxy.portproxy.js +0 -295
- package/ts/http/index.ts +0 -16
- package/ts/http/models/http-types.ts +0 -108
- package/ts/http/redirects/index.ts +0 -3
- package/ts/proxies/network-proxy/models/index.ts +0 -4
- package/ts/redirect/classes.redirect.ts +0 -295
- /package/dist_ts/proxies/{network-proxy → http-proxy}/context-creator.d.ts +0 -0
- /package/dist_ts/proxies/{network-proxy → http-proxy}/function-cache.d.ts +0 -0
- /package/dist_ts/proxies/{network-proxy → http-proxy}/http-request-handler.d.ts +0 -0
- /package/dist_ts/proxies/{network-proxy → http-proxy}/http2-request-handler.d.ts +0 -0
- /package/dist_ts/proxies/{network-proxy → http-proxy}/security-manager.d.ts +0 -0
- /package/ts/proxies/{network-proxy → http-proxy}/context-creator.ts +0 -0
- /package/ts/proxies/{network-proxy → http-proxy}/function-cache.ts +0 -0
- /package/ts/proxies/{network-proxy → http-proxy}/http-request-handler.ts +0 -0
- /package/ts/proxies/{network-proxy → http-proxy}/http2-request-handler.ts +0 -0
- /package/ts/proxies/{network-proxy → http-proxy}/security-manager.ts +0 -0
- /package/ts/{http → routing}/router/index.ts +0 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
/**
|
|
3
|
+
* Router for HTTP reverse proxy requests based on route configurations
|
|
4
|
+
*
|
|
5
|
+
* Supports the following domain matching patterns:
|
|
6
|
+
* - Exact matches: "example.com"
|
|
7
|
+
* - Wildcard subdomains: "*.example.com" (matches any subdomain of example.com)
|
|
8
|
+
* - TLD wildcards: "example.*" (matches example.com, example.org, etc.)
|
|
9
|
+
* - Complex wildcards: "*.lossless*" (matches any subdomain of any lossless domain)
|
|
10
|
+
* - Default fallback: "*" (matches any unmatched domain)
|
|
11
|
+
*
|
|
12
|
+
* Also supports path pattern matching for each domain:
|
|
13
|
+
* - Exact path: "/api/users"
|
|
14
|
+
* - Wildcard paths: "/api/*"
|
|
15
|
+
* - Path parameters: "/users/:id/profile"
|
|
16
|
+
*/
|
|
17
|
+
export class RouteRouter {
|
|
18
|
+
constructor(routes, logger) {
|
|
19
|
+
// Store original routes for reference
|
|
20
|
+
this.routes = [];
|
|
21
|
+
// Store path patterns separately since they're not in the original interface
|
|
22
|
+
this.pathPatterns = new Map();
|
|
23
|
+
this.logger = logger || {
|
|
24
|
+
error: console.error,
|
|
25
|
+
warn: console.warn,
|
|
26
|
+
info: console.info,
|
|
27
|
+
debug: console.debug
|
|
28
|
+
};
|
|
29
|
+
if (routes) {
|
|
30
|
+
this.setRoutes(routes);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Sets a new set of routes to be routed to
|
|
35
|
+
* @param routes Array of route configurations
|
|
36
|
+
*/
|
|
37
|
+
setRoutes(routes) {
|
|
38
|
+
this.routes = [...routes];
|
|
39
|
+
// Sort routes by priority
|
|
40
|
+
this.routes.sort((a, b) => {
|
|
41
|
+
const priorityA = a.priority ?? 0;
|
|
42
|
+
const priorityB = b.priority ?? 0;
|
|
43
|
+
return priorityB - priorityA;
|
|
44
|
+
});
|
|
45
|
+
// Find default route if any (route with "*" as domain)
|
|
46
|
+
this.defaultRoute = this.routes.find(route => {
|
|
47
|
+
const domains = Array.isArray(route.match.domains)
|
|
48
|
+
? route.match.domains
|
|
49
|
+
: [route.match.domains];
|
|
50
|
+
return domains.includes('*');
|
|
51
|
+
});
|
|
52
|
+
// Extract path patterns from route match.path
|
|
53
|
+
for (const route of this.routes) {
|
|
54
|
+
if (route.match.path) {
|
|
55
|
+
this.pathPatterns.set(route, route.match.path);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const uniqueDomains = this.getHostnames();
|
|
59
|
+
this.logger.info(`Router initialized with ${this.routes.length} routes (${uniqueDomains.length} unique hosts)`);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Routes a request based on hostname and path
|
|
63
|
+
* @param req The incoming HTTP request
|
|
64
|
+
* @returns The matching route or undefined if no match found
|
|
65
|
+
*/
|
|
66
|
+
routeReq(req) {
|
|
67
|
+
const result = this.routeReqWithDetails(req);
|
|
68
|
+
return result ? result.route : undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Routes a request with detailed matching information
|
|
72
|
+
* @param req The incoming HTTP request
|
|
73
|
+
* @returns Detailed routing result including matched route and path information
|
|
74
|
+
*/
|
|
75
|
+
routeReqWithDetails(req) {
|
|
76
|
+
// Extract and validate host header
|
|
77
|
+
const originalHost = req.headers.host;
|
|
78
|
+
if (!originalHost) {
|
|
79
|
+
this.logger.error('No host header found in request');
|
|
80
|
+
return this.defaultRoute ? { route: this.defaultRoute } : undefined;
|
|
81
|
+
}
|
|
82
|
+
// Parse URL for path matching
|
|
83
|
+
const parsedUrl = plugins.url.parse(req.url || '/');
|
|
84
|
+
const urlPath = parsedUrl.pathname || '/';
|
|
85
|
+
// Extract hostname without port
|
|
86
|
+
const hostWithoutPort = originalHost.split(':')[0].toLowerCase();
|
|
87
|
+
// First try exact hostname match
|
|
88
|
+
const exactRoute = this.findRouteForHost(hostWithoutPort, urlPath);
|
|
89
|
+
if (exactRoute) {
|
|
90
|
+
return exactRoute;
|
|
91
|
+
}
|
|
92
|
+
// Try various wildcard patterns
|
|
93
|
+
if (hostWithoutPort.includes('.')) {
|
|
94
|
+
const domainParts = hostWithoutPort.split('.');
|
|
95
|
+
// Try wildcard subdomain (*.example.com)
|
|
96
|
+
if (domainParts.length > 2) {
|
|
97
|
+
const wildcardDomain = `*.${domainParts.slice(1).join('.')}`;
|
|
98
|
+
const wildcardRoute = this.findRouteForHost(wildcardDomain, urlPath);
|
|
99
|
+
if (wildcardRoute) {
|
|
100
|
+
return wildcardRoute;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Try TLD wildcard (example.*)
|
|
104
|
+
const baseDomain = domainParts.slice(0, -1).join('.');
|
|
105
|
+
const tldWildcardDomain = `${baseDomain}.*`;
|
|
106
|
+
const tldWildcardRoute = this.findRouteForHost(tldWildcardDomain, urlPath);
|
|
107
|
+
if (tldWildcardRoute) {
|
|
108
|
+
return tldWildcardRoute;
|
|
109
|
+
}
|
|
110
|
+
// Try complex wildcard patterns
|
|
111
|
+
const wildcardPatterns = this.findWildcardMatches(hostWithoutPort);
|
|
112
|
+
for (const pattern of wildcardPatterns) {
|
|
113
|
+
const wildcardRoute = this.findRouteForHost(pattern, urlPath);
|
|
114
|
+
if (wildcardRoute) {
|
|
115
|
+
return wildcardRoute;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Fall back to default route if available
|
|
120
|
+
if (this.defaultRoute) {
|
|
121
|
+
this.logger.warn(`No specific route found for host: ${hostWithoutPort}, using default`);
|
|
122
|
+
return { route: this.defaultRoute };
|
|
123
|
+
}
|
|
124
|
+
this.logger.error(`No route found for host: ${hostWithoutPort}`);
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Find potential wildcard patterns that could match a given hostname
|
|
129
|
+
* Handles complex patterns like "*.lossless*" or other partial matches
|
|
130
|
+
* @param hostname The hostname to find wildcard matches for
|
|
131
|
+
* @returns Array of potential wildcard patterns that could match
|
|
132
|
+
*/
|
|
133
|
+
findWildcardMatches(hostname) {
|
|
134
|
+
const patterns = [];
|
|
135
|
+
// Find all routes with wildcard domains
|
|
136
|
+
for (const route of this.routes) {
|
|
137
|
+
if (!route.match.domains)
|
|
138
|
+
continue;
|
|
139
|
+
const domains = Array.isArray(route.match.domains)
|
|
140
|
+
? route.match.domains
|
|
141
|
+
: [route.match.domains];
|
|
142
|
+
// Filter to only wildcard domains
|
|
143
|
+
const wildcardDomains = domains.filter(domain => domain.includes('*'));
|
|
144
|
+
// Convert each wildcard domain to a regex pattern and check if it matches
|
|
145
|
+
for (const domain of wildcardDomains) {
|
|
146
|
+
// Skip the default wildcard '*'
|
|
147
|
+
if (domain === '*')
|
|
148
|
+
continue;
|
|
149
|
+
// Skip already checked patterns (*.domain.com and domain.*)
|
|
150
|
+
if (domain.startsWith('*.') && domain.indexOf('*', 2) === -1)
|
|
151
|
+
continue;
|
|
152
|
+
if (domain.endsWith('.*') && domain.indexOf('*') === domain.length - 1)
|
|
153
|
+
continue;
|
|
154
|
+
// Convert wildcard pattern to regex
|
|
155
|
+
const regexPattern = domain
|
|
156
|
+
.replace(/\./g, '\\.') // Escape dots
|
|
157
|
+
.replace(/\*/g, '.*'); // Convert * to .* for regex
|
|
158
|
+
// Create regex object with case insensitive flag
|
|
159
|
+
const regex = new RegExp(`^${regexPattern}$`, 'i');
|
|
160
|
+
// If hostname matches this complex pattern, add it to the list
|
|
161
|
+
if (regex.test(hostname)) {
|
|
162
|
+
patterns.push(domain);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return patterns;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Find a route for a specific host and path
|
|
170
|
+
*/
|
|
171
|
+
findRouteForHost(hostname, path) {
|
|
172
|
+
// Find all routes for this hostname
|
|
173
|
+
const matchingRoutes = this.routes.filter(route => {
|
|
174
|
+
if (!route.match.domains)
|
|
175
|
+
return false;
|
|
176
|
+
const domains = Array.isArray(route.match.domains)
|
|
177
|
+
? route.match.domains
|
|
178
|
+
: [route.match.domains];
|
|
179
|
+
return domains.some(domain => domain.toLowerCase() === hostname.toLowerCase());
|
|
180
|
+
});
|
|
181
|
+
if (matchingRoutes.length === 0) {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
// First try routes with path patterns
|
|
185
|
+
const routesWithPaths = matchingRoutes.filter(route => this.pathPatterns.has(route));
|
|
186
|
+
// Already sorted by priority during setRoutes
|
|
187
|
+
// Check each route with path pattern
|
|
188
|
+
for (const route of routesWithPaths) {
|
|
189
|
+
const pathPattern = this.pathPatterns.get(route);
|
|
190
|
+
if (pathPattern) {
|
|
191
|
+
const pathMatch = this.matchPath(path, pathPattern);
|
|
192
|
+
if (pathMatch) {
|
|
193
|
+
return {
|
|
194
|
+
route,
|
|
195
|
+
pathMatch: pathMatch.matched,
|
|
196
|
+
pathParams: pathMatch.params,
|
|
197
|
+
pathRemainder: pathMatch.remainder
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// If no path pattern matched, use the first route without a path pattern
|
|
203
|
+
const routeWithoutPath = matchingRoutes.find(route => !this.pathPatterns.has(route));
|
|
204
|
+
if (routeWithoutPath) {
|
|
205
|
+
return { route: routeWithoutPath };
|
|
206
|
+
}
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Matches a URL path against a pattern
|
|
211
|
+
* Supports:
|
|
212
|
+
* - Exact matches: /users/profile
|
|
213
|
+
* - Wildcards: /api/* (matches any path starting with /api/)
|
|
214
|
+
* - Path parameters: /users/:id (captures id as a parameter)
|
|
215
|
+
*
|
|
216
|
+
* @param path The URL path to match
|
|
217
|
+
* @param pattern The pattern to match against
|
|
218
|
+
* @returns Match result with params and remainder, or null if no match
|
|
219
|
+
*/
|
|
220
|
+
matchPath(path, pattern) {
|
|
221
|
+
// Handle exact match
|
|
222
|
+
if (path === pattern) {
|
|
223
|
+
return {
|
|
224
|
+
matched: pattern,
|
|
225
|
+
params: {},
|
|
226
|
+
remainder: ''
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
// Handle wildcard match
|
|
230
|
+
if (pattern.endsWith('/*')) {
|
|
231
|
+
const prefix = pattern.slice(0, -2);
|
|
232
|
+
if (path === prefix || path.startsWith(`${prefix}/`)) {
|
|
233
|
+
return {
|
|
234
|
+
matched: prefix,
|
|
235
|
+
params: {},
|
|
236
|
+
remainder: path.slice(prefix.length)
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
// Handle path parameters
|
|
242
|
+
const patternParts = pattern.split('/').filter(p => p);
|
|
243
|
+
const pathParts = path.split('/').filter(p => p);
|
|
244
|
+
// Too few path parts to match
|
|
245
|
+
if (pathParts.length < patternParts.length) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
const params = {};
|
|
249
|
+
// Compare each part
|
|
250
|
+
for (let i = 0; i < patternParts.length; i++) {
|
|
251
|
+
const patternPart = patternParts[i];
|
|
252
|
+
const pathPart = pathParts[i];
|
|
253
|
+
// Handle parameter
|
|
254
|
+
if (patternPart.startsWith(':')) {
|
|
255
|
+
const paramName = patternPart.slice(1);
|
|
256
|
+
params[paramName] = pathPart;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
// Handle wildcard at the end
|
|
260
|
+
if (patternPart === '*' && i === patternParts.length - 1) {
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
// Handle exact match for this part
|
|
264
|
+
if (patternPart !== pathPart) {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Calculate the remainder - the unmatched path parts
|
|
269
|
+
const remainderParts = pathParts.slice(patternParts.length);
|
|
270
|
+
const remainder = remainderParts.length ? '/' + remainderParts.join('/') : '';
|
|
271
|
+
// Calculate the matched path
|
|
272
|
+
const matchedParts = patternParts.map((part, i) => {
|
|
273
|
+
return part.startsWith(':') ? pathParts[i] : part;
|
|
274
|
+
});
|
|
275
|
+
const matched = '/' + matchedParts.join('/');
|
|
276
|
+
return {
|
|
277
|
+
matched,
|
|
278
|
+
params,
|
|
279
|
+
remainder
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Gets all currently active route configurations
|
|
284
|
+
* @returns Array of all active routes
|
|
285
|
+
*/
|
|
286
|
+
getRoutes() {
|
|
287
|
+
return [...this.routes];
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Gets all hostnames that this router is configured to handle
|
|
291
|
+
* @returns Array of hostnames
|
|
292
|
+
*/
|
|
293
|
+
getHostnames() {
|
|
294
|
+
const hostnames = new Set();
|
|
295
|
+
for (const route of this.routes) {
|
|
296
|
+
if (!route.match.domains)
|
|
297
|
+
continue;
|
|
298
|
+
const domains = Array.isArray(route.match.domains)
|
|
299
|
+
? route.match.domains
|
|
300
|
+
: [route.match.domains];
|
|
301
|
+
for (const domain of domains) {
|
|
302
|
+
if (domain !== '*') {
|
|
303
|
+
hostnames.add(domain.toLowerCase());
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return Array.from(hostnames);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Adds a single new route configuration
|
|
311
|
+
* @param route The route configuration to add
|
|
312
|
+
*/
|
|
313
|
+
addRoute(route) {
|
|
314
|
+
this.routes.push(route);
|
|
315
|
+
// Store path pattern if present
|
|
316
|
+
if (route.match.path) {
|
|
317
|
+
this.pathPatterns.set(route, route.match.path);
|
|
318
|
+
}
|
|
319
|
+
// Re-sort routes by priority
|
|
320
|
+
this.routes.sort((a, b) => {
|
|
321
|
+
const priorityA = a.priority ?? 0;
|
|
322
|
+
const priorityB = b.priority ?? 0;
|
|
323
|
+
return priorityB - priorityA;
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Removes routes by domain pattern
|
|
328
|
+
* @param domain The domain pattern to remove routes for
|
|
329
|
+
* @returns Boolean indicating whether any routes were removed
|
|
330
|
+
*/
|
|
331
|
+
removeRoutesByDomain(domain) {
|
|
332
|
+
const initialCount = this.routes.length;
|
|
333
|
+
// Find routes to remove
|
|
334
|
+
const routesToRemove = this.routes.filter(route => {
|
|
335
|
+
if (!route.match.domains)
|
|
336
|
+
return false;
|
|
337
|
+
const domains = Array.isArray(route.match.domains)
|
|
338
|
+
? route.match.domains
|
|
339
|
+
: [route.match.domains];
|
|
340
|
+
return domains.includes(domain);
|
|
341
|
+
});
|
|
342
|
+
// Remove them from the patterns map
|
|
343
|
+
for (const route of routesToRemove) {
|
|
344
|
+
this.pathPatterns.delete(route);
|
|
345
|
+
}
|
|
346
|
+
// Filter them out of the routes array
|
|
347
|
+
this.routes = this.routes.filter(route => {
|
|
348
|
+
if (!route.match.domains)
|
|
349
|
+
return true;
|
|
350
|
+
const domains = Array.isArray(route.match.domains)
|
|
351
|
+
? route.match.domains
|
|
352
|
+
: [route.match.domains];
|
|
353
|
+
return !domains.includes(domain);
|
|
354
|
+
});
|
|
355
|
+
return this.routes.length !== initialCount;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Legacy method for compatibility with ProxyRouter
|
|
359
|
+
* Converts IReverseProxyConfig to IRouteConfig and calls setRoutes
|
|
360
|
+
*
|
|
361
|
+
* @param configs Array of legacy proxy configurations
|
|
362
|
+
*/
|
|
363
|
+
setNewProxyConfigs(configs) {
|
|
364
|
+
// Convert legacy configs to routes and add them
|
|
365
|
+
const routes = configs.map(config => {
|
|
366
|
+
// Create a basic route configuration from the legacy config
|
|
367
|
+
return {
|
|
368
|
+
match: {
|
|
369
|
+
ports: config.destinationPorts[0], // Just use the first port
|
|
370
|
+
domains: config.hostName
|
|
371
|
+
},
|
|
372
|
+
action: {
|
|
373
|
+
type: 'forward',
|
|
374
|
+
target: {
|
|
375
|
+
host: config.destinationIps,
|
|
376
|
+
port: config.destinationPorts[0]
|
|
377
|
+
},
|
|
378
|
+
tls: {
|
|
379
|
+
mode: 'terminate',
|
|
380
|
+
certificate: {
|
|
381
|
+
key: config.privateKey,
|
|
382
|
+
cert: config.publicKey
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
name: `Legacy Config - ${config.hostName}`,
|
|
387
|
+
enabled: true
|
|
388
|
+
};
|
|
389
|
+
});
|
|
390
|
+
this.setRoutes(routes);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUtcm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvcm91dGluZy9yb3V0ZXIvcm91dGUtcm91dGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFxQjVDOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFVdEIsWUFDRSxNQUF1QixFQUN2QixNQUFnQjtRQVhsQixzQ0FBc0M7UUFDOUIsV0FBTSxHQUFtQixFQUFFLENBQUM7UUFHcEMsNkVBQTZFO1FBQ3JFLGlCQUFZLEdBQThCLElBQUksR0FBRyxFQUFFLENBQUM7UUFRMUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLElBQUk7WUFDdEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1lBQ3BCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtZQUNsQixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDbEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1NBQ3JCLENBQUM7UUFFRixJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNJLFNBQVMsQ0FBQyxNQUFzQjtRQUNyQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQztRQUUxQiwwQkFBMEI7UUFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDeEIsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUM7WUFDbEMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUM7WUFDbEMsT0FBTyxTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQy9CLENBQUMs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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartproxy",
|
|
3
|
-
"version": "19.3.
|
|
3
|
+
"version": "19.3.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
package/readme.md
CHANGED
|
@@ -43,7 +43,7 @@ SmartProxy has been restructured using a modern, modular architecture with a uni
|
|
|
43
43
|
│ │ ├── route-manager.ts # Route management system
|
|
44
44
|
│ │ ├── smart-proxy.ts # Main SmartProxy class
|
|
45
45
|
│ │ └── ... # Supporting classes
|
|
46
|
-
│ ├── /
|
|
46
|
+
│ ├── /http-proxy # HttpProxy implementation (HTTP/HTTPS handling)
|
|
47
47
|
│ └── /nftables-proxy # NfTablesProxy implementation
|
|
48
48
|
├── /tls # TLS-specific functionality
|
|
49
49
|
│ ├── /sni # SNI handling components
|
|
@@ -79,7 +79,7 @@ SmartProxy has been restructured using a modern, modular architecture with a uni
|
|
|
79
79
|
|
|
80
80
|
### Specialized Components
|
|
81
81
|
|
|
82
|
-
- **
|
|
82
|
+
- **HttpProxy** (`ts/proxies/http-proxy/http-proxy.ts`)
|
|
83
83
|
HTTP/HTTPS reverse proxy with TLS termination and WebSocket support
|
|
84
84
|
- **Port80Handler** (`ts/http/port80/port80-handler.ts`)
|
|
85
85
|
ACME HTTP-01 challenge handler for Let's Encrypt certificates
|
|
@@ -101,7 +101,7 @@ SmartProxy has been restructured using a modern, modular architecture with a uni
|
|
|
101
101
|
|
|
102
102
|
- `IRouteConfig`, `IRouteMatch`, `IRouteAction` (`ts/proxies/smart-proxy/models/route-types.ts`)
|
|
103
103
|
- `IRoutedSmartProxyOptions` (`ts/proxies/smart-proxy/models/route-types.ts`)
|
|
104
|
-
- `
|
|
104
|
+
- `IHttpProxyOptions` (`ts/proxies/http-proxy/models/types.ts`)
|
|
105
105
|
- `IAcmeOptions`, `IDomainOptions` (`ts/certificate/models/certificate-types.ts`)
|
|
106
106
|
- `INfTableProxySettings` (`ts/proxies/nftables-proxy/models/interfaces.ts`)
|
|
107
107
|
|
|
@@ -113,7 +113,7 @@ npm install @push.rocks/smartproxy
|
|
|
113
113
|
|
|
114
114
|
## Quick Start with SmartProxy
|
|
115
115
|
|
|
116
|
-
SmartProxy
|
|
116
|
+
SmartProxy v19.4.0 provides a unified route-based configuration system with enhanced certificate management, NFTables integration for high-performance kernel-level routing, and improved helper functions for common proxy setups.
|
|
117
117
|
|
|
118
118
|
```typescript
|
|
119
119
|
import {
|
|
@@ -136,10 +136,12 @@ import {
|
|
|
136
136
|
const proxy = new SmartProxy({
|
|
137
137
|
// Global ACME settings for all routes with certificate: 'auto'
|
|
138
138
|
acme: {
|
|
139
|
-
email: 'ssl@
|
|
139
|
+
email: 'ssl@bleu.de', // Required for Let's Encrypt
|
|
140
140
|
useProduction: false, // Use staging by default
|
|
141
141
|
renewThresholdDays: 30, // Renew 30 days before expiry
|
|
142
|
-
port: 80
|
|
142
|
+
port: 80, // Port for HTTP-01 challenges (use 8080 for non-privileged)
|
|
143
|
+
autoRenew: true, // Enable automatic renewal
|
|
144
|
+
renewCheckIntervalHours: 24 // Check for renewals daily
|
|
143
145
|
},
|
|
144
146
|
|
|
145
147
|
// Define all your routing rules in a single array
|
|
@@ -216,26 +218,7 @@ const proxy = new SmartProxy({
|
|
|
216
218
|
certificate: 'auto',
|
|
217
219
|
maxRate: '100mbps'
|
|
218
220
|
})
|
|
219
|
-
]
|
|
220
|
-
|
|
221
|
-
// Global settings that apply to all routes
|
|
222
|
-
defaults: {
|
|
223
|
-
security: {
|
|
224
|
-
maxConnections: 500
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
|
|
228
|
-
// Automatic Let's Encrypt integration
|
|
229
|
-
acme: {
|
|
230
|
-
enabled: true,
|
|
231
|
-
contactEmail: 'admin@example.com',
|
|
232
|
-
useProduction: true
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
// Listen for certificate events
|
|
237
|
-
proxy.on('certificate', evt => {
|
|
238
|
-
console.log(`Certificate for ${evt.domain} ready, expires: ${evt.expiryDate}`);
|
|
221
|
+
]
|
|
239
222
|
});
|
|
240
223
|
|
|
241
224
|
// Start the proxy
|
|
@@ -749,14 +732,14 @@ Available helper functions:
|
|
|
749
732
|
|
|
750
733
|
While SmartProxy provides a unified API for most needs, you can also use individual components:
|
|
751
734
|
|
|
752
|
-
###
|
|
735
|
+
### HttpProxy
|
|
753
736
|
For HTTP/HTTPS reverse proxy with TLS termination and WebSocket support. Now with native route-based configuration support:
|
|
754
737
|
|
|
755
738
|
```typescript
|
|
756
|
-
import {
|
|
739
|
+
import { HttpProxy } from '@push.rocks/smartproxy';
|
|
757
740
|
import * as fs from 'fs';
|
|
758
741
|
|
|
759
|
-
const proxy = new
|
|
742
|
+
const proxy = new HttpProxy({ port: 443 });
|
|
760
743
|
await proxy.start();
|
|
761
744
|
|
|
762
745
|
// Modern route-based configuration (recommended)
|
|
@@ -781,7 +764,7 @@ await proxy.updateRouteConfigs([
|
|
|
781
764
|
},
|
|
782
765
|
advanced: {
|
|
783
766
|
headers: {
|
|
784
|
-
'X-Forwarded-By': '
|
|
767
|
+
'X-Forwarded-By': 'HttpProxy'
|
|
785
768
|
},
|
|
786
769
|
urlRewrite: {
|
|
787
770
|
pattern: '^/old/(.*)$',
|
|
@@ -1053,7 +1036,7 @@ flowchart TB
|
|
|
1053
1036
|
direction TB
|
|
1054
1037
|
RouteConfig["Route Configuration<br>(Match/Action)"]
|
|
1055
1038
|
RouteManager["Route Manager"]
|
|
1056
|
-
HTTPS443["HTTPS Port 443<br>
|
|
1039
|
+
HTTPS443["HTTPS Port 443<br>HttpProxy"]
|
|
1057
1040
|
SmartProxy["SmartProxy<br>(TCP/SNI Proxy)"]
|
|
1058
1041
|
ACME["Port80Handler<br>(ACME HTTP-01)"]
|
|
1059
1042
|
Certs[(SSL Certificates)]
|
|
@@ -1439,7 +1422,7 @@ createRedirectRoute({
|
|
|
1439
1422
|
- `getListeningPorts()` - Get all ports currently being listened on
|
|
1440
1423
|
- `async updateRoutes(routes: IRouteConfig[])` - Update routes and automatically adjust port listeners
|
|
1441
1424
|
|
|
1442
|
-
###
|
|
1425
|
+
### HttpProxy (IHttpProxyOptions)
|
|
1443
1426
|
- `port` (number, required) - Main port to listen on
|
|
1444
1427
|
- `backendProtocol` ('http1'|'http2', default 'http1') - Protocol to use with backend servers
|
|
1445
1428
|
- `maxConnections` (number, default 10000) - Maximum concurrent connections
|
|
@@ -1452,8 +1435,8 @@ createRedirectRoute({
|
|
|
1452
1435
|
- `useExternalPort80Handler` (boolean) - Use external port 80 handler for ACME challenges
|
|
1453
1436
|
- `portProxyIntegration` (boolean) - Integration with other proxies
|
|
1454
1437
|
|
|
1455
|
-
####
|
|
1456
|
-
|
|
1438
|
+
#### HttpProxy Enhanced Features
|
|
1439
|
+
HttpProxy now supports full route-based configuration including:
|
|
1457
1440
|
- Advanced request and response header manipulation
|
|
1458
1441
|
- URL rewriting with RegExp pattern matching
|
|
1459
1442
|
- Template variable resolution for dynamic values (e.g. `{domain}`, `{clientIp}`)
|
|
@@ -1507,7 +1490,7 @@ NetworkProxy now supports full route-based configuration including:
|
|
|
1507
1490
|
- Ensure domains are publicly accessible for Let's Encrypt validation
|
|
1508
1491
|
- For TLS handshake issues, increase `initialDataTimeout` and `maxPendingDataSize`
|
|
1509
1492
|
|
|
1510
|
-
###
|
|
1493
|
+
### HttpProxy
|
|
1511
1494
|
- Verify ports, certificates and `rejectUnauthorized` for TLS errors
|
|
1512
1495
|
- Configure CORS for preflight issues
|
|
1513
1496
|
- Increase `maxConnections` or `connectionPoolSize` under load
|