Skip to content
This repository has been archived by the owner on Feb 3, 2021. It is now read-only.

Commit

Permalink
more router tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lunny committed Apr 15, 2015
1 parent a0f62f4 commit 9e0c382
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 77 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Tango [![Build Status](https://drone.io/github.com/lunny/tango/status.png)](http

Package tango is a micro-kernel & pluggable web framework for Go.

##### Current version: v0.4.3 [Version History](https://github.com/lunny/tango/releases)
##### Current version: v0.4.4 [Version History](https://github.com/lunny/tango/releases)

## Getting Started

Expand Down
2 changes: 1 addition & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Tango [![Build Status](https://drone.io/github.com/lunny/tango/status.png)](http

Tango 是一个微内核易扩展的Go语言Web框架.

##### 当前版本: v0.4.3 [版本更新记录](https://github.com/lunny/tango/releases)
##### 当前版本: v0.4.4 [版本更新记录](https://github.com/lunny/tango/releases)

## 简介

Expand Down
99 changes: 50 additions & 49 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,52 +1,53 @@
// package nodb is a high performance embedded NoSQL.
//
// Copyright 2014 lunny. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.
/*
Tango is a micro & pluggable web framework for Go language.
package main
import "github.com/lunny/tango"
type Action struct {
}
func (Action) Get() string {
return "Hello tango!"
}
func main() {
t := tango.Classic()
t.Get("/", new(Action))
t.Run()
}
Middlewares allow you easily plugin/unplugin features for your Tango applications.
There are already many [middlewares](https://github.com/tango-contrib) to simplify your work:
- recovery - recover after panic
- compress - Gzip & Deflate compression
- static - Serves static files
- logger - Log the request & inject Logger to action struct
- param - get the router parameters
- return - Handle the returned value smartlly
- ctx - Inject context to action struct
- [session](https://github.com/tango-contrib/session) - Session manager, with stores support:
* Memory - memory as a session store
* [Redis](https://github.com/tango-contrib/session-redis) - redis server as a session store
* [nodb](https://github.com/tango-contrib/session-nodb) - nodb as a session store
* [ledis](https://github.com/tango-contrib/session-ledis) - ledis server as a session store)
- [xsrf](https://github.com/tango-contrib/xsrf) - Generates and validates csrf tokens
- [binding](https://github.com/tango-contrib/binding) - Bind and validates forms
- [renders](https://github.com/tango-contrib/renders) - Go template engine
- [dispatch](https://github.com/tango-contrib/dispatch) - Multiple Application support on one server
- [tpongo2](https://github.com/tango-contrib/tpongo2) - Pongo2 teamplte engine support
- [captcha](https://github.com/tango-contrib/captcha) - Captcha
- [events](https://github.com/tango-contrib/events) - Before and After
- [flash](https://github.com/tango-contrib/flash) - Share data between requests
- [debug](https://github.com/tango-contrib/debug) - Show detail debug infomaton on log
*/

package tango

// Tango is a micro & pluggable web framework for Go language.

// package main

// import "github.com/lunny/tango"

// type Action struct {
// }

// func (Action) Get() string {
// return "Hello tango!"
// }

// func main() {
// t := tango.Classic()
// t.Get("/", new(Action))
// t.Run()
// }

// Middlewares allow you easily plugin/unplugin features for your Tango applications.

// There are already many [middlewares](https://github.com/tango-contrib) to simplify your work:

// - recovery - recover after panic
// - compress - Gzip & Deflate compression
// - static - Serves static files
// - logger - Log the request & inject Logger to action struct
// - param - get the router parameters
// - return - Handle the returned value smartlly
// - ctx - Inject context to action struct

// - [session](https://github.com/tango-contrib/session) - Session manager, with stores support:
// * Memory - memory as a session store
// * [Redis](https://github.com/tango-contrib/session-redis) - redis server as a session store
// * [nodb](https://github.com/tango-contrib/session-nodb) - nodb as a session store
// * [ledis](https://github.com/tango-contrib/session-ledis) - ledis server as a session store)
// - [xsrf](https://github.com/tango-contrib/xsrf) - Generates and validates csrf tokens
// - [binding](https://github.com/tango-contrib/binding) - Bind and validates forms
// - [renders](https://github.com/tango-contrib/renders) - Go template engine
// - [dispatch](https://github.com/tango-contrib/dispatch) - Multiple Application support on one server
// - [tpongo2](https://github.com/tango-contrib/tpongo2) - Pongo2 teamplte engine support
// - [captcha](https://github.com/tango-contrib/captcha) - Captcha
// - [events](https://github.com/tango-contrib/events) - Before and After
// - [flash](https://github.com/tango-contrib/flash) - Share data between requests
// - [debug](https://github.com/tango-contrib/debug) - Show detail debug infomaton on log

package tango
46 changes: 23 additions & 23 deletions router.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,21 +201,24 @@ func parseNodes(path string) []*node {
}
i = i + bracket
j = i
bracket = 0
if i == l {
return nodes
}
} else if path[i] == '*' {
nodes = append(nodes, &node{tp: snode, content: path[j:i]})
nodes = append(nodes, &node{tp: snode, content: path[j : i-bracket]})
j = i
if bracket == 1 {
for ; i < l && ')' == path[i]; i++ {
for ; i < l && ')' != path[i]; i++ {
}
} else {
i = i + 1
for ; i < l && isAlnum(path[i]); i++ {
}
}
nodes = append(nodes, &node{tp: anode, content: path[j:i]})
i = i + bracket
bracket = 0
j = i
if i == l {
return nodes
Expand Down Expand Up @@ -280,75 +283,72 @@ func (r *router) addRoute(method, path string, h *Route) {
//r.printTrees()
}

func (r *router) matchNode(n *node, url string, params *Params) *node {
func (r *router) matchNode(n *node, url string, params Params) (*node, Params) {
if n.tp == snode {
if strings.HasPrefix(url, n.content) {
if len(url) == len(n.content) {
return n
return n, params
}
for _, c := range n.edges {
e := r.matchNode(c, url[len(n.content):], params)
e, newParams := r.matchNode(c, url[len(n.content):], params)
if e != nil {
return e
return e, newParams
}
}
}
} else if n.tp == anode {
for _, c := range n.edges {
idx := strings.LastIndex(url, c.content)
if idx > -1 {
*params = append(*params, param{n.content, url[:idx]})
params = append(params, param{n.content, url[:idx]})
return r.matchNode(c, url[idx:], params)
}
}
*params = append(*params, param{n.content, url})
return n
return n, append(params, param{n.content, url})
} else if n.tp == nnode {
idx := strings.IndexByte(url, '/')
if idx > -1 {
for _, c := range n.edges {
h := r.matchNode(c, url[idx:], params)
h, newParams := r.matchNode(c, url[idx:], params)
if h != nil {
*params = append(*params, param{n.content, url[:idx]})
return h
return h, append([]param{param{n.content, url[:idx]}}, newParams...)
}
}
return nil
return nil, params
}

for _, c := range n.edges {
idx := strings.Index(url, c.content)
if idx > -1 {
*params = append(*params, param{n.content, url[:idx]})
params = append(params, param{n.content, url[:idx]})
return r.matchNode(c, url[idx:], params)
}
}
*params = append(*params, param{n.content, url})
return n
params = append(params, param{n.content, url})
return n, params
} else if n.tp == rnode {
if len(n.edges) == 0 && n.regexp.MatchString(url) {
*params = append(*params, param{n.content, url})
return n
params = append(params, param{n.content, url})
return n, params
}
for _, c := range n.edges {
idx := strings.Index(url, c.content)
if idx > -1 && n.regexp.MatchString(url[:idx]) {
*params = append(*params, param{n.content, url[:idx]})
params = append(params, param{n.content, url[:idx]})
return r.matchNode(c, url[idx:], params)
}
}
}
return nil
return nil, params
}

func (r *router) Match(url, method string) (*Route, Params) {
cn := r.trees[method]
var params = make(Params, 0, strings.Count(url, "/"))
for _, n := range cn.edges {
e := r.matchNode(n, url, &params)
e, newParams := r.matchNode(n, url, params)
if e != nil {
//fmt.Println("matched:", e.path, params)
return e.handle, params
return e.handle, newParams
}
}
return nil, nil
Expand Down
Loading

0 comments on commit 9e0c382

Please sign in to comment.