实现服务的缓存策略设置

This commit is contained in:
GoEdgeLab
2020-10-04 20:38:27 +08:00
parent db21a86825
commit 0bbd178b29
25 changed files with 502 additions and 133 deletions

View File

@@ -5,14 +5,15 @@ Vue.component("more-options-indicator", {
data: function () {
return {
visible: false
};
}
},
methods: {
changeVisible: function () {
this.visible = !this.visible;
this.visible = !this.visible
if (Tea.Vue != null) {
Tea.Vue.moreOptionsVisible = this.visible;
Tea.Vue.moreOptionsVisible = this.visible
}
this.$emit("change", this.visible)
}
},
template: '<a href="" style="font-weight: normal" @click.prevent="changeVisible()"><span v-if="!visible">更多选项</span><span v-if="visible">收起选项</span> <i class="icon angle" :class="{down:!visible, up:visible}"></i> </a>'

View File

@@ -12,7 +12,7 @@ Vue.component("size-capacity-box", {
v["count"] = -1
}
return {
"size": v,
size: v,
countString: (v.count >= 0) ? v.count.toString() : ""
}
},
@@ -21,12 +21,19 @@ Vue.component("size-capacity-box", {
let value = newValue.trim()
if (value.length == 0) {
this.size.count = -1
this.change()
return
}
let count = parseInt(value)
if (!isNaN(count)) {
this.size.count = count
}
this.change()
}
},
methods: {
change: function () {
this.$emit("change", this.size)
}
},
template: `<div class="ui fields inline">
@@ -35,7 +42,7 @@ Vue.component("size-capacity-box", {
<input type="text" v-model="countString" maxlength="11" size="11"/>
</div>
<div class="ui field">
<select class="ui dropdown" v-model="size.unit">
<select class="ui dropdown" v-model="size.unit" @change="change">
<option value="byte">字节</option>
<option value="kb">KB</option>
<option value="mb">MB</option>

View File

@@ -12,7 +12,7 @@ Vue.component("time-duration-box", {
v["count"] = -1
}
return {
"size": v,
duration: v,
countString: (v.count >= 0) ? v.count.toString() : ""
}
},
@@ -20,22 +20,28 @@ Vue.component("time-duration-box", {
"countString": function (newValue) {
let value = newValue.trim()
if (value.length == 0) {
this.size.count = -1
this.duration.count = -1
return
}
let count = parseInt(value)
if (!isNaN(count)) {
this.size.count = count
this.duration.count = count
}
this.change()
}
},
methods: {
change: function () {
this.$emit("change", this.duration)
}
},
template: `<div class="ui fields inline">
<input type="hidden" :name="vName" :value="JSON.stringify(size)"/>
<input type="hidden" :name="vName" :value="JSON.stringify(duration)"/>
<div class="ui field">
<input type="text" v-model="countString" maxlength="11" size="11"/>
</div>
<div class="ui field">
<select class="ui dropdown" v-model="size.unit">
<select class="ui dropdown" v-model="duration.unit" @change="change">
<option value="ms">毫秒</option>
<option value="second">秒</option>
<option value="minute">分钟</option>

View File

@@ -1,50 +0,0 @@
Vue.component("http-cache-cond-box", {
template: `<div>
<table class="ui table definition selectable">
<tr>
<td>匹配条件</td>
<td><http-request-conds-box></http-request-conds-box></td>
</tr>
<tr>
<td>缓存有效期</td>
<td>
<time-duration-box :name="'lifeJSON'" :v-count="3600" :v-unit="'second'"></time-duration-box>
</td>
</tr>
<tr>
<td>状态码列表</td>
<td>
<values-box name="statusList" size="3" maxlength="3" :values="['200']"></values-box>
<p class="comment">允许缓存的HTTP状态码列表。</p>
</td>
</tr>
<tr>
<td>跳过的Cache-Control值</td>
<td>
<values-box name="skipResponseCacheControlValues" size="10" maxlength="100" :values="['private', 'no-cache', 'no-store']"></values-box>
<p class="comment">当响应的Cache-Control为这些值时不缓存响应内容而且不区分大小写。</p>
</td>
</tr>
<tr>
<td>跳过Set-Cookie</td>
<td>
<div class="ui checkbox">
<input type="checkbox" name="skipResponseSetCookie" value="1" checked="checked"/>
<label></label>
</div>
<p class="comment">选中后当响应的Header中有Set-Cookie时不缓存响应内容。</p>
</td>
</tr>
<tr>
<td>支持请求no-cache刷新</td>
<td>
<div class="ui checkbox">
<input type="checkbox" name="enableRequestCachePragma" value="1"/>
<label></label>
</div>
<p class="comment">选中后当请求的Header中含有Pragma: no-cache或Cache-Control: no-cache时会跳过缓存直接读取源内容。</p>
</td>
</tr>
</table>
</div>`
})

View File

@@ -6,7 +6,7 @@ Vue.component("http-cache-config-box", {
cacheConfig = {
isPrior: false,
isOn: false,
cachePolicyId: 0
cacheRefs: []
}
}
return {
@@ -14,8 +14,71 @@ Vue.component("http-cache-config-box", {
}
},
methods: {
changePolicyId: function () {
this.cacheConfig.cachePolicyId = parseInt(this.cacheConfig.cachePolicyId)
isOn: function () {
return (!this.vIsLocation || this.cacheConfig.isPrior) && this.cacheConfig.isOn
},
addRef: function () {
window.UPDATING_CACHE_REF = null
let width = window.innerWidth
if (width > 1024) {
width = 1024
}
let height = window.innerHeight
if (height > 500) {
height = 500
}
let that = this
teaweb.popup("/servers/server/settings/cache/createPopup", {
width: width + "px",
height: height + "px",
callback: function (resp) {
that.cacheConfig.cacheRefs.push(resp.data.cacheRef)
}
})
},
updateRef: function (index, cacheRef) {
window.UPDATING_CACHE_REF = cacheRef
let width = window.innerWidth
if (width > 1024) {
width = 1024
}
let height = window.innerHeight
if (height > 500) {
height = 500
}
let that = this
teaweb.popup("/servers/server/settings/cache/createPopup", {
width: width + "px",
height: height + "px",
callback: function (resp) {
Vue.set(that.cacheConfig.cacheRefs, index, resp.data.cacheRef)
}
})
},
removeRef: function (index) {
let that = this
teaweb.confirm("确定要删除此缓存设置吗?", function () {
that.cacheConfig.cacheRefs.$remove(index)
})
},
timeUnitName: function (unit) {
switch (unit) {
case "ms":
return "毫秒"
case "second":
return "秒"
case "minute":
return "分钟"
case "hour":
return "小时"
case "day":
return "天"
case "week":
return "周 "
}
return unit
}
},
template: `<div>
@@ -33,21 +96,33 @@ Vue.component("http-cache-config-box", {
</td>
</tr>
</tbody>
<tbody v-show="(!vIsLocation || cacheConfig.isPrior) && cacheConfig.isOn">
<tr>
<td class="title">选择缓存策略</td>
<td>
<span class="disabled" v-if="vCachePolicies.length == 0">暂时没有可选的缓存策略</span>
<div v-if="vCachePolicies.length > 0">
<select class="ui dropdown auto-width" v-model="cacheConfig.cachePolicyId" @change="changePolicyId">
<option value="0">[不使用缓存策略]</option>
<option v-for="policy in vCachePolicies" :value="policy.id">{{policy.name}}</option>
</select>
</div>
</td>
</tr>
</tbody>
</table>
<div v-show="isOn()">
<table class="ui table selectable" v-show="cacheConfig.cacheRefs.length > 0">
<thead>
<tr>
<th>缓存策略</th>
<th>条件</th>
<th>缓存时间</th>
<th class="two op">操作</th>
</tr>
<tr v-for="(cacheRef, index) in cacheConfig.cacheRefs">
<td>{{cacheRef.cachePolicy.name}}</td>
<td>
<http-request-conds-view :v-conds="cacheRef.conds"></http-request-conds-view>
</td>
<td>{{cacheRef.life.count}} {{timeUnitName(cacheRef.life.unit)}}</td>
<td>
<a href="" @click.prevent="updateRef(index, cacheRef)">修改</a> &nbsp;
<a href="" @click.prevent="removeRef(index)">删除</a>
</td>
</tr>
</thead>
</table>
<button class="ui button tiny" @click.prevent="addRef">+添加缓存设置</button>
</div>
<div class="margin"></div>
</div>`
})

View File

@@ -0,0 +1,110 @@
Vue.component("http-cache-ref-box", {
props: ["v-cache-ref"],
data: function () {
let ref = this.vCacheRef
if (ref == null) {
ref = {
isOn: true,
cachePolicyId: 0,
key: "${scheme}://${host}${requestURI}",
life: {count: 2, unit: "hour"},
status: [200],
maxSize: {count: 32, unit: "mb"},
skipCacheControlValues: ["private", "no-cache", "no-store"],
skipSetCookie: true,
enableRequestCachePragma: false,
conds: null
}
}
if (ref.life == null) {
ref.life = {count: 2, unit: "hour"}
}
if (ref.maxSize == null) {
ref.maxSize = {count: 32, unit: "mb"}
}
return {
ref: ref,
moreOptionsVisible: false
}
},
methods: {
changeOptionsVisible: function (v) {
this.moreOptionsVisible = v
},
changeLife: function (v) {
this.ref.life = v
},
changeMaxSize: function (v) {
this.ref.maxSize = v
},
changeConds: function (v) {
this.ref.conds = v
}
},
template: `<tbody>
<tr>
<td>匹配条件 *</td>
<td>
<http-request-conds-box :v-conds="ref.conds" @change="changeConds"></http-request-conds-box>
<input type="hidden" name="cacheRefJSON" :value="JSON.stringify(ref)"/>
</td>
</tr>
<tr>
<td>缓存有效期 *</td>
<td>
<time-duration-box :v-value="ref.life" @change="changeLife"></time-duration-box>
</td>
</tr>
<tr>
<td>缓存Key *</td>
<td>
<input type="text" v-model="ref.key"/>
<p class="comment">用来区分不同缓存内容的唯一Key。</p>
</td>
</tr>
<tr>
<td colspan="2"><more-options-indicator @change="changeOptionsVisible"></more-options-indicator></td>
</tr>
<tr v-show="moreOptionsVisible">
<td>可缓存的最大文件</td>
<td>
<size-capacity-box :v-value="ref.maxSize" @change="changeMaxSize"></size-capacity-box>
</td>
</tr>
<tr v-show="moreOptionsVisible">
<td>状态码列表</td>
<td>
<values-box name="statusList" size="3" maxlength="3" :values="ref.status"></values-box>
<p class="comment">允许缓存的HTTP状态码列表。</p>
</td>
</tr>
<tr v-show="moreOptionsVisible">
<td>跳过的Cache-Control值</td>
<td>
<values-box name="skipResponseCacheControlValues" size="10" maxlength="100" :values="ref.skipCacheControlValues"></values-box>
<p class="comment">当响应的Cache-Control为这些值时不缓存响应内容而且不区分大小写。</p>
</td>
</tr>
<tr v-show="moreOptionsVisible">
<td>跳过Set-Cookie</td>
<td>
<div class="ui checkbox">
<input type="checkbox" value="1" v-model="ref.skipSetCookie"/>
<label></label>
</div>
<p class="comment">选中后当响应的Header中有Set-Cookie时不缓存响应内容。</p>
</td>
</tr>
<tr v-show="moreOptionsVisible">
<td>支持请求no-cache刷新</td>
<td>
<div class="ui checkbox">
<input type="checkbox" name="enableRequestCachePragma" value="1" v-model="ref.enableRequestCachePragma"/>
<label></label>
</div>
<p class="comment">选中后当请求的Header中含有Pragma: no-cache或Cache-Control: no-cache时会跳过缓存直接读取源内容。</p>
</td>
</tr>
</tbody>`
})

View File

@@ -15,12 +15,18 @@ Vue.component("http-request-conds-box", {
}
},
methods: {
change: function () {
this.$emit("change", this.conds)
},
addGroup: function () {
window.UPDATING_COND_GROUP = null
let that = this
teaweb.popup("/servers/server/settings/conds/addGroupPopup", {
height: "30em",
callback: function (resp) {
that.conds.groups.push(resp.data.group)
that.change()
}
})
},
@@ -31,6 +37,7 @@ Vue.component("http-request-conds-box", {
height: "30em",
callback: function (resp) {
Vue.set(that.conds.groups, groupIndex, resp.data.group)
that.change()
}
})
},
@@ -38,6 +45,7 @@ Vue.component("http-request-conds-box", {
let that = this
teaweb.confirm("确定要删除这一组条件吗?", function () {
that.conds.groups.$remove(groupIndex)
that.change()
})
},
typeName: function (cond) {

View File

@@ -0,0 +1,45 @@
Vue.component("http-request-conds-view", {
props: ["v-conds"],
data: function () {
let conds = this.vConds
if (conds == null) {
conds = {
isOn: true,
connector: "or",
groups: []
}
}
return {
conds: conds,
components: window.REQUEST_COND_COMPONENTS
}
},
methods: {
typeName: function (cond) {
let c = this.components.$find(function (k, v) {
return v.type == cond.type
})
if (c != null) {
return c.name;
}
return cond.param + " " + cond.operator
}
},
template: `<div>
<div v-if="conds.groups.length > 0">
<div v-for="(group, groupIndex) in conds.groups">
<var v-for="(cond, index) in group.conds" style="font-style: normal;display: inline-block; margin-bottom:0.5em">
<span class="ui label tiny">
<var v-if="cond.type.length == 0" style="font-style: normal">{{cond.param}} <var>{{cond.operator}}</var></var>
<var v-if="cond.type.length > 0" style="font-style: normal">{{typeName(cond)}}: </var>
{{cond.value}}
</span>
<var v-if="index < group.conds.length - 1"> {{group.connector}} &nbsp;</var>
</var>
<div class="ui divider" v-if="groupIndex != conds.groups.length - 1" style="margin-top:0.3em;margin-bottom:0.5em"></div>
</div>
</div>
</div>
</div>`
})