mirror of https://github.com/1Panel-dev/1Panel
parent
bd8d96be4d
commit
d900b52a50
@ -1,32 +1,196 @@
|
|||||||
package components
|
package components
|
||||||
|
|
||||||
type Location struct {
|
type Location struct {
|
||||||
*Directive
|
Modifier string
|
||||||
Modifier string
|
Match string
|
||||||
Match string
|
Cache bool
|
||||||
|
ProxyPass string
|
||||||
|
Host string
|
||||||
|
CacheTime string
|
||||||
|
|
||||||
|
Comment string
|
||||||
|
Directives []IDirective
|
||||||
|
Line int
|
||||||
|
Parameters []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLocation(directive *Directive) *Location {
|
func NewLocation(directive IDirective) *Location {
|
||||||
location := &Location{
|
location := &Location{
|
||||||
Modifier: "",
|
Modifier: "",
|
||||||
Match: "",
|
Match: "",
|
||||||
Directive: directive,
|
}
|
||||||
|
directives := make([]IDirective, 0)
|
||||||
|
if len(directive.GetParameters()) == 0 {
|
||||||
|
panic("no enough parameter for location")
|
||||||
}
|
}
|
||||||
if directive.GetBlock() != nil {
|
for _, dir := range directive.GetBlock().GetDirectives() {
|
||||||
directive.Comment = directive.GetBlock().GetComment()
|
directives = append(directives, dir)
|
||||||
|
params := dir.GetParameters()
|
||||||
|
switch dir.GetName() {
|
||||||
|
case "proxy_pass":
|
||||||
|
location.ProxyPass = params[0]
|
||||||
|
case "proxy_set_header":
|
||||||
|
if params[0] == "Host" {
|
||||||
|
location.Host = params[1]
|
||||||
|
}
|
||||||
|
case "proxy_cache":
|
||||||
|
location.Cache = true
|
||||||
|
case "if":
|
||||||
|
if params[0] == "(" && params[1] == "$uri" && params[2] == "~*" {
|
||||||
|
dirs := dir.GetBlock().GetDirectives()
|
||||||
|
for _, di := range dirs {
|
||||||
|
if di.GetName() == "expires" {
|
||||||
|
location.CacheTime = di.GetParameters()[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(directive.Parameters) == 0 {
|
params := directive.GetParameters()
|
||||||
panic("no enough parameter for location")
|
if len(params) == 1 {
|
||||||
|
location.Match = params[0]
|
||||||
|
} else if len(params) == 2 {
|
||||||
|
location.Match = params[1]
|
||||||
|
location.Modifier = params[0]
|
||||||
}
|
}
|
||||||
|
location.Parameters = directive.GetParameters()
|
||||||
|
location.Line = directive.GetLine()
|
||||||
|
location.Comment = directive.GetComment()
|
||||||
|
location.Directives = directives
|
||||||
|
return location
|
||||||
|
}
|
||||||
|
|
||||||
if len(directive.Parameters) == 1 {
|
func (l *Location) GetName() string {
|
||||||
location.Match = directive.Parameters[0]
|
return "location"
|
||||||
return location
|
}
|
||||||
} else if len(directive.Parameters) == 2 {
|
|
||||||
location.Match = directive.Parameters[1]
|
func (l *Location) GetParameters() []string {
|
||||||
location.Modifier = directive.Parameters[0]
|
return l.Parameters
|
||||||
return location
|
}
|
||||||
|
|
||||||
|
func (l *Location) GetBlock() IBlock {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) GetComment() string {
|
||||||
|
return l.Comment
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) GetLine() int {
|
||||||
|
return l.Line
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) GetDirectives() []IDirective {
|
||||||
|
return l.Directives
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) FindDirectives(directiveName string) []IDirective {
|
||||||
|
directives := make([]IDirective, 0)
|
||||||
|
for _, directive := range l.Directives {
|
||||||
|
if directive.GetName() == directiveName {
|
||||||
|
directives = append(directives, directive)
|
||||||
|
}
|
||||||
|
if directive.GetBlock() != nil {
|
||||||
|
directives = append(directives, directive.GetBlock().FindDirectives(directiveName)...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return directives
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) UpdateDirective(key string, params []string) {
|
||||||
|
if key == "" || len(params) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
directives := l.Directives
|
||||||
|
index := -1
|
||||||
|
for i, dir := range directives {
|
||||||
|
if dir.GetName() == key {
|
||||||
|
if IsRepeatKey(key) {
|
||||||
|
oldParams := dir.GetParameters()
|
||||||
|
if !(len(oldParams) > 0 && oldParams[0] == params[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newDirective := &Directive{
|
||||||
|
Name: key,
|
||||||
|
Parameters: params,
|
||||||
|
}
|
||||||
|
if index > -1 {
|
||||||
|
directives[index] = newDirective
|
||||||
|
} else {
|
||||||
|
directives = append(directives, newDirective)
|
||||||
|
}
|
||||||
|
l.Directives = directives
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) RemoveDirective(key string, params []string) {
|
||||||
|
directives := l.Directives
|
||||||
|
var newDirectives []IDirective
|
||||||
|
for _, dir := range directives {
|
||||||
|
if dir.GetName() == key {
|
||||||
|
if len(params) > 0 {
|
||||||
|
oldParams := dir.GetParameters()
|
||||||
|
if oldParams[0] == params[0] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newDirectives = append(newDirectives, dir)
|
||||||
|
}
|
||||||
|
l.Directives = newDirectives
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) ChangePath(Modifier string, Match string) {
|
||||||
|
if Match != "" && Modifier != "" {
|
||||||
|
l.Parameters = []string{Modifier, Match}
|
||||||
|
}
|
||||||
|
if Match != "" && Modifier == "" {
|
||||||
|
l.Parameters = []string{Match}
|
||||||
|
}
|
||||||
|
l.Modifier = Modifier
|
||||||
|
l.Match = Match
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) AddCache(cacheTime string) {
|
||||||
|
l.RemoveDirective("add_header", []string{"Cache-Control", "no-cache"})
|
||||||
|
directives := l.GetDirectives()
|
||||||
|
newDir := &Directive{
|
||||||
|
Name: "if",
|
||||||
|
Parameters: []string{"(", "$uri", "~*", `"\.(gif|png|jpg|css|js|woff|woff2)$"`, ")"},
|
||||||
|
Block: &Block{},
|
||||||
|
}
|
||||||
|
block := &Block{}
|
||||||
|
block.Directives = append(block.Directives, &Directive{
|
||||||
|
Name: "expires",
|
||||||
|
Parameters: []string{cacheTime},
|
||||||
|
})
|
||||||
|
newDir.Block = block
|
||||||
|
directives = append(directives, newDir)
|
||||||
|
l.Directives = directives
|
||||||
|
l.UpdateDirective("proxy_ignore_headers", []string{"Set-Cookie", "Cache-Control", "expires"})
|
||||||
|
l.UpdateDirective("proxy_cache", []string{"proxy_cache_panel"})
|
||||||
|
l.UpdateDirective("proxy_cache_key", []string{"$host$uri$is_args$args"})
|
||||||
|
l.UpdateDirective("proxy_cache_valid", []string{"200", "304", "301", "302", "10m"})
|
||||||
|
l.Cache = true
|
||||||
|
l.CacheTime = cacheTime
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Location) RemoveCache() {
|
||||||
|
l.RemoveDirective("if", []string{"(", "$uri", "~*", `"\.(gif|png|jpg|css|js|woff|woff2)$"`, ")"})
|
||||||
|
l.RemoveDirective("proxy_ignore_headers", []string{"Set-Cookie"})
|
||||||
|
l.RemoveDirective("proxy_cache", []string{"proxy_cache_panel"})
|
||||||
|
l.RemoveDirective("proxy_cache_key", []string{"$host$uri$is_args$args"})
|
||||||
|
l.RemoveDirective("proxy_cache_valid", []string{"200"})
|
||||||
|
|
||||||
|
l.UpdateDirective("add_header", []string{"Cache-Control", "no-cache"})
|
||||||
|
|
||||||
|
l.CacheTime = ""
|
||||||
|
l.Cache = false
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
proxy_temp_path /www/common/proxy/proxy_temp_dir;
|
||||||
|
proxy_cache_path /www/common/proxy/proxy_cache_dir levels=1:2 keys_zone=proxy_cache_panel:20m inactive=1d max_size=5g;
|
||||||
|
client_body_buffer_size 512k;
|
||||||
|
proxy_connect_timeout 60;
|
||||||
|
proxy_read_timeout 60;
|
||||||
|
proxy_send_timeout 60;
|
||||||
|
proxy_buffer_size 32k;
|
||||||
|
proxy_buffers 4 64k;
|
||||||
|
proxy_busy_buffers_size 128k;
|
||||||
|
proxy_temp_file_write_size 128k;
|
||||||
|
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
|
||||||
|
proxy_cache proxy_cache_panel;
|
@ -0,0 +1,12 @@
|
|||||||
|
location ^~ /test {
|
||||||
|
proxy_pass http://1panel.cloud/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header REMOTE-HOST $remote_addr;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
add_header X-Cache $upstream_cache_status;
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
proxy_ignore_headers Set-Cookie Cache-Control expires;
|
||||||
|
proxy_cache cache_one;
|
||||||
|
proxy_cache_key $host$uri$is_args$args;
|
||||||
|
proxy_cache_valid 200 304 301 302 10m;
|
@ -0,0 +1,10 @@
|
|||||||
|
set $static_fileg 0;
|
||||||
|
if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
|
||||||
|
{
|
||||||
|
set $static_fileg 1;
|
||||||
|
expires 1m;
|
||||||
|
}
|
||||||
|
if ( $static_fileg = 0 )
|
||||||
|
{
|
||||||
|
add_header Cache-Control no-cache;
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer v-model="open" :close-on-click-modal="false" size="40%" :before-close="handleClose">
|
||||||
|
<template #header>
|
||||||
|
<DrawerHeader :header="$t('website.createProxy')" :back="handleClose" />
|
||||||
|
</template>
|
||||||
|
<el-row v-loading="loading">
|
||||||
|
<el-col :span="22" :offset="1">
|
||||||
|
<el-form ref="proxyForm" label-position="top" :model="proxy" :rules="rules">
|
||||||
|
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||||
|
<el-input v-model.trim="proxy.name"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('website.proxyPath')" prop="match">
|
||||||
|
<el-input v-model.trim="proxy.match"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('website.enableCache')" prop="cache">
|
||||||
|
<el-switch v-model="proxy.cache"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('website.cacheTime')" prop="cacheTime" v-if="proxy.cache">
|
||||||
|
<el-input v-model.number="proxy.cacheTime" maxlength="15">
|
||||||
|
<template #append>
|
||||||
|
<el-select v-model="proxy.cacheUnit" style="width: 80px">
|
||||||
|
<el-option
|
||||||
|
v-for="(unit, index) in Units"
|
||||||
|
:key="index"
|
||||||
|
:label="unit.label"
|
||||||
|
:value="unit.value"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('website.proxyPass')" prop="proxyPass">
|
||||||
|
<el-input v-model.trim="proxy.proxyPass"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('website.proxyHost')" prop="proxyHost">
|
||||||
|
<el-input v-model.trim="proxy.proxyHost"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
|
||||||
|
<el-button type="primary" @click="submit(proxyForm)" :disabled="loading">
|
||||||
|
{{ $t('commons.button.confirm') }}
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
|
import { CreateProxyConfig } from '@/api/modules/website';
|
||||||
|
import { checkNumberRange, Rules } from '@/global/form-rules';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
import { FormInstance } from 'element-plus';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { MsgSuccess } from '@/utils/message';
|
||||||
|
import { Website } from '@/api/interface/website';
|
||||||
|
import { Units } from '@/global/mimetype';
|
||||||
|
// import { Website } from '@/api/interface/website';
|
||||||
|
|
||||||
|
const proxyForm = ref<FormInstance>();
|
||||||
|
const rules = ref({
|
||||||
|
name: [Rules.requiredInput, Rules.appName],
|
||||||
|
match: [Rules.requiredInput],
|
||||||
|
cacheTime: [Rules.requiredInput, checkNumberRange(1, 65535)],
|
||||||
|
proxyPass: [Rules.requiredInput],
|
||||||
|
proxyHost: [Rules.requiredInput],
|
||||||
|
});
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const initData = (): Website.ProxyConfig => ({
|
||||||
|
id: 0,
|
||||||
|
operate: 'create',
|
||||||
|
enable: true,
|
||||||
|
cache: false,
|
||||||
|
cacheTime: 1,
|
||||||
|
cacheUnit: 'm',
|
||||||
|
name: '',
|
||||||
|
modifier: '^~',
|
||||||
|
match: '/',
|
||||||
|
proxyPass: 'http://',
|
||||||
|
proxyHost: '$host',
|
||||||
|
filePath: '',
|
||||||
|
});
|
||||||
|
let proxy = ref(initData());
|
||||||
|
|
||||||
|
const em = defineEmits(['close']);
|
||||||
|
const handleClose = () => {
|
||||||
|
proxyForm.value?.resetFields();
|
||||||
|
open.value = false;
|
||||||
|
em('close', false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const acceptParams = async (proxyParam: Website.ProxyConfig) => {
|
||||||
|
proxy.value = proxyParam;
|
||||||
|
open.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
await formEl.validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loading.value = true;
|
||||||
|
CreateProxyConfig(proxy.value)
|
||||||
|
.then(() => {
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
|
||||||
|
handleClose();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams,
|
||||||
|
});
|
||||||
|
</script>
|
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<ComplexTable :data="data" @search="search" v-loading="loading">
|
||||||
|
<template #toolbar>
|
||||||
|
<el-button type="primary" plain @click="openCreate">{{ $t('website.addProxy') }}</el-button>
|
||||||
|
</template>
|
||||||
|
<el-table-column :label="$t('commons.table.name')" prop="name"></el-table-column>
|
||||||
|
<el-table-column :label="$t('website.proxyPath')" prop="match"></el-table-column>
|
||||||
|
<el-table-column :label="$t('website.proxyPass')" prop="proxyPass"></el-table-column>
|
||||||
|
<el-table-column :label="$t('website.cache')" prop="cache">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-switch v-model="row.cache"></el-switch>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('commons.table.status')" prop="enable">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button v-if="row.enable" link type="success" :icon="VideoPlay">
|
||||||
|
{{ $t('commons.status.running') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button v-else link type="danger" :icon="VideoPause">
|
||||||
|
{{ $t('commons.status.stopped') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ComplexTable>
|
||||||
|
<Create ref="createRef" @close="search()" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="proxy">
|
||||||
|
import { Website } from '@/api/interface/website';
|
||||||
|
import { GetProxyConfig } from '@/api/modules/website';
|
||||||
|
import { computed, onMounted, ref } from 'vue';
|
||||||
|
import Create from './create/index.vue';
|
||||||
|
import { VideoPlay, VideoPause } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const id = computed(() => {
|
||||||
|
return props.id;
|
||||||
|
});
|
||||||
|
const loading = ref(false);
|
||||||
|
const data = ref();
|
||||||
|
const createRef = ref();
|
||||||
|
|
||||||
|
const initData = (id: number): Website.ProxyConfig => ({
|
||||||
|
id: id,
|
||||||
|
operate: 'create',
|
||||||
|
enable: true,
|
||||||
|
cache: false,
|
||||||
|
cacheTime: 1,
|
||||||
|
cacheUnit: 'm',
|
||||||
|
name: '',
|
||||||
|
modifier: '^~',
|
||||||
|
match: '/',
|
||||||
|
proxyPass: 'http://',
|
||||||
|
proxyHost: '$host',
|
||||||
|
});
|
||||||
|
|
||||||
|
const openCreate = () => {
|
||||||
|
createRef.value.acceptParams(initData(id.value));
|
||||||
|
};
|
||||||
|
const search = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const res = await GetProxyConfig({ id: id.value });
|
||||||
|
data.value = res.data || [];
|
||||||
|
} catch (error) {
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
search();
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Reference in new issue