mirror of https://github.com/fatedier/frp
show tcpmux proxies on the frps dashboard (#4152)
parent
dd7e2e8473
commit
f3a71bc08f
|
@ -1,3 +1,7 @@
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Show tcpmux proxies on the frps dashboard.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
* When an HTTP proxy request times out, it returns 504 instead of 404 now.
|
* When an HTTP proxy request times out, it returns 504 instead of 404 now.
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -4,7 +4,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>frps dashboard</title>
|
<title>frps dashboard</title>
|
||||||
<script type="module" crossorigin src="./index-Q42Pu2_S.js"></script>
|
<script type="module" crossorigin src="./index-82-40HIG.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="./index-rzPDshRD.css">
|
<link rel="stylesheet" crossorigin href="./index-rzPDshRD.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,7 @@ type TCPMuxOutConf struct {
|
||||||
BaseOutConf
|
BaseOutConf
|
||||||
v1.DomainConfig
|
v1.DomainConfig
|
||||||
Multiplexer string `json:"multiplexer"`
|
Multiplexer string `json:"multiplexer"`
|
||||||
|
RouteByHTTPUser string `json:"routeByHTTPUser"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UDPOutConf struct {
|
type UDPOutConf struct {
|
||||||
|
|
|
@ -31,6 +31,7 @@ declare module 'vue' {
|
||||||
ProxiesSTCP: typeof import('./src/components/ProxiesSTCP.vue')['default']
|
ProxiesSTCP: typeof import('./src/components/ProxiesSTCP.vue')['default']
|
||||||
ProxiesSUDP: typeof import('./src/components/ProxiesSUDP.vue')['default']
|
ProxiesSUDP: typeof import('./src/components/ProxiesSUDP.vue')['default']
|
||||||
ProxiesTCP: typeof import('./src/components/ProxiesTCP.vue')['default']
|
ProxiesTCP: typeof import('./src/components/ProxiesTCP.vue')['default']
|
||||||
|
ProxiesTCPMux: typeof import('./src/components/ProxiesTCPMux.vue')['default']
|
||||||
ProxiesUDP: typeof import('./src/components/ProxiesUDP.vue')['default']
|
ProxiesUDP: typeof import('./src/components/ProxiesUDP.vue')['default']
|
||||||
ProxyView: typeof import('./src/components/ProxyView.vue')['default']
|
ProxyView: typeof import('./src/components/ProxyView.vue')['default']
|
||||||
ProxyViewExpand: typeof import('./src/components/ProxyViewExpand.vue')['default']
|
ProxyViewExpand: typeof import('./src/components/ProxyViewExpand.vue')['default']
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<el-menu-item index="/proxies/udp">UDP</el-menu-item>
|
<el-menu-item index="/proxies/udp">UDP</el-menu-item>
|
||||||
<el-menu-item index="/proxies/http">HTTP</el-menu-item>
|
<el-menu-item index="/proxies/http">HTTP</el-menu-item>
|
||||||
<el-menu-item index="/proxies/https">HTTPS</el-menu-item>
|
<el-menu-item index="/proxies/https">HTTPS</el-menu-item>
|
||||||
|
<el-menu-item index="/proxies/tcpmux">TCPMUX</el-menu-item>
|
||||||
<el-menu-item index="/proxies/stcp">STCP</el-menu-item>
|
<el-menu-item index="/proxies/stcp">STCP</el-menu-item>
|
||||||
<el-menu-item index="/proxies/sudp">SUDP</el-menu-item>
|
<el-menu-item index="/proxies/sudp">SUDP</el-menu-item>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<template>
|
||||||
|
<ProxyView :proxies="proxies" proxyType="tcpmux" @refresh="fetchData" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { TCPMuxProxy } from '../utils/proxy.js'
|
||||||
|
import ProxyView from './ProxyView.vue'
|
||||||
|
|
||||||
|
let proxies = ref<TCPMuxProxy[]>([])
|
||||||
|
|
||||||
|
const fetchData = () => {
|
||||||
|
let tcpmuxHTTPConnectPort: number
|
||||||
|
let subdomainHost: string
|
||||||
|
fetch('../api/serverinfo', { credentials: 'include' })
|
||||||
|
.then((res) => {
|
||||||
|
return res.json()
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
tcpmuxHTTPConnectPort = json.tcpmuxHTTPConnectPort
|
||||||
|
subdomainHost = json.subdomainHost
|
||||||
|
|
||||||
|
fetch('../api/proxy/tcpmux', { credentials: 'include' })
|
||||||
|
.then((res) => {
|
||||||
|
return res.json()
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
proxies.value = []
|
||||||
|
for (let proxyStats of json.proxies) {
|
||||||
|
proxies.value.push(new TCPMuxProxy(proxyStats, tcpmuxHTTPConnectPort, subdomainHost))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fetchData()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form
|
<el-form
|
||||||
label-position="left"
|
label-position="left"
|
||||||
|
label-width="auto"
|
||||||
inline
|
inline
|
||||||
class="proxy-table-expand"
|
class="proxy-table-expand"
|
||||||
v-if="proxyType === 'http' || proxyType === 'https'"
|
|
||||||
>
|
>
|
||||||
<el-form-item label="Name">
|
<el-form-item label="Name">
|
||||||
<span>{{ row.name }}</span>
|
<span>{{ row.name }}</span>
|
||||||
|
@ -11,6 +11,20 @@
|
||||||
<el-form-item label="Type">
|
<el-form-item label="Type">
|
||||||
<span>{{ row.type }}</span>
|
<span>{{ row.type }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="Encryption">
|
||||||
|
<span>{{ row.encryption }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Compression">
|
||||||
|
<span>{{ row.compression }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Last Start">
|
||||||
|
<span>{{ row.lastStartTime }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Last Close">
|
||||||
|
<span>{{ row.lastCloseTime }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<div v-if="proxyType === 'http' || proxyType === 'https'">
|
||||||
<el-form-item label="Domains">
|
<el-form-item label="Domains">
|
||||||
<span>{{ row.customDomains }}</span>
|
<span>{{ row.customDomains }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
@ -23,42 +37,26 @@
|
||||||
<el-form-item label="HostRewrite">
|
<el-form-item label="HostRewrite">
|
||||||
<span>{{ row.hostHeaderRewrite }}</span>
|
<span>{{ row.hostHeaderRewrite }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Encryption">
|
</div>
|
||||||
<span>{{ row.encryption }}</span>
|
<div v-else-if="proxyType === 'tcpmux'">
|
||||||
|
<el-form-item label="Multiplexer">
|
||||||
|
<span>{{ row.multiplexer }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Compression">
|
<el-form-item label="RouteByHTTPUser">
|
||||||
<span>{{ row.compression }}</span>
|
<span>{{ row.routeByHTTPUser }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Last Start">
|
<el-form-item label="Domains">
|
||||||
<span>{{ row.lastStartTime }}</span>
|
<span>{{ row.customDomains }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Last Close">
|
<el-form-item label="SubDomain">
|
||||||
<span>{{ row.lastCloseTime }}</span>
|
<span>{{ row.subdomain }}</span>
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-form label-position="left" inline class="proxy-table-expand" v-else>
|
|
||||||
<el-form-item label="Name">
|
|
||||||
<span>{{ row.name }}</span>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="Type">
|
|
||||||
<span>{{ row.type }}</span>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
<el-form-item label="Addr">
|
<el-form-item label="Addr">
|
||||||
<span>{{ row.addr }}</span>
|
<span>{{ row.addr }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Encryption">
|
</div>
|
||||||
<span>{{ row.encryption }}</span>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="Compression">
|
|
||||||
<span>{{ row.compression }}</span>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="Last Start">
|
|
||||||
<span>{{ row.lastStartTime }}</span>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="Last Close">
|
|
||||||
<span>{{ row.lastCloseTime }}</span>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div v-if="row.annotations && row.annotations.size > 0">
|
<div v-if="row.annotations && row.annotations.size > 0">
|
||||||
|
|
|
@ -20,10 +20,10 @@
|
||||||
<el-form-item label="QUIC Bind Port" v-if="data.quicBindPort != 0">
|
<el-form-item label="QUIC Bind Port" v-if="data.quicBindPort != 0">
|
||||||
<span>{{ data.quicBindPort }}</span>
|
<span>{{ data.quicBindPort }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Http Port" v-if="data.vhostHTTPPort != 0">
|
<el-form-item label="HTTP Port" v-if="data.vhostHTTPPort != 0">
|
||||||
<span>{{ data.vhostHTTPPort }}</span>
|
<span>{{ data.vhostHTTPPort }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Https Port" v-if="data.vhostHTTPSPort != 0">
|
<el-form-item label="HTTPS Port" v-if="data.vhostHTTPSPort != 0">
|
||||||
<span>{{ data.vhostHTTPSPort }}</span>
|
<span>{{ data.vhostHTTPSPort }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
|
|
@ -4,6 +4,7 @@ import ProxiesTCP from '../components/ProxiesTCP.vue'
|
||||||
import ProxiesUDP from '../components/ProxiesUDP.vue'
|
import ProxiesUDP from '../components/ProxiesUDP.vue'
|
||||||
import ProxiesHTTP from '../components/ProxiesHTTP.vue'
|
import ProxiesHTTP from '../components/ProxiesHTTP.vue'
|
||||||
import ProxiesHTTPS from '../components/ProxiesHTTPS.vue'
|
import ProxiesHTTPS from '../components/ProxiesHTTPS.vue'
|
||||||
|
import ProxiesTCPMux from '../components/ProxiesTCPMux.vue'
|
||||||
import ProxiesSTCP from '../components/ProxiesSTCP.vue'
|
import ProxiesSTCP from '../components/ProxiesSTCP.vue'
|
||||||
import ProxiesSUDP from '../components/ProxiesSUDP.vue'
|
import ProxiesSUDP from '../components/ProxiesSUDP.vue'
|
||||||
|
|
||||||
|
@ -35,6 +36,11 @@ const router = createRouter({
|
||||||
name: 'ProxiesHTTPS',
|
name: 'ProxiesHTTPS',
|
||||||
component: ProxiesHTTPS,
|
component: ProxiesHTTPS,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/proxies/tcpmux',
|
||||||
|
name: 'ProxiesTCPMux',
|
||||||
|
component: ProxiesTCPMux,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/proxies/stcp',
|
path: '/proxies/stcp',
|
||||||
name: 'ProxiesSTCP',
|
name: 'ProxiesSTCP',
|
||||||
|
|
|
@ -110,6 +110,28 @@ class HTTPSProxy extends BaseProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TCPMuxProxy extends BaseProxy {
|
||||||
|
multiplexer: string
|
||||||
|
routeByHTTPUser: string
|
||||||
|
|
||||||
|
constructor(proxyStats: any, port: number, subdomainHost: string) {
|
||||||
|
super(proxyStats)
|
||||||
|
this.type = 'tcpmux'
|
||||||
|
this.port = port
|
||||||
|
this.multiplexer = ''
|
||||||
|
this.routeByHTTPUser = ''
|
||||||
|
|
||||||
|
if (proxyStats.conf) {
|
||||||
|
this.customDomains = proxyStats.conf.customDomains || this.customDomains
|
||||||
|
this.multiplexer = proxyStats.conf.multiplexer
|
||||||
|
this.routeByHTTPUser = proxyStats.conf.routeByHTTPUser
|
||||||
|
if (proxyStats.conf.subdomain) {
|
||||||
|
this.subdomain = `${proxyStats.conf.subdomain}.${subdomainHost}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class STCPProxy extends BaseProxy {
|
class STCPProxy extends BaseProxy {
|
||||||
constructor(proxyStats: any) {
|
constructor(proxyStats: any) {
|
||||||
super(proxyStats)
|
super(proxyStats)
|
||||||
|
@ -128,6 +150,7 @@ export {
|
||||||
BaseProxy,
|
BaseProxy,
|
||||||
TCPProxy,
|
TCPProxy,
|
||||||
UDPProxy,
|
UDPProxy,
|
||||||
|
TCPMuxProxy,
|
||||||
HTTPProxy,
|
HTTPProxy,
|
||||||
HTTPSProxy,
|
HTTPSProxy,
|
||||||
STCPProxy,
|
STCPProxy,
|
||||||
|
|
Loading…
Reference in New Issue