Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
二次元的罪恶王冠
beego
提交
2473e694
B
beego
项目概览
二次元的罪恶王冠
/
beego
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
B
beego
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
2473e694
编写于
9月 10, 2020
作者:
M
Ming Deng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Rewrite admin service by using multiple server feature
上级
d455805a
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
419 addition
and
376 deletion
+419
-376
pkg/adapter/admin.go
pkg/adapter/admin.go
+2
-5
pkg/server/web/admin.go
pkg/server/web/admin.go
+21
-361
pkg/server/web/admin_controller.go
pkg/server/web/admin_controller.go
+305
-0
pkg/server/web/admin_test.go
pkg/server/web/admin_test.go
+2
-2
pkg/server/web/hooks.go
pkg/server/web/hooks.go
+0
-8
pkg/server/web/server.go
pkg/server/web/server.go
+89
-0
未找到文件。
pkg/adapter/admin.go
浏览文件 @
2473e694
...
...
@@ -17,6 +17,7 @@ package adapter
import
(
"time"
_
"github.com/astaxie/beego/pkg/infrastructure/governor"
"github.com/astaxie/beego/pkg/server/web"
)
...
...
@@ -38,11 +39,7 @@ import (
// beego.FilterMonitorFunc = MyFilterMonitor.
var
FilterMonitorFunc
func
(
string
,
string
,
time
.
Duration
,
string
,
int
)
bool
func
init
()
{
FilterMonitorFunc
=
web
.
FilterMonitorFunc
}
// PrintTree prints all registered routers.
func
PrintTree
()
M
{
return
(
M
)(
web
.
PrintTree
())
return
(
M
)(
web
.
BeeApp
.
PrintTree
())
}
pkg/server/web/admin.go
浏览文件 @
2473e694
...
...
@@ -15,24 +15,12 @@
package
web
import
(
"bytes"
context2
"context"
"encoding/json"
"fmt"
"net/http"
"os"
"reflect"
"strconv"
"text/template"
"time"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/astaxie/beego/pkg/infrastructure/logs"
"github.com/astaxie/beego/pkg/infrastructure/governor"
"github.com/astaxie/beego/pkg/infrastructure/utils"
"github.com/astaxie/beego/pkg/server/web/grace"
"github.com/astaxie/beego/pkg/task"
)
...
...
@@ -58,127 +46,23 @@ var beeAdminApp *adminApp
var
FilterMonitorFunc
func
(
string
,
string
,
time
.
Duration
,
string
,
int
)
bool
func
init
()
{
c
:=
&
adminController
{
servers
:
make
([]
*
HttpServer
,
0
,
2
),
}
beeAdminApp
=
&
adminApp
{
routers
:
make
(
map
[
string
]
http
.
HandlerFunc
),
HttpServer
:
NewHttpServerWithCfg
(
*
BConfig
),
}
// keep in mind that all data should be html escaped to avoid XSS attack
beeAdminApp
.
Route
(
"/"
,
adminIndex
)
beeAdminApp
.
Route
(
"/qps"
,
qpsIndex
)
beeAdminApp
.
Route
(
"/prof"
,
profIndex
)
beeAdminApp
.
Route
(
"/healthcheck"
,
healthcheck
)
beeAdminApp
.
Route
(
"/task"
,
taskStatus
)
beeAdminApp
.
Route
(
"/listconf"
,
listConf
)
beeAdminApp
.
Route
(
"/metrics"
,
promhttp
.
Handler
()
.
ServeHTTP
)
beeAdminApp
.
Route
r
(
"/"
,
c
,
"get:AdminIndex"
)
beeAdminApp
.
Route
r
(
"/qps"
,
c
,
"get:QpsIndex"
)
beeAdminApp
.
Route
r
(
"/prof"
,
c
,
"get:ProfIndex"
)
beeAdminApp
.
Route
r
(
"/healthcheck"
,
c
,
"get:Healthcheck"
)
beeAdminApp
.
Route
r
(
"/task"
,
c
,
"get:TaskStatus"
)
beeAdminApp
.
Route
r
(
"/listconf"
,
c
,
"get:ListConf"
)
beeAdminApp
.
Route
r
(
"/metrics"
,
c
,
"get:PrometheusMetrics"
)
FilterMonitorFunc
=
func
(
string
,
string
,
time
.
Duration
,
string
,
int
)
bool
{
return
true
}
}
// AdminIndex is the default http.Handler for admin module.
// it matches url pattern "/".
func
adminIndex
(
rw
http
.
ResponseWriter
,
_
*
http
.
Request
)
{
writeTemplate
(
rw
,
map
[
interface
{}]
interface
{}{},
indexTpl
,
defaultScriptsTpl
)
}
// QpsIndex is the http.Handler for writing qps statistics map result info in http.ResponseWriter.
// it's registered with url pattern "/qps" in admin module.
func
qpsIndex
(
rw
http
.
ResponseWriter
,
_
*
http
.
Request
)
{
data
:=
make
(
map
[
interface
{}]
interface
{})
data
[
"Content"
]
=
StatisticsMap
.
GetMap
()
// do html escape before display path, avoid xss
if
content
,
ok
:=
(
data
[
"Content"
])
.
(
M
);
ok
{
if
resultLists
,
ok
:=
(
content
[
"Data"
])
.
([][]
string
);
ok
{
for
i
:=
range
resultLists
{
if
len
(
resultLists
[
i
])
>
0
{
resultLists
[
i
][
0
]
=
template
.
HTMLEscapeString
(
resultLists
[
i
][
0
])
}
}
}
}
writeTemplate
(
rw
,
data
,
qpsTpl
,
defaultScriptsTpl
)
}
// ListConf is the http.Handler of displaying all beego configuration values as key/value pair.
// it's registered with url pattern "/listconf" in admin module.
func
listConf
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
r
.
ParseForm
()
command
:=
r
.
Form
.
Get
(
"command"
)
if
command
==
""
{
rw
.
Write
([]
byte
(
"command not support"
))
return
}
data
:=
make
(
map
[
interface
{}]
interface
{})
switch
command
{
case
"conf"
:
m
:=
make
(
M
)
list
(
"BConfig"
,
BConfig
,
m
)
m
[
"AppConfigPath"
]
=
template
.
HTMLEscapeString
(
appConfigPath
)
m
[
"AppConfigProvider"
]
=
template
.
HTMLEscapeString
(
appConfigProvider
)
tmpl
:=
template
.
Must
(
template
.
New
(
"dashboard"
)
.
Parse
(
dashboardTpl
))
tmpl
=
template
.
Must
(
tmpl
.
Parse
(
configTpl
))
tmpl
=
template
.
Must
(
tmpl
.
Parse
(
defaultScriptsTpl
))
data
[
"Content"
]
=
m
tmpl
.
Execute
(
rw
,
data
)
case
"router"
:
content
:=
PrintTree
()
content
[
"Fields"
]
=
[]
string
{
"Router Pattern"
,
"Methods"
,
"Controller"
,
}
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Routers"
writeTemplate
(
rw
,
data
,
routerAndFilterTpl
,
defaultScriptsTpl
)
case
"filter"
:
var
(
content
=
M
{
"Fields"
:
[]
string
{
"Router Pattern"
,
"Filter Function"
,
},
}
filterTypes
=
[]
string
{}
filterTypeData
=
make
(
M
)
)
if
BeeApp
.
Handlers
.
enableFilter
{
var
filterType
string
for
k
,
fr
:=
range
map
[
int
]
string
{
BeforeStatic
:
"Before Static"
,
BeforeRouter
:
"Before Router"
,
BeforeExec
:
"Before Exec"
,
AfterExec
:
"After Exec"
,
FinishRouter
:
"Finish Router"
}
{
if
bf
:=
BeeApp
.
Handlers
.
filters
[
k
];
len
(
bf
)
>
0
{
filterType
=
fr
filterTypes
=
append
(
filterTypes
,
filterType
)
resultList
:=
new
([][]
string
)
for
_
,
f
:=
range
bf
{
var
result
=
[]
string
{
// void xss
template
.
HTMLEscapeString
(
f
.
pattern
),
template
.
HTMLEscapeString
(
utils
.
GetFuncName
(
f
.
filterFunc
)),
}
*
resultList
=
append
(
*
resultList
,
result
)
}
filterTypeData
[
filterType
]
=
resultList
}
}
}
content
[
"Data"
]
=
filterTypeData
content
[
"Methods"
]
=
filterTypes
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Filters"
writeTemplate
(
rw
,
data
,
routerAndFilterTpl
,
defaultScriptsTpl
)
default
:
rw
.
Write
([]
byte
(
"command not support"
))
}
beeAdminApp
.
Run
()
}
func
list
(
root
string
,
p
interface
{},
m
M
)
{
...
...
@@ -203,239 +87,19 @@ func list(root string, p interface{}, m M) {
}
}
// PrintTree prints all registered routers.
func
PrintTree
()
M
{
var
(
content
=
M
{}
methods
=
[]
string
{}
methodsData
=
make
(
M
)
)
for
method
,
t
:=
range
BeeApp
.
Handlers
.
routers
{
resultList
:=
new
([][]
string
)
printTree
(
resultList
,
t
)
methods
=
append
(
methods
,
template
.
HTMLEscapeString
(
method
))
methodsData
[
template
.
HTMLEscapeString
(
method
)]
=
resultList
}
content
[
"Data"
]
=
methodsData
content
[
"Methods"
]
=
methods
return
content
}
func
printTree
(
resultList
*
[][]
string
,
t
*
Tree
)
{
for
_
,
tr
:=
range
t
.
fixrouters
{
printTree
(
resultList
,
tr
)
}
if
t
.
wildcard
!=
nil
{
printTree
(
resultList
,
t
.
wildcard
)
}
for
_
,
l
:=
range
t
.
leaves
{
if
v
,
ok
:=
l
.
runObject
.
(
*
ControllerInfo
);
ok
{
if
v
.
routerType
==
routerTypeBeego
{
var
result
=
[]
string
{
template
.
HTMLEscapeString
(
v
.
pattern
),
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s"
,
v
.
methods
)),
template
.
HTMLEscapeString
(
v
.
controllerType
.
String
()),
}
*
resultList
=
append
(
*
resultList
,
result
)
}
else
if
v
.
routerType
==
routerTypeRESTFul
{
var
result
=
[]
string
{
template
.
HTMLEscapeString
(
v
.
pattern
),
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s"
,
v
.
methods
)),
""
,
}
*
resultList
=
append
(
*
resultList
,
result
)
}
else
if
v
.
routerType
==
routerTypeHandler
{
var
result
=
[]
string
{
template
.
HTMLEscapeString
(
v
.
pattern
),
""
,
""
,
}
*
resultList
=
append
(
*
resultList
,
result
)
}
}
}
}
// ProfIndex is a http.Handler for showing profile command.
// it's in url pattern "/prof" in admin module.
func
profIndex
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
r
.
ParseForm
()
command
:=
r
.
Form
.
Get
(
"command"
)
if
command
==
""
{
return
}
var
(
format
=
r
.
Form
.
Get
(
"format"
)
data
=
make
(
map
[
interface
{}]
interface
{})
result
bytes
.
Buffer
)
governor
.
ProcessInput
(
command
,
&
result
)
data
[
"Content"
]
=
template
.
HTMLEscapeString
(
result
.
String
())
if
format
==
"json"
&&
command
==
"gc summary"
{
dataJSON
,
err
:=
json
.
Marshal
(
data
)
if
err
!=
nil
{
http
.
Error
(
rw
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
}
writeJSON
(
rw
,
dataJSON
)
return
}
data
[
"Title"
]
=
template
.
HTMLEscapeString
(
command
)
defaultTpl
:=
defaultScriptsTpl
if
command
==
"gc summary"
{
defaultTpl
=
gcAjaxTpl
}
writeTemplate
(
rw
,
data
,
profillingTpl
,
defaultTpl
)
}
// Healthcheck is a http.Handler calling health checking and showing the result.
// it's in "/healthcheck" pattern in admin module.
func
healthcheck
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
var
(
result
[]
string
data
=
make
(
map
[
interface
{}]
interface
{})
resultList
=
new
([][]
string
)
content
=
M
{
"Fields"
:
[]
string
{
"Name"
,
"Message"
,
"Status"
},
}
)
for
name
,
h
:=
range
governor
.
AdminCheckList
{
if
err
:=
h
.
Check
();
err
!=
nil
{
result
=
[]
string
{
"error"
,
template
.
HTMLEscapeString
(
name
),
template
.
HTMLEscapeString
(
err
.
Error
()),
}
}
else
{
result
=
[]
string
{
"success"
,
template
.
HTMLEscapeString
(
name
),
"OK"
,
}
}
*
resultList
=
append
(
*
resultList
,
result
)
}
queryParams
:=
r
.
URL
.
Query
()
jsonFlag
:=
queryParams
.
Get
(
"json"
)
shouldReturnJSON
,
_
:=
strconv
.
ParseBool
(
jsonFlag
)
if
shouldReturnJSON
{
response
:=
buildHealthCheckResponseList
(
resultList
)
jsonResponse
,
err
:=
json
.
Marshal
(
response
)
if
err
!=
nil
{
http
.
Error
(
rw
,
err
.
Error
(),
http
.
StatusInternalServerError
)
}
else
{
writeJSON
(
rw
,
jsonResponse
)
}
return
}
content
[
"Data"
]
=
resultList
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Health Check"
writeTemplate
(
rw
,
data
,
healthCheckTpl
,
defaultScriptsTpl
)
}
func
buildHealthCheckResponseList
(
healthCheckResults
*
[][]
string
)
[]
map
[
string
]
interface
{}
{
response
:=
make
([]
map
[
string
]
interface
{},
len
(
*
healthCheckResults
))
for
i
,
healthCheckResult
:=
range
*
healthCheckResults
{
currentResultMap
:=
make
(
map
[
string
]
interface
{})
currentResultMap
[
"name"
]
=
healthCheckResult
[
0
]
currentResultMap
[
"message"
]
=
healthCheckResult
[
1
]
currentResultMap
[
"status"
]
=
healthCheckResult
[
2
]
response
[
i
]
=
currentResultMap
}
return
response
}
func
writeJSON
(
rw
http
.
ResponseWriter
,
jsonData
[]
byte
)
{
rw
.
Header
()
.
Set
(
"Content-Type"
,
"application/json"
)
rw
.
Write
(
jsonData
)
}
// TaskStatus is a http.Handler with running task status (task name, status and the last execution).
// it's in "/task" pattern in admin module.
func
taskStatus
(
rw
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
data
:=
make
(
map
[
interface
{}]
interface
{})
// Run Task
req
.
ParseForm
()
taskname
:=
req
.
Form
.
Get
(
"taskname"
)
if
taskname
!=
""
{
if
t
,
ok
:=
task
.
AdminTaskList
[
taskname
];
ok
{
if
err
:=
t
.
Run
(
nil
);
err
!=
nil
{
data
[
"Message"
]
=
[]
string
{
"error"
,
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s"
,
err
))}
}
data
[
"Message"
]
=
[]
string
{
"success"
,
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s run success,Now the Status is <br>%s"
,
taskname
,
t
.
GetStatus
(
nil
)))}
}
else
{
data
[
"Message"
]
=
[]
string
{
"warning"
,
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"there's no task which named: %s"
,
taskname
))}
}
}
// List Tasks
content
:=
make
(
M
)
resultList
:=
new
([][]
string
)
var
fields
=
[]
string
{
"Task Name"
,
"Task Spec"
,
"Task Status"
,
"Last Time"
,
""
,
}
for
tname
,
tk
:=
range
task
.
AdminTaskList
{
result
:=
[]
string
{
template
.
HTMLEscapeString
(
tname
),
template
.
HTMLEscapeString
(
tk
.
GetSpec
(
nil
)),
template
.
HTMLEscapeString
(
tk
.
GetStatus
(
nil
)),
template
.
HTMLEscapeString
(
tk
.
GetPrev
(
context2
.
Background
())
.
String
()),
}
*
resultList
=
append
(
*
resultList
,
result
)
}
content
[
"Fields"
]
=
fields
content
[
"Data"
]
=
resultList
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Tasks"
writeTemplate
(
rw
,
data
,
tasksTpl
,
defaultScriptsTpl
)
}
func
writeTemplate
(
rw
http
.
ResponseWriter
,
data
map
[
interface
{}]
interface
{},
tpls
...
string
)
{
tmpl
:=
template
.
Must
(
template
.
New
(
"dashboard"
)
.
Parse
(
dashboardTpl
))
for
_
,
tpl
:=
range
tpls
{
tmpl
=
template
.
Must
(
tmpl
.
Parse
(
tpl
))
}
tmpl
.
Execute
(
rw
,
data
)
}
// adminApp is an http.HandlerFunc map used as beeAdminApp.
type
adminApp
struct
{
routers
map
[
string
]
http
.
HandlerFunc
*
HttpServer
}
// Route adds http.HandlerFunc to adminApp with url pattern.
func
(
admin
*
adminApp
)
Route
(
pattern
string
,
f
http
.
HandlerFunc
)
{
admin
.
routers
[
pattern
]
=
f
}
// Run adminApp http server.
// Its addr is defined in configuration file as adminhttpaddr and adminhttpport.
func
(
admin
*
adminApp
)
Run
()
{
if
len
(
task
.
AdminTaskList
)
>
0
{
task
.
StartTask
()
}
...
...
@@ -444,18 +108,14 @@ func (admin *adminApp) Run() {
if
BConfig
.
Listen
.
AdminPort
!=
0
{
addr
=
fmt
.
Sprintf
(
"%s:%d"
,
BConfig
.
Listen
.
AdminAddr
,
BConfig
.
Listen
.
AdminPort
)
}
for
p
,
f
:=
range
admin
.
routers
{
http
.
Handle
(
p
,
f
)
}
logs
.
Info
(
"Admin server Running on %s"
,
addr
)
admin
.
HttpServer
.
Run
(
addr
)
}
var
err
error
if
BConfig
.
Listen
.
Graceful
{
err
=
grace
.
ListenAndServe
(
addr
,
nil
)
}
else
{
err
=
http
.
ListenAndServe
(
addr
,
nil
)
}
if
err
!=
nil
{
logs
.
Critical
(
"Admin ListenAndServe: "
,
err
,
fmt
.
Sprintf
(
"%d"
,
os
.
Getpid
()))
func
registerAdmin
()
error
{
if
BConfig
.
Listen
.
EnableAdmin
{
go
beeAdminApp
.
Run
()
}
return
nil
}
pkg/server/web/admin_controller.go
0 → 100644
浏览文件 @
2473e694
// Copyright 2020
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
web
import
(
"bytes"
context2
"context"
"encoding/json"
"fmt"
"net/http"
"strconv"
"text/template"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/astaxie/beego/pkg/infrastructure/governor"
"github.com/astaxie/beego/pkg/task"
)
type
adminController
struct
{
Controller
servers
[]
*
HttpServer
}
func
(
a
*
adminController
)
registerHttpServer
(
svr
*
HttpServer
)
{
a
.
servers
=
append
(
a
.
servers
,
svr
)
}
// ProfIndex is a http.Handler for showing profile command.
// it's in url pattern "/prof" in admin module.
func
(
a
*
adminController
)
ProfIndex
()
{
rw
,
r
:=
a
.
Ctx
.
ResponseWriter
,
a
.
Ctx
.
Request
r
.
ParseForm
()
command
:=
r
.
Form
.
Get
(
"command"
)
if
command
==
""
{
return
}
var
(
format
=
r
.
Form
.
Get
(
"format"
)
data
=
make
(
map
[
interface
{}]
interface
{})
result
bytes
.
Buffer
)
governor
.
ProcessInput
(
command
,
&
result
)
data
[
"Content"
]
=
template
.
HTMLEscapeString
(
result
.
String
())
if
format
==
"json"
&&
command
==
"gc summary"
{
dataJSON
,
err
:=
json
.
Marshal
(
data
)
if
err
!=
nil
{
http
.
Error
(
rw
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
}
writeJSON
(
rw
,
dataJSON
)
return
}
data
[
"Title"
]
=
template
.
HTMLEscapeString
(
command
)
defaultTpl
:=
defaultScriptsTpl
if
command
==
"gc summary"
{
defaultTpl
=
gcAjaxTpl
}
writeTemplate
(
rw
,
data
,
profillingTpl
,
defaultTpl
)
}
func
(
a
*
adminController
)
PrometheusMetrics
()
{
promhttp
.
Handler
()
.
ServeHTTP
(
a
.
Ctx
.
ResponseWriter
,
a
.
Ctx
.
Request
)
}
// TaskStatus is a http.Handler with running task status (task name, status and the last execution).
// it's in "/task" pattern in admin module.
func
(
a
*
adminController
)
TaskStatus
()
{
rw
,
req
:=
a
.
Ctx
.
ResponseWriter
,
a
.
Ctx
.
Request
data
:=
make
(
map
[
interface
{}]
interface
{})
// Run Task
req
.
ParseForm
()
taskname
:=
req
.
Form
.
Get
(
"taskname"
)
if
taskname
!=
""
{
if
t
,
ok
:=
task
.
AdminTaskList
[
taskname
];
ok
{
if
err
:=
t
.
Run
(
nil
);
err
!=
nil
{
data
[
"Message"
]
=
[]
string
{
"error"
,
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s"
,
err
))}
}
data
[
"Message"
]
=
[]
string
{
"success"
,
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s run success,Now the Status is <br>%s"
,
taskname
,
t
.
GetStatus
(
nil
)))}
}
else
{
data
[
"Message"
]
=
[]
string
{
"warning"
,
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"there's no task which named: %s"
,
taskname
))}
}
}
// List Tasks
content
:=
make
(
M
)
resultList
:=
new
([][]
string
)
var
fields
=
[]
string
{
"Task Name"
,
"Task Spec"
,
"Task Status"
,
"Last Time"
,
""
,
}
for
tname
,
tk
:=
range
task
.
AdminTaskList
{
result
:=
[]
string
{
template
.
HTMLEscapeString
(
tname
),
template
.
HTMLEscapeString
(
tk
.
GetSpec
(
nil
)),
template
.
HTMLEscapeString
(
tk
.
GetStatus
(
nil
)),
template
.
HTMLEscapeString
(
tk
.
GetPrev
(
context2
.
Background
())
.
String
()),
}
*
resultList
=
append
(
*
resultList
,
result
)
}
content
[
"Fields"
]
=
fields
content
[
"Data"
]
=
resultList
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Tasks"
writeTemplate
(
rw
,
data
,
tasksTpl
,
defaultScriptsTpl
)
}
func
(
a
*
adminController
)
AdminIndex
()
{
// AdminIndex is the default http.Handler for admin module.
// it matches url pattern "/".
writeTemplate
(
a
.
Ctx
.
ResponseWriter
,
map
[
interface
{}]
interface
{}{},
indexTpl
,
defaultScriptsTpl
)
}
// Healthcheck is a http.Handler calling health checking and showing the result.
// it's in "/healthcheck" pattern in admin module.
func
(
a
*
adminController
)
Healthcheck
()
{
heathCheck
(
a
.
Ctx
.
ResponseWriter
,
a
.
Ctx
.
Request
)
}
func
heathCheck
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
var
(
result
[]
string
data
=
make
(
map
[
interface
{}]
interface
{})
resultList
=
new
([][]
string
)
content
=
M
{
"Fields"
:
[]
string
{
"Name"
,
"Message"
,
"Status"
},
}
)
for
name
,
h
:=
range
governor
.
AdminCheckList
{
if
err
:=
h
.
Check
();
err
!=
nil
{
result
=
[]
string
{
"error"
,
template
.
HTMLEscapeString
(
name
),
template
.
HTMLEscapeString
(
err
.
Error
()),
}
}
else
{
result
=
[]
string
{
"success"
,
template
.
HTMLEscapeString
(
name
),
"OK"
,
}
}
*
resultList
=
append
(
*
resultList
,
result
)
}
queryParams
:=
r
.
URL
.
Query
()
jsonFlag
:=
queryParams
.
Get
(
"json"
)
shouldReturnJSON
,
_
:=
strconv
.
ParseBool
(
jsonFlag
)
if
shouldReturnJSON
{
response
:=
buildHealthCheckResponseList
(
resultList
)
jsonResponse
,
err
:=
json
.
Marshal
(
response
)
if
err
!=
nil
{
http
.
Error
(
rw
,
err
.
Error
(),
http
.
StatusInternalServerError
)
}
else
{
writeJSON
(
rw
,
jsonResponse
)
}
return
}
content
[
"Data"
]
=
resultList
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Health Check"
writeTemplate
(
rw
,
data
,
healthCheckTpl
,
defaultScriptsTpl
)
}
// QpsIndex is the http.Handler for writing qps statistics map result info in http.ResponseWriter.
// it's registered with url pattern "/qps" in admin module.
func
(
a
*
adminController
)
QpsIndex
()
{
data
:=
make
(
map
[
interface
{}]
interface
{})
data
[
"Content"
]
=
StatisticsMap
.
GetMap
()
// do html escape before display path, avoid xss
if
content
,
ok
:=
(
data
[
"Content"
])
.
(
M
);
ok
{
if
resultLists
,
ok
:=
(
content
[
"Data"
])
.
([][]
string
);
ok
{
for
i
:=
range
resultLists
{
if
len
(
resultLists
[
i
])
>
0
{
resultLists
[
i
][
0
]
=
template
.
HTMLEscapeString
(
resultLists
[
i
][
0
])
}
}
}
}
writeTemplate
(
a
.
Ctx
.
ResponseWriter
,
data
,
qpsTpl
,
defaultScriptsTpl
)
}
// ListConf is the http.Handler of displaying all beego configuration values as key/value pair.
// it's registered with url pattern "/listconf" in admin module.
func
(
a
*
adminController
)
ListConf
()
{
rw
:=
a
.
Ctx
.
ResponseWriter
r
:=
a
.
Ctx
.
Request
r
.
ParseForm
()
command
:=
r
.
Form
.
Get
(
"command"
)
if
command
==
""
{
rw
.
Write
([]
byte
(
"command not support"
))
return
}
data
:=
make
(
map
[
interface
{}]
interface
{})
switch
command
{
case
"conf"
:
m
:=
make
(
M
)
list
(
"BConfig"
,
BConfig
,
m
)
m
[
"appConfigPath"
]
=
template
.
HTMLEscapeString
(
appConfigPath
)
m
[
"appConfigProvider"
]
=
template
.
HTMLEscapeString
(
appConfigProvider
)
tmpl
:=
template
.
Must
(
template
.
New
(
"dashboard"
)
.
Parse
(
dashboardTpl
))
tmpl
=
template
.
Must
(
tmpl
.
Parse
(
configTpl
))
tmpl
=
template
.
Must
(
tmpl
.
Parse
(
defaultScriptsTpl
))
data
[
"Content"
]
=
m
tmpl
.
Execute
(
rw
,
data
)
case
"router"
:
content
:=
BeeApp
.
PrintTree
()
content
[
"Fields"
]
=
[]
string
{
"Router Pattern"
,
"Methods"
,
"Controller"
,
}
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Routers"
writeTemplate
(
rw
,
data
,
routerAndFilterTpl
,
defaultScriptsTpl
)
case
"filter"
:
var
(
content
=
M
{
"Fields"
:
[]
string
{
"Router Pattern"
,
"Filter Function"
,
},
}
)
filterTypeData
:=
BeeApp
.
reportFilter
()
filterTypes
:=
make
([]
string
,
0
,
len
(
filterTypeData
))
for
k
,
_
:=
range
filterTypeData
{
filterTypes
=
append
(
filterTypes
,
k
)
}
content
[
"Data"
]
=
filterTypeData
content
[
"Methods"
]
=
filterTypes
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Filters"
writeTemplate
(
rw
,
data
,
routerAndFilterTpl
,
defaultScriptsTpl
)
default
:
rw
.
Write
([]
byte
(
"command not support"
))
}
}
func
writeTemplate
(
rw
http
.
ResponseWriter
,
data
map
[
interface
{}]
interface
{},
tpls
...
string
)
{
tmpl
:=
template
.
Must
(
template
.
New
(
"dashboard"
)
.
Parse
(
dashboardTpl
))
for
_
,
tpl
:=
range
tpls
{
tmpl
=
template
.
Must
(
tmpl
.
Parse
(
tpl
))
}
tmpl
.
Execute
(
rw
,
data
)
}
func
buildHealthCheckResponseList
(
healthCheckResults
*
[][]
string
)
[]
map
[
string
]
interface
{}
{
response
:=
make
([]
map
[
string
]
interface
{},
len
(
*
healthCheckResults
))
for
i
,
healthCheckResult
:=
range
*
healthCheckResults
{
currentResultMap
:=
make
(
map
[
string
]
interface
{})
currentResultMap
[
"name"
]
=
healthCheckResult
[
0
]
currentResultMap
[
"message"
]
=
healthCheckResult
[
1
]
currentResultMap
[
"status"
]
=
healthCheckResult
[
2
]
response
[
i
]
=
currentResultMap
}
return
response
}
// PrintTree print all routers
// Deprecated using BeeApp directly
func
PrintTree
()
M
{
return
BeeApp
.
PrintTree
()
}
pkg/server/web/admin_test.go
浏览文件 @
2473e694
...
...
@@ -136,7 +136,7 @@ func TestHealthCheckHandlerDefault(t *testing.T) {
w
:=
httptest
.
NewRecorder
()
handler
:=
http
.
HandlerFunc
(
hea
lthc
heck
)
handler
:=
http
.
HandlerFunc
(
hea
thC
heck
)
handler
.
ServeHTTP
(
w
,
req
)
...
...
@@ -197,7 +197,7 @@ func TestHealthCheckHandlerReturnsJSON(t *testing.T) {
w
:=
httptest
.
NewRecorder
()
handler
:=
http
.
HandlerFunc
(
hea
lthc
heck
)
handler
:=
http
.
HandlerFunc
(
hea
thC
heck
)
handler
.
ServeHTTP
(
w
,
req
)
if
status
:=
w
.
Code
;
status
!=
http
.
StatusOK
{
...
...
pkg/server/web/hooks.go
浏览文件 @
2473e694
...
...
@@ -9,7 +9,6 @@ import (
"github.com/astaxie/beego/pkg/infrastructure/logs"
"github.com/astaxie/beego/pkg/infrastructure/session"
"github.com/astaxie/beego/pkg/server/web/context"
)
...
...
@@ -87,13 +86,6 @@ func registerTemplate() error {
return
nil
}
func
registerAdmin
()
error
{
if
BConfig
.
Listen
.
EnableAdmin
{
go
beeAdminApp
.
Run
()
}
return
nil
}
func
registerGzip
()
error
{
if
BConfig
.
EnableGzip
{
context
.
InitGzip
(
...
...
pkg/server/web/server.go
浏览文件 @
2473e694
...
...
@@ -26,6 +26,7 @@ import (
"path"
"strconv"
"strings"
"text/template"
"time"
"golang.org/x/crypto/acme/autocert"
...
...
@@ -72,6 +73,7 @@ func NewHttpServerWithCfg(cfg Config) *HttpServer {
Server
:
&
http
.
Server
{},
Cfg
:
cfgPtr
,
}
return
app
}
...
...
@@ -665,3 +667,90 @@ func (app *HttpServer) LogAccess(ctx *beecontext.Context, startTime *time.Time,
}
logs
.
AccessLog
(
record
,
app
.
Cfg
.
Log
.
AccessLogsFormat
)
}
// PrintTree prints all registered routers.
func
(
app
*
HttpServer
)
PrintTree
()
M
{
var
(
content
=
M
{}
methods
=
[]
string
{}
methodsData
=
make
(
M
)
)
for
method
,
t
:=
range
app
.
Handlers
.
routers
{
resultList
:=
new
([][]
string
)
printTree
(
resultList
,
t
)
methods
=
append
(
methods
,
template
.
HTMLEscapeString
(
method
))
methodsData
[
template
.
HTMLEscapeString
(
method
)]
=
resultList
}
content
[
"Data"
]
=
methodsData
content
[
"Methods"
]
=
methods
return
content
}
func
printTree
(
resultList
*
[][]
string
,
t
*
Tree
)
{
for
_
,
tr
:=
range
t
.
fixrouters
{
printTree
(
resultList
,
tr
)
}
if
t
.
wildcard
!=
nil
{
printTree
(
resultList
,
t
.
wildcard
)
}
for
_
,
l
:=
range
t
.
leaves
{
if
v
,
ok
:=
l
.
runObject
.
(
*
ControllerInfo
);
ok
{
if
v
.
routerType
==
routerTypeBeego
{
var
result
=
[]
string
{
template
.
HTMLEscapeString
(
v
.
pattern
),
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s"
,
v
.
methods
)),
template
.
HTMLEscapeString
(
v
.
controllerType
.
String
()),
}
*
resultList
=
append
(
*
resultList
,
result
)
}
else
if
v
.
routerType
==
routerTypeRESTFul
{
var
result
=
[]
string
{
template
.
HTMLEscapeString
(
v
.
pattern
),
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s"
,
v
.
methods
)),
""
,
}
*
resultList
=
append
(
*
resultList
,
result
)
}
else
if
v
.
routerType
==
routerTypeHandler
{
var
result
=
[]
string
{
template
.
HTMLEscapeString
(
v
.
pattern
),
""
,
""
,
}
*
resultList
=
append
(
*
resultList
,
result
)
}
}
}
}
func
(
app
*
HttpServer
)
reportFilter
()
M
{
filterTypeData
:=
make
(
M
)
// filterTypes := []string{}
if
app
.
Handlers
.
enableFilter
{
// var filterType string
for
k
,
fr
:=
range
map
[
int
]
string
{
BeforeStatic
:
"Before Static"
,
BeforeRouter
:
"Before Router"
,
BeforeExec
:
"Before Exec"
,
AfterExec
:
"After Exec"
,
FinishRouter
:
"Finish Router"
,
}
{
if
bf
:=
app
.
Handlers
.
filters
[
k
];
len
(
bf
)
>
0
{
resultList
:=
new
([][]
string
)
for
_
,
f
:=
range
bf
{
var
result
=
[]
string
{
// void xss
template
.
HTMLEscapeString
(
f
.
pattern
),
template
.
HTMLEscapeString
(
utils
.
GetFuncName
(
f
.
filterFunc
)),
}
*
resultList
=
append
(
*
resultList
,
result
)
}
filterTypeData
[
fr
]
=
resultList
}
}
}
return
filterTypeData
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录