9f2327ee by mingqi.zhou

Merge remote-tracking branch 'astaxie.beego/master'

2 parents 68f2a5dd b1374b6a
...@@ -40,7 +40,14 @@ func init() { ...@@ -40,7 +40,14 @@ func init() {
40 } 40 }
41 41
42 func AdminIndex(rw http.ResponseWriter, r *http.Request) { 42 func AdminIndex(rw http.ResponseWriter, r *http.Request) {
43 rw.Write([]byte("Welcome to Admin Dashboard")) 43 rw.Write([]byte("Welcome to Admin Dashboard\n"))
44 rw.Write([]byte("There are servral functions:\n"))
45 rw.Write([]byte("1. Record all request and request time, http://localhost:8088/qps\n"))
46 rw.Write([]byte("2. Get runtime profiling data by the pprof, http://localhost:8088/prof\n"))
47 rw.Write([]byte("3. Get healthcheck result from http://localhost:8088/prof\n"))
48 rw.Write([]byte("4. Get current task infomation from taskhttp://localhost:8088/task \n"))
49 rw.Write([]byte("5. To run a task passed a param http://localhost:8088/runtask\n"))
50
44 } 51 }
45 52
46 func QpsIndex(rw http.ResponseWriter, r *http.Request) { 53 func QpsIndex(rw http.ResponseWriter, r *http.Request) {
......
...@@ -3,6 +3,7 @@ package beego ...@@ -3,6 +3,7 @@ package beego
3 import ( 3 import (
4 "bytes" 4 "bytes"
5 "crypto/hmac" 5 "crypto/hmac"
6 "crypto/rand"
6 "crypto/sha1" 7 "crypto/sha1"
7 "encoding/base64" 8 "encoding/base64"
8 "errors" 9 "errors"
...@@ -370,7 +371,7 @@ func (c *Controller) XsrfToken() string { ...@@ -370,7 +371,7 @@ func (c *Controller) XsrfToken() string {
370 } else { 371 } else {
371 expire = int64(XSRFExpire) 372 expire = int64(XSRFExpire)
372 } 373 }
373 token = GetRandomString(15) 374 token = getRandomString(15)
374 c.SetSecureCookie(XSRFKEY, "_xsrf", token, expire) 375 c.SetSecureCookie(XSRFKEY, "_xsrf", token, expire)
375 } 376 }
376 c._xsrf_token = token 377 c._xsrf_token = token
...@@ -405,3 +406,14 @@ func (c *Controller) GoToFunc(funcname string) { ...@@ -405,3 +406,14 @@ func (c *Controller) GoToFunc(funcname string) {
405 } 406 }
406 c.gotofunc = funcname 407 c.gotofunc = funcname
407 } 408 }
409
410 //utils func for controller internal
411 func getRandomString(n int) string {
412 const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
413 var bytes = make([]byte, n)
414 rand.Read(bytes)
415 for i, b := range bytes {
416 bytes[i] = alphanum[b%byte(len(alphanum))]
417 }
418 return string(bytes)
419 }
......
...@@ -15,6 +15,7 @@ import ( ...@@ -15,6 +15,7 @@ import (
15 beecontext "github.com/astaxie/beego/context" 15 beecontext "github.com/astaxie/beego/context"
16 "github.com/astaxie/beego/middleware" 16 "github.com/astaxie/beego/middleware"
17 "github.com/astaxie/beego/toolbox" 17 "github.com/astaxie/beego/toolbox"
18 "github.com/astaxie/beego/utils"
18 ) 19 )
19 20
20 const ( 21 const (
...@@ -159,7 +160,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM ...@@ -159,7 +160,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM
159 } 160 }
160 comma := strings.Split(colon[0], ",") 161 comma := strings.Split(colon[0], ",")
161 for _, m := range comma { 162 for _, m := range comma {
162 if m == "*" || inSlice(strings.ToLower(m), HTTPMETHOD) { 163 if m == "*" || utils.InSlice(strings.ToLower(m), HTTPMETHOD) {
163 if val := reflectVal.MethodByName(colon[1]); val.IsValid() { 164 if val := reflectVal.MethodByName(colon[1]); val.IsValid() {
164 methods[strings.ToLower(m)] = colon[1] 165 methods[strings.ToLower(m)] = colon[1]
165 } else { 166 } else {
...@@ -272,7 +273,7 @@ func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string { ...@@ -272,7 +273,7 @@ func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string {
272 for _, route := range p.fixrouters { 273 for _, route := range p.fixrouters {
273 if route.controllerType.Name() == controllName { 274 if route.controllerType.Name() == controllName {
274 var finded bool 275 var finded bool
275 if inSlice(strings.ToLower(methodName), HTTPMETHOD) { 276 if utils.InSlice(strings.ToLower(methodName), HTTPMETHOD) {
276 if route.hasMethod { 277 if route.hasMethod {
277 if m, ok := route.methods[strings.ToLower(methodName)]; ok && m != methodName { 278 if m, ok := route.methods[strings.ToLower(methodName)]; ok && m != methodName {
278 finded = false 279 finded = false
...@@ -303,7 +304,7 @@ func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string { ...@@ -303,7 +304,7 @@ func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string {
303 for _, route := range p.routers { 304 for _, route := range p.routers {
304 if route.controllerType.Name() == controllName { 305 if route.controllerType.Name() == controllName {
305 var finded bool 306 var finded bool
306 if inSlice(strings.ToLower(methodName), HTTPMETHOD) { 307 if utils.InSlice(strings.ToLower(methodName), HTTPMETHOD) {
307 if route.hasMethod { 308 if route.hasMethod {
308 if m, ok := route.methods[strings.ToLower(methodName)]; ok && m != methodName { 309 if m, ok := route.methods[strings.ToLower(methodName)]; ok && m != methodName {
309 finded = false 310 finded = false
...@@ -419,7 +420,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) ...@@ -419,7 +420,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
419 context.Output = beecontext.NewOutput(rw) 420 context.Output = beecontext.NewOutput(rw)
420 } 421 }
421 422
422 if !inSlice(strings.ToLower(r.Method), HTTPMETHOD) { 423 if !utils.InSlice(strings.ToLower(r.Method), HTTPMETHOD) {
423 http.Error(w, "Method Not Allowed", 405) 424 http.Error(w, "Method Not Allowed", 405)
424 goto Admin 425 goto Admin
425 } 426 }
......
...@@ -9,9 +9,10 @@ import ( ...@@ -9,9 +9,10 @@ import (
9 "io/ioutil" 9 "io/ioutil"
10 "os" 10 "os"
11 "path/filepath" 11 "path/filepath"
12 "reflect"
13 "regexp" 12 "regexp"
14 "strings" 13 "strings"
14
15 "github.com/astaxie/beego/utils"
15 ) 16 )
16 17
17 var ( 18 var (
...@@ -144,7 +145,7 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp ...@@ -144,7 +145,7 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp
144 } else { 145 } else {
145 fileabspath = filepath.Join(root, file) 146 fileabspath = filepath.Join(root, file)
146 } 147 }
147 if e, _ := FileExists(fileabspath); !e { 148 if e := utils.FileExists(fileabspath); !e {
148 panic("can't find template file" + file) 149 panic("can't find template file" + file)
149 } 150 }
150 data, err := ioutil.ReadFile(fileabspath) 151 data, err := ioutil.ReadFile(fileabspath)
...@@ -238,156 +239,3 @@ func _getTemplate(t0 *template.Template, root string, submods [][]string, others ...@@ -238,156 +239,3 @@ func _getTemplate(t0 *template.Template, root string, submods [][]string, others
238 } 239 }
239 return 240 return
240 } 241 }
241
242 // go1.2 added template funcs. begin
243 var (
244 errBadComparisonType = errors.New("invalid type for comparison")
245 errBadComparison = errors.New("incompatible types for comparison")
246 errNoComparison = errors.New("missing argument for comparison")
247 )
248
249 type kind int
250
251 const (
252 invalidKind kind = iota
253 boolKind
254 complexKind
255 intKind
256 floatKind
257 integerKind
258 stringKind
259 uintKind
260 )
261
262 func basicKind(v reflect.Value) (kind, error) {
263 switch v.Kind() {
264 case reflect.Bool:
265 return boolKind, nil
266 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
267 return intKind, nil
268 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
269 return uintKind, nil
270 case reflect.Float32, reflect.Float64:
271 return floatKind, nil
272 case reflect.Complex64, reflect.Complex128:
273 return complexKind, nil
274 case reflect.String:
275 return stringKind, nil
276 }
277 return invalidKind, errBadComparisonType
278 }
279
280 // eq evaluates the comparison a == b || a == c || ...
281 func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
282 v1 := reflect.ValueOf(arg1)
283 k1, err := basicKind(v1)
284 if err != nil {
285 return false, err
286 }
287 if len(arg2) == 0 {
288 return false, errNoComparison
289 }
290 for _, arg := range arg2 {
291 v2 := reflect.ValueOf(arg)
292 k2, err := basicKind(v2)
293 if err != nil {
294 return false, err
295 }
296 if k1 != k2 {
297 return false, errBadComparison
298 }
299 truth := false
300 switch k1 {
301 case boolKind:
302 truth = v1.Bool() == v2.Bool()
303 case complexKind:
304 truth = v1.Complex() == v2.Complex()
305 case floatKind:
306 truth = v1.Float() == v2.Float()
307 case intKind:
308 truth = v1.Int() == v2.Int()
309 case stringKind:
310 truth = v1.String() == v2.String()
311 case uintKind:
312 truth = v1.Uint() == v2.Uint()
313 default:
314 panic("invalid kind")
315 }
316 if truth {
317 return true, nil
318 }
319 }
320 return false, nil
321 }
322
323 // ne evaluates the comparison a != b.
324 func ne(arg1, arg2 interface{}) (bool, error) {
325 // != is the inverse of ==.
326 equal, err := eq(arg1, arg2)
327 return !equal, err
328 }
329
330 // lt evaluates the comparison a < b.
331 func lt(arg1, arg2 interface{}) (bool, error) {
332 v1 := reflect.ValueOf(arg1)
333 k1, err := basicKind(v1)
334 if err != nil {
335 return false, err
336 }
337 v2 := reflect.ValueOf(arg2)
338 k2, err := basicKind(v2)
339 if err != nil {
340 return false, err
341 }
342 if k1 != k2 {
343 return false, errBadComparison
344 }
345 truth := false
346 switch k1 {
347 case boolKind, complexKind:
348 return false, errBadComparisonType
349 case floatKind:
350 truth = v1.Float() < v2.Float()
351 case intKind:
352 truth = v1.Int() < v2.Int()
353 case stringKind:
354 truth = v1.String() < v2.String()
355 case uintKind:
356 truth = v1.Uint() < v2.Uint()
357 default:
358 panic("invalid kind")
359 }
360 return truth, nil
361 }
362
363 // le evaluates the comparison <= b.
364 func le(arg1, arg2 interface{}) (bool, error) {
365 // <= is < or ==.
366 lessThan, err := lt(arg1, arg2)
367 if lessThan || err != nil {
368 return lessThan, err
369 }
370 return eq(arg1, arg2)
371 }
372
373 // gt evaluates the comparison a > b.
374 func gt(arg1, arg2 interface{}) (bool, error) {
375 // > is the inverse of <=.
376 lessOrEqual, err := le(arg1, arg2)
377 if err != nil {
378 return false, err
379 }
380 return !lessOrEqual, nil
381 }
382
383 // ge evaluates the comparison a >= b.
384 func ge(arg1, arg2 interface{}) (bool, error) {
385 // >= is the inverse of <.
386 lessThan, err := lt(arg1, arg2)
387 if err != nil {
388 return false, err
389 }
390 return !lessThan, nil
391 }
392
393 // go1.2 added template funcs. end
......
...@@ -7,18 +7,6 @@ import ( ...@@ -7,18 +7,6 @@ import (
7 "time" 7 "time"
8 ) 8 )
9 9
10 func TestWebTime(t *testing.T) {
11 ts := "Fri, 26 Jul 2013 12:27:42 CST"
12 l, _ := time.LoadLocation("GST")
13 tt, _ := time.ParseInLocation(time.RFC1123, ts, l)
14 if ts != webTime(tt) {
15 t.Error("should be equal")
16 }
17 if "Fri, 26 Jul 2013 12:27:42 GMT" != webTime(tt.UTC()) {
18 t.Error("should be equal")
19 }
20 }
21
22 func TestSubstr(t *testing.T) { 10 func TestSubstr(t *testing.T) {
23 s := `012345` 11 s := `012345`
24 if Substr(s, 0, 2) != "01" { 12 if Substr(s, 0, 2) != "01" {
...@@ -92,16 +80,6 @@ func TestHtmlunquote(t *testing.T) { ...@@ -92,16 +80,6 @@ func TestHtmlunquote(t *testing.T) {
92 } 80 }
93 } 81 }
94 82
95 func TestInSlice(t *testing.T) {
96 sl := []string{"A", "b"}
97 if !inSlice("A", sl) {
98 t.Error("should be true")
99 }
100 if inSlice("B", sl) {
101 t.Error("should be false")
102 }
103 }
104
105 func TestParseForm(t *testing.T) { 83 func TestParseForm(t *testing.T) {
106 type user struct { 84 type user struct {
107 Id int `form:"-"` 85 Id int `form:"-"`
......
...@@ -30,7 +30,7 @@ func FileExists(name string) bool { ...@@ -30,7 +30,7 @@ func FileExists(name string) bool {
30 30
31 // search a file in paths. 31 // search a file in paths.
32 // this is offen used in search config file in /etc ~/ 32 // this is offen used in search config file in /etc ~/
33 func LookFile(filename string, paths ...string) (fullpath string, err error) { 33 func SearchFile(filename string, paths ...string) (fullpath string, err error) {
34 for _, path := range paths { 34 for _, path := range paths {
35 if fullpath = filepath.Join(path, filename); FileExists(fullpath) { 35 if fullpath = filepath.Join(path, filename); FileExists(fullpath) {
36 return 36 return
...@@ -41,7 +41,7 @@ func LookFile(filename string, paths ...string) (fullpath string, err error) { ...@@ -41,7 +41,7 @@ func LookFile(filename string, paths ...string) (fullpath string, err error) {
41 } 41 }
42 42
43 // like command grep -E 43 // like command grep -E
44 // for example: GrepE(`^hello`, "hello.txt") 44 // for example: GrepFile(`^hello`, "hello.txt")
45 // \n is striped while read 45 // \n is striped while read
46 func GrepFile(patten string, filename string) (lines []string, err error) { 46 func GrepFile(patten string, filename string) (lines []string, err error) {
47 re, err := regexp.Compile(patten) 47 re, err := regexp.Compile(patten)
......
...@@ -23,7 +23,7 @@ func TestSelfDir(t *testing.T) { ...@@ -23,7 +23,7 @@ func TestSelfDir(t *testing.T) {
23 23
24 func TestFileExists(t *testing.T) { 24 func TestFileExists(t *testing.T) {
25 if !FileExists("./file.go") { 25 if !FileExists("./file.go") {
26 t.Errorf("/bin/echo should exists, but it didn't") 26 t.Errorf("./file.go should exists, but it didn't")
27 } 27 }
28 28
29 if FileExists(noExistedFile) { 29 if FileExists(noExistedFile) {
...@@ -31,14 +31,14 @@ func TestFileExists(t *testing.T) { ...@@ -31,14 +31,14 @@ func TestFileExists(t *testing.T) {
31 } 31 }
32 } 32 }
33 33
34 func TestLookFile(t *testing.T) { 34 func TestSearchFile(t *testing.T) {
35 path, err := LookFile(filepath.Base(SelfPath()), SelfDir()) 35 path, err := SearchFile(filepath.Base(SelfPath()), SelfDir())
36 if err != nil { 36 if err != nil {
37 t.Error(err) 37 t.Error(err)
38 } 38 }
39 t.Log(path) 39 t.Log(path)
40 40
41 path, err = LookFile(noExistedFile, ".") 41 path, err = SearchFile(noExistedFile, ".")
42 if err == nil { 42 if err == nil {
43 t.Errorf("err shouldnot be nil, got path: %s", SelfDir()) 43 t.Errorf("err shouldnot be nil, got path: %s", SelfDir())
44 } 44 }
......
1 package beego 1 package utils
2 2
3 import ( 3 import (
4 "sync" 4 "sync"
......
1 package beego 1 package utils
2 2
3 import ( 3 import (
4 "testing" 4 "testing"
......
1 package utils
2
3 import (
4 "math/rand"
5 "time"
6 )
7
8 type reducetype func(interface{}) interface{}
9 type filtertype func(interface{}) bool
10
11 func InSlice(v string, sl []string) bool {
12 for _, vv := range sl {
13 if vv == v {
14 return true
15 }
16 }
17 return false
18 }
19
20 func InSliceIface(v interface{}, sl []interface{}) bool {
21 for _, vv := range sl {
22 if vv == v {
23 return true
24 }
25 }
26 return false
27 }
28
29 func SliceRandList(min, max int) []int {
30 if max < min {
31 min, max = max, min
32 }
33 length := max - min + 1
34 t0 := time.Now()
35 rand.Seed(int64(t0.Nanosecond()))
36 list := rand.Perm(length)
37 for index, _ := range list {
38 list[index] += min
39 }
40 return list
41 }
42
43 func SliceMerge(slice1, slice2 []interface{}) (c []interface{}) {
44 c = append(slice1, slice2...)
45 return
46 }
47
48 func SliceReduce(slice []interface{}, a reducetype) (dslice []interface{}) {
49 for _, v := range slice {
50 dslice = append(dslice, a(v))
51 }
52 return
53 }
54
55 func SliceRand(a []interface{}) (b interface{}) {
56 randnum := rand.Intn(len(a))
57 b = a[randnum]
58 return
59 }
60
61 func SliceSum(intslice []int64) (sum int64) {
62 for _, v := range intslice {
63 sum += v
64 }
65 return
66 }
67
68 func SliceFilter(slice []interface{}, a filtertype) (ftslice []interface{}) {
69 for _, v := range slice {
70 if a(v) {
71 ftslice = append(ftslice, v)
72 }
73 }
74 return
75 }
76
77 func SliceDiff(slice1, slice2 []interface{}) (diffslice []interface{}) {
78 for _, v := range slice1 {
79 if !InSliceIface(v, slice2) {
80 diffslice = append(diffslice, v)
81 }
82 }
83 return
84 }
85
86 func SliceIntersect(slice1, slice2 []interface{}) (diffslice []interface{}) {
87 for _, v := range slice1 {
88 if !InSliceIface(v, slice2) {
89 diffslice = append(diffslice, v)
90 }
91 }
92 return
93 }
94
95 func SliceChunk(slice []interface{}, size int) (chunkslice [][]interface{}) {
96 if size >= len(slice) {
97 chunkslice = append(chunkslice, slice)
98 return
99 }
100 end := size
101 for i := 0; i <= (len(slice) - size); i += size {
102 chunkslice = append(chunkslice, slice[i:end])
103 end += size
104 }
105 return
106 }
107
108 func SliceRange(start, end, step int64) (intslice []int64) {
109 for i := start; i <= end; i += step {
110 intslice = append(intslice, i)
111 }
112 return
113 }
114
115 func SlicePad(slice []interface{}, size int, val interface{}) []interface{} {
116 if size <= len(slice) {
117 return slice
118 }
119 for i := 0; i < (size - len(slice)); i++ {
120 slice = append(slice, val)
121 }
122 return slice
123 }
124
125 func SliceUnique(slice []interface{}) (uniqueslice []interface{}) {
126 for _, v := range slice {
127 if !InSliceIface(v, uniqueslice) {
128 uniqueslice = append(uniqueslice, v)
129 }
130 }
131 return
132 }
133
134 func SliceShuffle(slice []interface{}) []interface{} {
135 for i := 0; i < len(slice); i++ {
136 a := rand.Intn(len(slice))
137 b := rand.Intn(len(slice))
138 slice[a], slice[b] = slice[b], slice[a]
139 }
140 return slice
141 }
1 package utils
2
3 import (
4 "testing"
5 )
6
7 func TestInSlice(t *testing.T) {
8 sl := []string{"A", "b"}
9 if !InSlice("A", sl) {
10 t.Error("should be true")
11 }
12 if InSlice("B", sl) {
13 t.Error("should be false")
14 }
15 }
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!