Merge branch 'develop' of https://github.com/astaxie/beego into fix-issue-4176
This commit is contained in:
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
|
||||
"github.com/astaxie/beego/core/governor"
|
||||
"github.com/astaxie/beego/core/admin"
|
||||
)
|
||||
|
||||
type adminController struct {
|
||||
@@ -51,7 +51,7 @@ func (a *adminController) ProfIndex() {
|
||||
data = make(map[interface{}]interface{})
|
||||
result bytes.Buffer
|
||||
)
|
||||
governor.ProcessInput(command, &result)
|
||||
admin.ProcessInput(command, &result)
|
||||
data["Content"] = template.HTMLEscapeString(result.String())
|
||||
|
||||
if format == "json" && command == "gc summary" {
|
||||
@@ -88,7 +88,7 @@ func (a *adminController) TaskStatus() {
|
||||
req.ParseForm()
|
||||
taskname := req.Form.Get("taskname")
|
||||
if taskname != "" {
|
||||
cmd := governor.GetCommand("task", "run")
|
||||
cmd := admin.GetCommand("task", "run")
|
||||
res := cmd.Execute(taskname)
|
||||
if res.IsSuccess() {
|
||||
|
||||
@@ -103,7 +103,7 @@ func (a *adminController) TaskStatus() {
|
||||
|
||||
// List Tasks
|
||||
content := make(M)
|
||||
resultList := governor.GetCommand("task", "list").Execute().Content.([][]string)
|
||||
resultList := admin.GetCommand("task", "list").Execute().Content.([][]string)
|
||||
var fields = []string{
|
||||
"Task Name",
|
||||
"Task Spec",
|
||||
@@ -141,7 +141,7 @@ func heathCheck(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
)
|
||||
|
||||
for name, h := range governor.AdminCheckList {
|
||||
for name, h := range admin.AdminCheckList {
|
||||
if err := h.Check(); err != nil {
|
||||
result = []string{
|
||||
"error",
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/astaxie/beego/core/governor"
|
||||
"github.com/astaxie/beego/core/admin"
|
||||
)
|
||||
|
||||
type SampleDatabaseCheck struct {
|
||||
@@ -126,8 +126,8 @@ func TestWriteJSON(t *testing.T) {
|
||||
func TestHealthCheckHandlerDefault(t *testing.T) {
|
||||
endpointPath := "/healthcheck"
|
||||
|
||||
governor.AddHealthCheck("database", &SampleDatabaseCheck{})
|
||||
governor.AddHealthCheck("cache", &SampleCacheCheck{})
|
||||
admin.AddHealthCheck("database", &SampleDatabaseCheck{})
|
||||
admin.AddHealthCheck("cache", &SampleCacheCheck{})
|
||||
|
||||
req, err := http.NewRequest("GET", endpointPath, nil)
|
||||
if err != nil {
|
||||
@@ -187,8 +187,8 @@ func TestBuildHealthCheckResponseList(t *testing.T) {
|
||||
|
||||
func TestHealthCheckHandlerReturnsJSON(t *testing.T) {
|
||||
|
||||
governor.AddHealthCheck("database", &SampleDatabaseCheck{})
|
||||
governor.AddHealthCheck("cache", &SampleCacheCheck{})
|
||||
admin.AddHealthCheck("database", &SampleDatabaseCheck{})
|
||||
admin.AddHealthCheck("cache", &SampleCacheCheck{})
|
||||
|
||||
req, err := http.NewRequest("GET", "/healthcheck?json=true", nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -21,7 +21,7 @@ var indexTpl = `
|
||||
For detail usage please check our document:
|
||||
</p>
|
||||
<p>
|
||||
<a target="_blank" href="http://beego.me/docs/module/governor.md">Toolbox</a>
|
||||
<a target="_blank" href="http://beego.me/docs/module/admin.md">Toolbox</a>
|
||||
</p>
|
||||
<p>
|
||||
<a target="_blank" href="http://beego.me/docs/advantage/monitor.md">Live Monitor</a>
|
||||
|
||||
@@ -149,7 +149,8 @@ func (ctx *Context) XSRFToken(key string, expire int64) string {
|
||||
token, ok := ctx.GetSecureCookie(key, "_xsrf")
|
||||
if !ok {
|
||||
token = string(utils.RandomCreateBytes(32))
|
||||
ctx.SetSecureCookie(key, "_xsrf", token, expire, "", "", true, true)
|
||||
// TODO make it configurable
|
||||
ctx.SetSecureCookie(key, "_xsrf", token, expire, "", "")
|
||||
}
|
||||
ctx._xsrfToken = token
|
||||
}
|
||||
|
||||
@@ -261,15 +261,15 @@ func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error {
|
||||
}
|
||||
|
||||
// ServeFormatted serves YAML, XML or JSON, depending on the value of the Accept header
|
||||
func (output *BeegoOutput) ServeFormatted(data interface{}, hasIndent bool, hasEncode ...bool) {
|
||||
func (output *BeegoOutput) ServeFormatted(data interface{}, hasIndent bool, hasEncode ...bool) error {
|
||||
accept := output.Context.Input.Header("Accept")
|
||||
switch accept {
|
||||
case ApplicationYAML:
|
||||
output.YAML(data)
|
||||
return output.YAML(data)
|
||||
case ApplicationXML, TextXML:
|
||||
output.XML(data, hasIndent)
|
||||
return output.XML(data, hasIndent)
|
||||
default:
|
||||
output.JSON(data, hasIndent, len(hasEncode) > 0 && hasEncode[0])
|
||||
return output.JSON(data, hasIndent, len(hasEncode) > 0 && hasEncode[0])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ package web
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
context2 "context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
@@ -250,13 +251,16 @@ func (c *Controller) Render() error {
|
||||
// RenderString returns the rendered template string. Do not send out response.
|
||||
func (c *Controller) RenderString() (string, error) {
|
||||
b, e := c.RenderBytes()
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
return string(b), e
|
||||
}
|
||||
|
||||
// RenderBytes returns the bytes of rendered template string. Do not send out response.
|
||||
func (c *Controller) RenderBytes() ([]byte, error) {
|
||||
buf, err := c.renderTemplate()
|
||||
//if the controller has set layout, then first get the tplName's content set the content to the layout
|
||||
// if the controller has set layout, then first get the tplName's content set the content to the layout
|
||||
if err == nil && c.Layout != "" {
|
||||
c.Data["LayoutContent"] = template.HTML(buf.String())
|
||||
|
||||
@@ -276,7 +280,7 @@ func (c *Controller) RenderBytes() ([]byte, error) {
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
ExecuteViewPathTemplate(&buf, c.Layout, c.viewPath(), c.Data)
|
||||
err = ExecuteViewPathTemplate(&buf, c.Layout, c.viewPath(), c.Data)
|
||||
}
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
@@ -373,50 +377,57 @@ func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
|
||||
}
|
||||
|
||||
// ServeJSON sends a json response with encoding charset.
|
||||
func (c *Controller) ServeJSON(encoding ...bool) {
|
||||
func (c *Controller) ServeJSON(encoding ...bool) error {
|
||||
var (
|
||||
hasIndent = BConfig.RunMode != PROD
|
||||
hasEncoding = len(encoding) > 0 && encoding[0]
|
||||
)
|
||||
|
||||
c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasEncoding)
|
||||
return c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasEncoding)
|
||||
}
|
||||
|
||||
// ServeJSONP sends a jsonp response.
|
||||
func (c *Controller) ServeJSONP() {
|
||||
func (c *Controller) ServeJSONP() error {
|
||||
hasIndent := BConfig.RunMode != PROD
|
||||
c.Ctx.Output.JSONP(c.Data["jsonp"], hasIndent)
|
||||
return c.Ctx.Output.JSONP(c.Data["jsonp"], hasIndent)
|
||||
}
|
||||
|
||||
// ServeXML sends xml response.
|
||||
func (c *Controller) ServeXML() {
|
||||
func (c *Controller) ServeXML() error {
|
||||
hasIndent := BConfig.RunMode != PROD
|
||||
c.Ctx.Output.XML(c.Data["xml"], hasIndent)
|
||||
return c.Ctx.Output.XML(c.Data["xml"], hasIndent)
|
||||
}
|
||||
|
||||
// ServeYAML sends yaml response.
|
||||
func (c *Controller) ServeYAML() {
|
||||
c.Ctx.Output.YAML(c.Data["yaml"])
|
||||
func (c *Controller) ServeYAML() error {
|
||||
return c.Ctx.Output.YAML(c.Data["yaml"])
|
||||
}
|
||||
|
||||
// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
|
||||
func (c *Controller) ServeFormatted(encoding ...bool) {
|
||||
func (c *Controller) ServeFormatted(encoding ...bool) error {
|
||||
hasIndent := BConfig.RunMode != PROD
|
||||
hasEncoding := len(encoding) > 0 && encoding[0]
|
||||
c.Ctx.Output.ServeFormatted(c.Data, hasIndent, hasEncoding)
|
||||
return c.Ctx.Output.ServeFormatted(c.Data, hasIndent, hasEncoding)
|
||||
}
|
||||
|
||||
// Input returns the input data map from POST or PUT request body and query string.
|
||||
func (c *Controller) Input() url.Values {
|
||||
func (c *Controller) Input() (url.Values, error) {
|
||||
if c.Ctx.Request.Form == nil {
|
||||
c.Ctx.Request.ParseForm()
|
||||
err := c.Ctx.Request.ParseForm()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return c.Ctx.Request.Form
|
||||
return c.Ctx.Request.Form, nil
|
||||
}
|
||||
|
||||
// ParseForm maps input data map to obj struct.
|
||||
func (c *Controller) ParseForm(obj interface{}) error {
|
||||
return ParseForm(c.Input(), obj)
|
||||
form, err := c.Input()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ParseForm(form, obj)
|
||||
}
|
||||
|
||||
// GetString returns the input value by key string or the default value while it's present and input is blank
|
||||
@@ -438,7 +449,7 @@ func (c *Controller) GetStrings(key string, def ...[]string) []string {
|
||||
defv = def[0]
|
||||
}
|
||||
|
||||
if f := c.Input(); f == nil {
|
||||
if f, err := c.Input(); f == nil || err != nil {
|
||||
return defv
|
||||
} else if vs := f[key]; len(vs) > 0 {
|
||||
return vs
|
||||
@@ -618,11 +629,11 @@ func (c *Controller) StartSession() session.Store {
|
||||
}
|
||||
|
||||
// SetSession puts value into session.
|
||||
func (c *Controller) SetSession(name interface{}, value interface{}) {
|
||||
func (c *Controller) SetSession(name interface{}, value interface{}) error {
|
||||
if c.CruSession == nil {
|
||||
c.StartSession()
|
||||
}
|
||||
c.CruSession.Set(nil, name, value)
|
||||
return c.CruSession.Set(context2.Background(), name, value)
|
||||
}
|
||||
|
||||
// GetSession gets value from session.
|
||||
@@ -630,32 +641,38 @@ func (c *Controller) GetSession(name interface{}) interface{} {
|
||||
if c.CruSession == nil {
|
||||
c.StartSession()
|
||||
}
|
||||
return c.CruSession.Get(nil, name)
|
||||
return c.CruSession.Get(context2.Background(), name)
|
||||
}
|
||||
|
||||
// DelSession removes value from session.
|
||||
func (c *Controller) DelSession(name interface{}) {
|
||||
func (c *Controller) DelSession(name interface{}) error {
|
||||
if c.CruSession == nil {
|
||||
c.StartSession()
|
||||
}
|
||||
c.CruSession.Delete(nil, name)
|
||||
return c.CruSession.Delete(context2.Background(), name)
|
||||
}
|
||||
|
||||
// SessionRegenerateID regenerates session id for this session.
|
||||
// the session data have no changes.
|
||||
func (c *Controller) SessionRegenerateID() {
|
||||
func (c *Controller) SessionRegenerateID() error {
|
||||
if c.CruSession != nil {
|
||||
c.CruSession.SessionRelease(nil, c.Ctx.ResponseWriter)
|
||||
c.CruSession.SessionRelease(context2.Background(), c.Ctx.ResponseWriter)
|
||||
}
|
||||
c.CruSession = GlobalSessions.SessionRegenerateID(c.Ctx.ResponseWriter, c.Ctx.Request)
|
||||
var err error
|
||||
c.CruSession, err = GlobalSessions.SessionRegenerateID(c.Ctx.ResponseWriter, c.Ctx.Request)
|
||||
c.Ctx.Input.CruSession = c.CruSession
|
||||
return err
|
||||
}
|
||||
|
||||
// DestroySession cleans session data and session cookie.
|
||||
func (c *Controller) DestroySession() {
|
||||
c.Ctx.Input.CruSession.Flush(nil)
|
||||
func (c *Controller) DestroySession() error {
|
||||
err := c.Ctx.Input.CruSession.Flush(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Ctx.Input.CruSession = nil
|
||||
GlobalSessions.SessionDestroy(c.Ctx.ResponseWriter, c.Ctx.Request)
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsAjax returns this request is ajax or not.
|
||||
|
||||
@@ -298,15 +298,21 @@ func (manager *Manager) GC() {
|
||||
}
|
||||
|
||||
// SessionRegenerateID Regenerate a session id for this SessionStore who's id is saving in http request.
|
||||
func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Request) (session Store) {
|
||||
func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Request) (Store, error) {
|
||||
sid, err := manager.sessionID()
|
||||
if err != nil {
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var session Store
|
||||
|
||||
cookie, err := r.Cookie(manager.config.CookieName)
|
||||
if err != nil || cookie.Value == "" {
|
||||
//delete old cookie
|
||||
session, _ = manager.provider.SessionRead(nil, sid)
|
||||
session, err = manager.provider.SessionRead(nil, sid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cookie = &http.Cookie{Name: manager.config.CookieName,
|
||||
Value: url.QueryEscape(sid),
|
||||
Path: "/",
|
||||
@@ -315,8 +321,16 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque
|
||||
Domain: manager.config.Domain,
|
||||
}
|
||||
} else {
|
||||
oldsid, _ := url.QueryUnescape(cookie.Value)
|
||||
session, _ = manager.provider.SessionRegenerate(nil, oldsid, sid)
|
||||
oldsid, err := url.QueryUnescape(cookie.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
session, err = manager.provider.SessionRegenerate(nil, oldsid, sid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cookie.Value = url.QueryEscape(sid)
|
||||
cookie.HttpOnly = true
|
||||
cookie.Path = "/"
|
||||
@@ -335,7 +349,7 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque
|
||||
w.Header().Set(manager.config.SessionNameInHTTPHeader, sid)
|
||||
}
|
||||
|
||||
return
|
||||
return session, nil
|
||||
}
|
||||
|
||||
// GetActiveSession Get all active sessions count number.
|
||||
|
||||
@@ -21,76 +21,109 @@ import (
|
||||
"github.com/astaxie/beego/server/web/context"
|
||||
)
|
||||
|
||||
type testinfo struct {
|
||||
url string
|
||||
requesturl string
|
||||
params map[string]string
|
||||
type testInfo struct {
|
||||
pattern string
|
||||
requestUrl string
|
||||
params map[string]string
|
||||
shouldMatchOrNot bool
|
||||
}
|
||||
|
||||
var routers []testinfo
|
||||
var routers []testInfo
|
||||
|
||||
func matchTestInfo(pattern, url string, params map[string]string) testInfo {
|
||||
return testInfo{
|
||||
pattern: pattern,
|
||||
requestUrl: url,
|
||||
params: params,
|
||||
shouldMatchOrNot: true,
|
||||
}
|
||||
}
|
||||
|
||||
func notMatchTestInfo(pattern, url string) testInfo {
|
||||
return testInfo{
|
||||
pattern: pattern,
|
||||
requestUrl: url,
|
||||
params: nil,
|
||||
shouldMatchOrNot: false,
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
routers = make([]testinfo, 0)
|
||||
routers = append(routers, testinfo{"/topic/?:auth:int", "/topic", nil})
|
||||
routers = append(routers, testinfo{"/topic/?:auth:int", "/topic/123", map[string]string{":auth": "123"}})
|
||||
routers = append(routers, testinfo{"/topic/:id/?:auth", "/topic/1", map[string]string{":id": "1"}})
|
||||
routers = append(routers, testinfo{"/topic/:id/?:auth", "/topic/1/2", map[string]string{":id": "1", ":auth": "2"}})
|
||||
routers = append(routers, testinfo{"/topic/:id/?:auth:int", "/topic/1", map[string]string{":id": "1"}})
|
||||
routers = append(routers, testinfo{"/topic/:id/?:auth:int", "/topic/1/123", map[string]string{":id": "1", ":auth": "123"}})
|
||||
routers = append(routers, testinfo{"/:id", "/123", map[string]string{":id": "123"}})
|
||||
routers = append(routers, testinfo{"/hello/?:id", "/hello", map[string]string{":id": ""}})
|
||||
routers = append(routers, testinfo{"/", "/", nil})
|
||||
routers = append(routers, testinfo{"/customer/login", "/customer/login", nil})
|
||||
routers = append(routers, testinfo{"/customer/login", "/customer/login.json", map[string]string{":ext": "json"}})
|
||||
routers = append(routers, testinfo{"/*", "/http://customer/123/", map[string]string{":splat": "http://customer/123/"}})
|
||||
routers = append(routers, testinfo{"/*", "/customer/2009/12/11", map[string]string{":splat": "customer/2009/12/11"}})
|
||||
routers = append(routers, testinfo{"/aa/*/bb", "/aa/2009/bb", map[string]string{":splat": "2009"}})
|
||||
routers = append(routers, testinfo{"/cc/*/dd", "/cc/2009/11/dd", map[string]string{":splat": "2009/11"}})
|
||||
routers = append(routers, testinfo{"/cc/:id/*", "/cc/2009/11/dd", map[string]string{":id": "2009", ":splat": "11/dd"}})
|
||||
routers = append(routers, testinfo{"/ee/:year/*/ff", "/ee/2009/11/ff", map[string]string{":year": "2009", ":splat": "11"}})
|
||||
routers = append(routers, testinfo{"/thumbnail/:size/uploads/*",
|
||||
"/thumbnail/100x100/uploads/items/2014/04/20/dPRCdChkUd651t1Hvs18.jpg",
|
||||
map[string]string{":size": "100x100", ":splat": "items/2014/04/20/dPRCdChkUd651t1Hvs18.jpg"}})
|
||||
routers = append(routers, testinfo{"/*.*", "/nice/api.json", map[string]string{":path": "nice/api", ":ext": "json"}})
|
||||
routers = append(routers, testinfo{"/:name/*.*", "/nice/api.json", map[string]string{":name": "nice", ":path": "api", ":ext": "json"}})
|
||||
routers = append(routers, testinfo{"/:name/test/*.*", "/nice/test/api.json", map[string]string{":name": "nice", ":path": "api", ":ext": "json"}})
|
||||
routers = append(routers, testinfo{"/dl/:width:int/:height:int/*.*",
|
||||
"/dl/48/48/05ac66d9bda00a3acf948c43e306fc9a.jpg",
|
||||
map[string]string{":width": "48", ":height": "48", ":ext": "jpg", ":path": "05ac66d9bda00a3acf948c43e306fc9a"}})
|
||||
routers = append(routers, testinfo{"/v1/shop/:id:int", "/v1/shop/123", map[string]string{":id": "123"}})
|
||||
routers = append(routers, testinfo{"/v1/shop/:id\\((a|b|c)\\)", "/v1/shop/123(a)", map[string]string{":id": "123"}})
|
||||
routers = append(routers, testinfo{"/v1/shop/:id\\((a|b|c)\\)", "/v1/shop/123(b)", map[string]string{":id": "123"}})
|
||||
routers = append(routers, testinfo{"/v1/shop/:id\\((a|b|c)\\)", "/v1/shop/123(c)", map[string]string{":id": "123"}})
|
||||
routers = append(routers, testinfo{"/:year:int/:month:int/:id/:endid", "/1111/111/aaa/aaa", map[string]string{":year": "1111", ":month": "111", ":id": "aaa", ":endid": "aaa"}})
|
||||
routers = append(routers, testinfo{"/v1/shop/:id/:name", "/v1/shop/123/nike", map[string]string{":id": "123", ":name": "nike"}})
|
||||
routers = append(routers, testinfo{"/v1/shop/:id/account", "/v1/shop/123/account", map[string]string{":id": "123"}})
|
||||
routers = append(routers, testinfo{"/v1/shop/:name:string", "/v1/shop/nike", map[string]string{":name": "nike"}})
|
||||
routers = append(routers, testinfo{"/v1/shop/:id([0-9]+)", "/v1/shop//123", map[string]string{":id": "123"}})
|
||||
routers = append(routers, testinfo{"/v1/shop/:id([0-9]+)_:name", "/v1/shop/123_nike", map[string]string{":id": "123", ":name": "nike"}})
|
||||
routers = append(routers, testinfo{"/v1/shop/:id(.+)_cms.html", "/v1/shop/123_cms.html", map[string]string{":id": "123"}})
|
||||
routers = append(routers, testinfo{"/v1/shop/cms_:id(.+)_:page(.+).html", "/v1/shop/cms_123_1.html", map[string]string{":id": "123", ":page": "1"}})
|
||||
routers = append(routers, testinfo{"/v1/:v/cms/aaa_:id(.+)_:page(.+).html", "/v1/2/cms/aaa_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}})
|
||||
routers = append(routers, testinfo{"/v1/:v/cms_:id(.+)_:page(.+).html", "/v1/2/cms_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}})
|
||||
routers = append(routers, testinfo{"/v1/:v(.+)_cms/ttt_:id(.+)_:page(.+).html", "/v1/2_cms/ttt_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}})
|
||||
routers = append(routers, testinfo{"/api/projects/:pid/members/?:mid", "/api/projects/1/members", map[string]string{":pid": "1"}})
|
||||
routers = append(routers, testinfo{"/api/projects/:pid/members/?:mid", "/api/projects/1/members/2", map[string]string{":pid": "1", ":mid": "2"}})
|
||||
routers = make([]testInfo, 0)
|
||||
//match example
|
||||
routers = append(routers, matchTestInfo("/topic/?:auth:int", "/topic", nil))
|
||||
routers = append(routers, matchTestInfo("/topic/?:auth:int", "/topic/123", map[string]string{":auth": "123"}))
|
||||
routers = append(routers, matchTestInfo("/topic/:id/?:auth", "/topic/1", map[string]string{":id": "1"}))
|
||||
routers = append(routers, matchTestInfo("/topic/:id/?:auth", "/topic/1/2", map[string]string{":id": "1", ":auth": "2"}))
|
||||
routers = append(routers, matchTestInfo("/topic/:id/?:auth:int", "/topic/1", map[string]string{":id": "1"}))
|
||||
routers = append(routers, matchTestInfo("/topic/:id/?:auth:int", "/topic/1/123", map[string]string{":id": "1", ":auth": "123"}))
|
||||
routers = append(routers, matchTestInfo("/:id", "/123", map[string]string{":id": "123"}))
|
||||
routers = append(routers, matchTestInfo("/hello/?:id", "/hello", map[string]string{":id": ""}))
|
||||
routers = append(routers, matchTestInfo("/", "/", nil))
|
||||
routers = append(routers, matchTestInfo("/customer/login", "/customer/login", nil))
|
||||
routers = append(routers, matchTestInfo("/customer/login", "/customer/login.json", map[string]string{":ext": "json"}))
|
||||
routers = append(routers, matchTestInfo("/*", "/http://customer/123/", map[string]string{":splat": "http://customer/123/"}))
|
||||
routers = append(routers, matchTestInfo("/*", "/customer/2009/12/11", map[string]string{":splat": "customer/2009/12/11"}))
|
||||
routers = append(routers, matchTestInfo("/aa/*/bb", "/aa/2009/bb", map[string]string{":splat": "2009"}))
|
||||
routers = append(routers, matchTestInfo("/cc/*/dd", "/cc/2009/11/dd", map[string]string{":splat": "2009/11"}))
|
||||
routers = append(routers, matchTestInfo("/cc/:id/*", "/cc/2009/11/dd", map[string]string{":id": "2009", ":splat": "11/dd"}))
|
||||
routers = append(routers, matchTestInfo("/ee/:year/*/ff", "/ee/2009/11/ff", map[string]string{":year": "2009", ":splat": "11"}))
|
||||
routers = append(routers, matchTestInfo("/thumbnail/:size/uploads/*", "/thumbnail/100x100/uploads/items/2014/04/20/dPRCdChkUd651t1Hvs18.jpg", map[string]string{":size": "100x100", ":splat": "items/2014/04/20/dPRCdChkUd651t1Hvs18.jpg"}))
|
||||
routers = append(routers, matchTestInfo("/*.*", "/nice/api.json", map[string]string{":path": "nice/api", ":ext": "json"}))
|
||||
routers = append(routers, matchTestInfo("/:name/*.*", "/nice/api.json", map[string]string{":name": "nice", ":path": "api", ":ext": "json"}))
|
||||
routers = append(routers, matchTestInfo("/:name/test/*.*", "/nice/test/api.json", map[string]string{":name": "nice", ":path": "api", ":ext": "json"}))
|
||||
routers = append(routers, matchTestInfo("/dl/:width:int/:height:int/*.*", "/dl/48/48/05ac66d9bda00a3acf948c43e306fc9a.jpg", map[string]string{":width": "48", ":height": "48", ":ext": "jpg", ":path": "05ac66d9bda00a3acf948c43e306fc9a"}))
|
||||
routers = append(routers, matchTestInfo("/v1/shop/:id:int", "/v1/shop/123", map[string]string{":id": "123"}))
|
||||
routers = append(routers, matchTestInfo("/v1/shop/:id\\((a|b|c)\\)", "/v1/shop/123(a)", map[string]string{":id": "123"}))
|
||||
routers = append(routers, matchTestInfo("/v1/shop/:id\\((a|b|c)\\)", "/v1/shop/123(b)", map[string]string{":id": "123"}))
|
||||
routers = append(routers, matchTestInfo("/v1/shop/:id\\((a|b|c)\\)", "/v1/shop/123(c)", map[string]string{":id": "123"}))
|
||||
routers = append(routers, matchTestInfo("/:year:int/:month:int/:id/:endid", "/1111/111/aaa/aaa", map[string]string{":year": "1111", ":month": "111", ":id": "aaa", ":endid": "aaa"}))
|
||||
routers = append(routers, matchTestInfo("/v1/shop/:id/:name", "/v1/shop/123/nike", map[string]string{":id": "123", ":name": "nike"}))
|
||||
routers = append(routers, matchTestInfo("/v1/shop/:id/account", "/v1/shop/123/account", map[string]string{":id": "123"}))
|
||||
routers = append(routers, matchTestInfo("/v1/shop/:name:string", "/v1/shop/nike", map[string]string{":name": "nike"}))
|
||||
routers = append(routers, matchTestInfo("/v1/shop/:id([0-9]+)", "/v1/shop//123", map[string]string{":id": "123"}))
|
||||
routers = append(routers, matchTestInfo("/v1/shop/:id([0-9]+)_:name", "/v1/shop/123_nike", map[string]string{":id": "123", ":name": "nike"}))
|
||||
routers = append(routers, matchTestInfo("/v1/shop/:id(.+)_cms.html", "/v1/shop/123_cms.html", map[string]string{":id": "123"}))
|
||||
routers = append(routers, matchTestInfo("/v1/shop/cms_:id(.+)_:page(.+).html", "/v1/shop/cms_123_1.html", map[string]string{":id": "123", ":page": "1"}))
|
||||
routers = append(routers, matchTestInfo("/v1/:v/cms/aaa_:id(.+)_:page(.+).html", "/v1/2/cms/aaa_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}))
|
||||
routers = append(routers, matchTestInfo("/v1/:v/cms_:id(.+)_:page(.+).html", "/v1/2/cms_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}))
|
||||
routers = append(routers, matchTestInfo("/v1/:v(.+)_cms/ttt_:id(.+)_:page(.+).html", "/v1/2_cms/ttt_123_1.html", map[string]string{":v": "2", ":id": "123", ":page": "1"}))
|
||||
routers = append(routers, matchTestInfo("/api/projects/:pid/members/?:mid", "/api/projects/1/members", map[string]string{":pid": "1"}))
|
||||
routers = append(routers, matchTestInfo("/api/projects/:pid/members/?:mid", "/api/projects/1/members/2", map[string]string{":pid": "1", ":mid": "2"}))
|
||||
|
||||
//not match example
|
||||
|
||||
// https://github.com/astaxie/beego/issues/3865
|
||||
routers = append(routers, notMatchTestInfo("/read_:id:int\\.htm", "/read_222htm"))
|
||||
routers = append(routers, notMatchTestInfo("/read_:id:int\\.htm", "/read_222_htm"))
|
||||
routers = append(routers, notMatchTestInfo("/read_:id:int\\.htm", " /read_262shtm"))
|
||||
|
||||
}
|
||||
|
||||
func TestTreeRouters(t *testing.T) {
|
||||
for _, r := range routers {
|
||||
shouldMatch := r.shouldMatchOrNot
|
||||
|
||||
tr := NewTree()
|
||||
tr.AddRouter(r.url, "astaxie")
|
||||
tr.AddRouter(r.pattern, "astaxie")
|
||||
ctx := context.NewContext()
|
||||
obj := tr.Match(r.requesturl, ctx)
|
||||
obj := tr.Match(r.requestUrl, ctx)
|
||||
if !shouldMatch {
|
||||
if obj != nil {
|
||||
t.Fatal("pattern:", r.pattern, ", should not match", r.requestUrl)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
if obj == nil || obj.(string) != "astaxie" {
|
||||
t.Fatal(r.url+" can't get obj, Expect ", r.requesturl)
|
||||
t.Fatal("pattern:", r.pattern+", can't match obj, Expect ", r.requestUrl)
|
||||
}
|
||||
if r.params != nil {
|
||||
for k, v := range r.params {
|
||||
if vv := ctx.Input.Param(k); vv != v {
|
||||
t.Fatal("The Rule: " + r.url + "\nThe RequestURL:" + r.requesturl + "\nThe Key is " + k + ", The Value should be: " + v + ", but get: " + vv)
|
||||
t.Fatal("The Rule: " + r.pattern + "\nThe RequestURL:" + r.requestUrl + "\nThe Key is " + k + ", The Value should be: " + v + ", but get: " + vv)
|
||||
} else if vv == "" && v != "" {
|
||||
t.Fatal(r.url + " " + r.requesturl + " get param empty:" + k)
|
||||
t.Fatal(r.pattern + " " + r.requestUrl + " get param empty:" + k)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,7 +280,6 @@ func TestAddTree5(t *testing.T) {
|
||||
t.Fatal("url /v1/shop/ need match router /v1/shop/ ")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitPath(t *testing.T) {
|
||||
a := splitPath("")
|
||||
if len(a) != 0 {
|
||||
@@ -292,6 +324,7 @@ func TestSplitSegment(t *testing.T) {
|
||||
":id([0-9]+)": {true, []string{":id"}, `([0-9]+)`},
|
||||
":id([0-9]+)_:name": {true, []string{":id", ":name"}, `([0-9]+)_(.+)`},
|
||||
":id(.+)_cms.html": {true, []string{":id"}, `(.+)_cms.html`},
|
||||
":id(.+)_cms\\.html": {true, []string{":id"}, `(.+)_cms\.html`},
|
||||
"cms_:id(.+)_:page(.+).html": {true, []string{":id", ":page"}, `cms_(.+)_(.+).html`},
|
||||
`:app(a|b|c)`: {true, []string{":app"}, `(a|b|c)`},
|
||||
`:app\((a|b|c)\)`: {true, []string{":app"}, `(.+)\((a|b|c)\)`},
|
||||
@@ -303,4 +336,4 @@ func TestSplitSegment(t *testing.T) {
|
||||
t.Fatalf("%s should return %t,%s,%q, got %t,%s,%q", pattern, v.isReg, v.params, v.regStr, b, w, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user