Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
张磊
/
FileStorageBeego
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
020bfbcc
authored
2015-02-27 22:47:59 +0800
by
astaxie
Browse Files
Options
Browse Files
Tag
Download
Plain Diff
Merge branch 'develop'
2 parents
d536f5b8
3f8252bf
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
564 additions
and
397 deletions
admin.go
adminui.go
app.go
beego.go
cache/cache_test.go
cache/file.go
cache/redis/redis.go
config.go
config/json.go
config/json_test.go
context/context.go
context/input.go
context/input_test.go
context/output.go
controller.go
middleware/error.go → error.go
httplib/httplib.go
logs/conn.go
logs/console.go
logs/file.go
logs/log.go
logs/smtp.go
middleware/exceptions.go
middleware/i18n.go
namespace.go
orm/cmd_utils.go
orm/models_info_f.go
orm/orm.go
orm/types.go
parser.go
plugins/cors/cors.go
router.go
session/ledis/ledis_session.go
session/redis/sess_redis.go
staticfile.go
template.go
templatefunc.go
templatefunc_test.go
toolbox/task.go
tree.go
tree_test.go
utils/pagination/controller.go
utils/pagination/paginator.go
admin.go
View file @
020bfbc
...
...
@@ -397,7 +397,7 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
if
err
!=
nil
{
data
[
"Message"
]
=
[]
string
{
"error"
,
fmt
.
Sprintf
(
"%s"
,
err
)}
}
data
[
"Message"
]
=
[]
string
{
"success"
,
fmt
.
Sprintf
(
"%s run success,Now the Status is %s"
,
taskname
,
t
.
GetStatus
())}
data
[
"Message"
]
=
[]
string
{
"success"
,
fmt
.
Sprintf
(
"%s run success,Now the Status is
<br>
%s"
,
taskname
,
t
.
GetStatus
())}
}
else
{
data
[
"Message"
]
=
[]
string
{
"warning"
,
fmt
.
Sprintf
(
"there's no task which named: %s"
,
taskname
)}
}
...
...
@@ -410,12 +410,14 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
var
fields
=
[]
string
{
fmt
.
Sprintf
(
"Task Name"
),
fmt
.
Sprintf
(
"Task Spec"
),
fmt
.
Sprintf
(
"Task Function"
),
fmt
.
Sprintf
(
"Task Status"
),
fmt
.
Sprintf
(
"Last Time"
),
fmt
.
Sprintf
(
""
),
}
for
tname
,
tk
:=
range
toolbox
.
AdminTaskList
{
result
=
[]
string
{
fmt
.
Sprintf
(
"%s"
,
tname
),
fmt
.
Sprintf
(
"%s"
,
tk
.
GetSpec
()),
fmt
.
Sprintf
(
"%s"
,
tk
.
GetStatus
()),
fmt
.
Sprintf
(
"%s"
,
tk
.
GetPrev
()
.
String
()),
}
...
...
adminui.go
View file @
020bfbc
...
...
@@ -186,7 +186,7 @@ bg-warning
</td>
{{end}}
<td>
<a class="btn btn-primary btn-sm" href="/task?taskname={{index $slice
1
}}">Run</a>
<a class="btn btn-primary btn-sm" href="/task?taskname={{index $slice
0
}}">Run</a>
</td>
</tr>
{{end}}
...
...
app.go
View file @
020bfbc
...
...
@@ -19,7 +19,10 @@ import (
"net"
"net/http"
"net/http/fcgi"
"os"
"time"
"github.com/astaxie/beego/utils"
)
// App defines beego application with a new PatternServeMux.
...
...
@@ -59,6 +62,10 @@ func (app *App) Run() {
}
}
else
{
if
HttpPort
==
0
{
// remove the Socket file before start
if
utils
.
FileExists
(
addr
)
{
os
.
Remove
(
addr
)
}
l
,
err
=
net
.
Listen
(
"unix"
,
addr
)
}
else
{
l
,
err
=
net
.
Listen
(
"tcp"
,
addr
)
...
...
beego.go
View file @
020bfbc
...
...
@@ -33,83 +33,15 @@ import (
"strconv"
"strings"
"github.com/astaxie/beego/middleware"
"github.com/astaxie/beego/session"
)
// beego web framework version.
const
VERSION
=
"1.4.
2
"
const
VERSION
=
"1.4.
3
"
type
hookfunc
func
()
error
//hook function to run
var
hooks
[]
hookfunc
//hook function slice to store the hookfunc
type
groupRouter
struct
{
pattern
string
controller
ControllerInterface
mappingMethods
string
}
// RouterGroups which will store routers
type
GroupRouters
[]
groupRouter
// Get a new GroupRouters
func
NewGroupRouters
()
GroupRouters
{
return
make
(
GroupRouters
,
0
)
}
// Add Router in the GroupRouters
// it is for plugin or module to register router
func
(
gr
*
GroupRouters
)
AddRouter
(
pattern
string
,
c
ControllerInterface
,
mappingMethod
...
string
)
{
var
newRG
groupRouter
if
len
(
mappingMethod
)
>
0
{
newRG
=
groupRouter
{
pattern
,
c
,
mappingMethod
[
0
],
}
}
else
{
newRG
=
groupRouter
{
pattern
,
c
,
""
,
}
}
*
gr
=
append
(
*
gr
,
newRG
)
}
func
(
gr
*
GroupRouters
)
AddAuto
(
c
ControllerInterface
)
{
newRG
:=
groupRouter
{
""
,
c
,
""
,
}
*
gr
=
append
(
*
gr
,
newRG
)
}
// AddGroupRouter with the prefix
// it will register the router in BeeApp
// the follow code is write in modules:
// GR:=NewGroupRouters()
// GR.AddRouter("/login",&UserController,"get:Login")
// GR.AddRouter("/logout",&UserController,"get:Logout")
// GR.AddRouter("/register",&UserController,"get:Reg")
// the follow code is write in app:
// import "github.com/beego/modules/auth"
// AddRouterGroup("/admin", auth.GR)
func
AddGroupRouter
(
prefix
string
,
groups
GroupRouters
)
*
App
{
for
_
,
v
:=
range
groups
{
if
v
.
pattern
==
""
{
BeeApp
.
Handlers
.
AddAutoPrefix
(
prefix
,
v
.
controller
)
}
else
if
v
.
mappingMethods
!=
""
{
BeeApp
.
Handlers
.
Add
(
prefix
+
v
.
pattern
,
v
.
controller
,
v
.
mappingMethods
)
}
else
{
BeeApp
.
Handlers
.
Add
(
prefix
+
v
.
pattern
,
v
.
controller
)
}
}
return
BeeApp
}
// Router adds a patterned controller handler to BeeApp.
// it's an alias method of App.Router.
// usage:
...
...
@@ -280,15 +212,6 @@ func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
return
BeeApp
}
// ErrorHandler registers http.HandlerFunc to each http err code string.
// usage:
// beego.ErrorHandler("404",NotFound)
// beego.ErrorHandler("500",InternalServerError)
func
Errorhandler
(
err
string
,
h
http
.
HandlerFunc
)
*
App
{
middleware
.
Errorhandler
(
err
,
h
)
return
BeeApp
}
// SetViewsPath sets view directory path in beego application.
func
SetViewsPath
(
path
string
)
*
App
{
ViewsPath
=
path
...
...
@@ -402,9 +325,7 @@ func initBeforeHttpRun() {
}
}
middleware
.
VERSION
=
VERSION
middleware
.
AppName
=
AppName
middleware
.
RegisterErrorHandler
()
registerDefaultErrorHandler
()
if
EnableDocs
{
Get
(
"/docs"
,
serverDocs
)
...
...
cache/cache_test.go
View file @
020bfbc
...
...
@@ -15,6 +15,7 @@
package
cache
import
(
"os"
"testing"
"time"
)
...
...
@@ -67,7 +68,7 @@ func TestCache(t *testing.T) {
}
func
TestFileCache
(
t
*
testing
.
T
)
{
bm
,
err
:=
NewCache
(
"file"
,
`{"CachePath":"
/
cache","FileSuffix":".bin","DirectoryLevel":2,"EmbedExpiry":0}`
)
bm
,
err
:=
NewCache
(
"file"
,
`{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":2,"EmbedExpiry":0}`
)
if
err
!=
nil
{
t
.
Error
(
"init err"
)
}
...
...
@@ -112,4 +113,5 @@ func TestFileCache(t *testing.T) {
if
v
:=
bm
.
Get
(
"astaxie"
);
v
.
(
string
)
!=
"author"
{
t
.
Error
(
"get err"
)
}
os
.
RemoveAll
(
"cache"
)
}
...
...
cache/file.go
View file @
020bfbc
...
...
@@ -92,8 +92,6 @@ func (fc *FileCache) StartAndGC(config string) error {
// Init will make new dir for file cache if not exist.
func
(
fc
*
FileCache
)
Init
()
{
app
:=
filepath
.
Dir
(
os
.
Args
[
0
])
fc
.
CachePath
=
filepath
.
Join
(
app
,
fc
.
CachePath
)
if
ok
,
_
:=
exists
(
fc
.
CachePath
);
!
ok
{
// todo : error handle
_
=
os
.
MkdirAll
(
fc
.
CachePath
,
os
.
ModePerm
)
// todo : error handle
}
...
...
cache/redis/redis.go
View file @
020bfbc
...
...
@@ -32,6 +32,7 @@ package redis
import
(
"encoding/json"
"errors"
"strconv"
"time"
"github.com/garyburd/redigo/redis"
...
...
@@ -48,6 +49,7 @@ var (
type
RedisCache
struct
{
p
*
redis
.
Pool
// redis connection pool
conninfo
string
dbNum
int
key
string
}
...
...
@@ -137,7 +139,7 @@ func (rc *RedisCache) ClearAll() error {
}
// start redis cache adapter.
// config is like {"key":"collection key","conn":"connection info"}
// config is like {"key":"collection key","conn":"connection info"
,"dbNum":"0"
}
// the cache item in redis are stored forever,
// so no gc operation.
func
(
rc
*
RedisCache
)
StartAndGC
(
config
string
)
error
{
...
...
@@ -151,9 +153,12 @@ func (rc *RedisCache) StartAndGC(config string) error {
if
_
,
ok
:=
cf
[
"conn"
];
!
ok
{
return
errors
.
New
(
"config has no conn key"
)
}
if
_
,
ok
:=
cf
[
"dbNum"
];
!
ok
{
cf
[
"dbNum"
]
=
"0"
}
rc
.
key
=
cf
[
"key"
]
rc
.
conninfo
=
cf
[
"conn"
]
rc
.
dbNum
,
_
=
strconv
.
Atoi
(
cf
[
"dbNum"
])
rc
.
connectInit
()
c
:=
rc
.
p
.
Get
()
...
...
@@ -166,6 +171,11 @@ func (rc *RedisCache) StartAndGC(config string) error {
func
(
rc
*
RedisCache
)
connectInit
()
{
dialFunc
:=
func
()
(
c
redis
.
Conn
,
err
error
)
{
c
,
err
=
redis
.
Dial
(
"tcp"
,
rc
.
conninfo
)
_
,
selecterr
:=
c
.
Do
(
"SELECT"
,
rc
.
dbNum
)
if
selecterr
!=
nil
{
c
.
Close
()
return
nil
,
selecterr
}
return
}
// initialize a new pool
...
...
config.go
View file @
020bfbc
...
...
@@ -81,6 +81,7 @@ var (
AppConfigProvider
string
// config provider
EnableDocs
bool
// enable generate docs & server docs API Swagger
RouterCaseSensitive
bool
// router case sensitive default is true
AccessLogs
bool
// print access logs, default is false
)
type
beegoAppConfig
struct
{
...
...
@@ -110,7 +111,7 @@ func (b *beegoAppConfig) String(key string) string {
func
(
b
*
beegoAppConfig
)
Strings
(
key
string
)
[]
string
{
v
:=
b
.
innerConfig
.
Strings
(
RunMode
+
"::"
+
key
)
if
len
(
v
)
==
0
{
if
v
[
0
]
==
""
{
return
b
.
innerConfig
.
Strings
(
key
)
}
return
v
...
...
config/json.go
View file @
020bfbc
...
...
@@ -17,13 +17,10 @@ package config
import
(
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"strings"
"sync"
"time"
)
// JsonConfig is a json config parser and implements Config interface.
...
...
@@ -41,13 +38,19 @@ func (js *JsonConfig) Parse(filename string) (ConfigContainer, error) {
if
err
!=
nil
{
return
nil
,
err
}
return
js
.
ParseData
(
content
)
}
// ParseData returns a ConfigContainer with json string
func
(
js
*
JsonConfig
)
ParseData
(
data
[]
byte
)
(
ConfigContainer
,
error
)
{
x
:=
&
JsonConfigContainer
{
data
:
make
(
map
[
string
]
interface
{}),
}
err
=
json
.
Unmarshal
(
content
,
&
x
.
data
)
err
:=
json
.
Unmarshal
(
data
,
&
x
.
data
)
if
err
!=
nil
{
var
wrappingArray
[]
interface
{}
err2
:=
json
.
Unmarshal
(
content
,
&
wrappingArray
)
err2
:=
json
.
Unmarshal
(
data
,
&
wrappingArray
)
if
err2
!=
nil
{
return
nil
,
err
}
...
...
@@ -56,16 +59,6 @@ func (js *JsonConfig) Parse(filename string) (ConfigContainer, error) {
return
x
,
nil
}
func
(
js
*
JsonConfig
)
ParseData
(
data
[]
byte
)
(
ConfigContainer
,
error
)
{
// Save memory data to temporary file
tmpName
:=
path
.
Join
(
os
.
TempDir
(),
"beego"
,
fmt
.
Sprintf
(
"%d"
,
time
.
Now
()
.
Nanosecond
()))
os
.
MkdirAll
(
path
.
Dir
(
tmpName
),
os
.
ModePerm
)
if
err
:=
ioutil
.
WriteFile
(
tmpName
,
data
,
0655
);
err
!=
nil
{
return
nil
,
err
}
return
js
.
Parse
(
tmpName
)
}
// A Config represents the json configuration.
// Only when get value, support key as section:name type.
type
JsonConfigContainer
struct
{
...
...
@@ -88,11 +81,10 @@ func (c *JsonConfigContainer) Bool(key string) (bool, error) {
// DefaultBool return the bool value if has no error
// otherwise return the defaultval
func
(
c
*
JsonConfigContainer
)
DefaultBool
(
key
string
,
defaultval
bool
)
bool
{
if
v
,
err
:=
c
.
Bool
(
key
);
err
!=
nil
{
return
defaultval
}
else
{
if
v
,
err
:=
c
.
Bool
(
key
);
err
==
nil
{
return
v
}
return
defaultval
}
// Int returns the integer value for a given key.
...
...
@@ -110,11 +102,10 @@ func (c *JsonConfigContainer) Int(key string) (int, error) {
// DefaultInt returns the integer value for a given key.
// if err != nil return defaltval
func
(
c
*
JsonConfigContainer
)
DefaultInt
(
key
string
,
defaultval
int
)
int
{
if
v
,
err
:=
c
.
Int
(
key
);
err
!=
nil
{
return
defaultval
}
else
{
if
v
,
err
:=
c
.
Int
(
key
);
err
==
nil
{
return
v
}
return
defaultval
}
// Int64 returns the int64 value for a given key.
...
...
@@ -132,11 +123,10 @@ func (c *JsonConfigContainer) Int64(key string) (int64, error) {
// DefaultInt64 returns the int64 value for a given key.
// if err != nil return defaltval
func
(
c
*
JsonConfigContainer
)
DefaultInt64
(
key
string
,
defaultval
int64
)
int64
{
if
v
,
err
:=
c
.
Int64
(
key
);
err
!=
nil
{
return
defaultval
}
else
{
if
v
,
err
:=
c
.
Int64
(
key
);
err
==
nil
{
return
v
}
return
defaultval
}
// Float returns the float value for a given key.
...
...
@@ -154,11 +144,10 @@ func (c *JsonConfigContainer) Float(key string) (float64, error) {
// DefaultFloat returns the float64 value for a given key.
// if err != nil return defaltval
func
(
c
*
JsonConfigContainer
)
DefaultFloat
(
key
string
,
defaultval
float64
)
float64
{
if
v
,
err
:=
c
.
Float
(
key
);
err
!=
nil
{
return
defaultval
}
else
{
if
v
,
err
:=
c
.
Float
(
key
);
err
==
nil
{
return
v
}
return
defaultval
}
// String returns the string value for a given key.
...
...
@@ -175,35 +164,37 @@ func (c *JsonConfigContainer) String(key string) string {
// DefaultString returns the string value for a given key.
// if err != nil return defaltval
func
(
c
*
JsonConfigContainer
)
DefaultString
(
key
string
,
defaultval
string
)
string
{
if
v
:=
c
.
String
(
key
);
v
==
""
{
return
defaultval
}
else
{
// TODO FIXME should not use "" to replace non existance
if
v
:=
c
.
String
(
key
);
v
!=
""
{
return
v
}
return
defaultval
}
// Strings returns the []string value for a given key.
func
(
c
*
JsonConfigContainer
)
Strings
(
key
string
)
[]
string
{
stringVal
:=
c
.
String
(
key
)
if
stringVal
==
""
{
return
[]
string
{}
}
return
strings
.
Split
(
c
.
String
(
key
),
";"
)
}
// DefaultStrings returns the []string value for a given key.
// if err != nil return defaltval
func
(
c
*
JsonConfigContainer
)
DefaultStrings
(
key
string
,
defaultval
[]
string
)
[]
string
{
if
v
:=
c
.
Strings
(
key
);
len
(
v
)
==
0
{
return
defaultval
}
else
{
if
v
:=
c
.
Strings
(
key
);
len
(
v
)
>
0
{
return
v
}
return
defaultval
}
// GetSection returns map for the given section
func
(
c
*
JsonConfigContainer
)
GetSection
(
section
string
)
(
map
[
string
]
string
,
error
)
{
if
v
,
ok
:=
c
.
data
[
section
];
ok
{
return
v
.
(
map
[
string
]
string
),
nil
}
else
{
return
nil
,
errors
.
New
(
"not exist setction"
)
}
return
nil
,
errors
.
New
(
"nonexist section "
+
section
)
}
// SaveConfigFile save the config into file
...
...
@@ -222,7 +213,7 @@ func (c *JsonConfigContainer) SaveConfigFile(filename string) (err error) {
return
err
}
//
WriteValue
writes a new value for key.
//
Set
writes a new value for key.
func
(
c
*
JsonConfigContainer
)
Set
(
key
,
val
string
)
error
{
c
.
Lock
()
defer
c
.
Unlock
()
...
...
@@ -241,18 +232,20 @@ func (c *JsonConfigContainer) DIY(key string) (v interface{}, err error) {
// section.key or key
func
(
c
*
JsonConfigContainer
)
getData
(
key
string
)
interface
{}
{
c
.
RLock
()
defer
c
.
RUnlock
()
if
len
(
key
)
==
0
{
return
nil
}
sectionKey
:=
strings
.
Split
(
key
,
"::"
)
if
len
(
sectionKey
)
>=
2
{
curValue
,
ok
:=
c
.
data
[
sectionKey
[
0
]]
c
.
RLock
()
defer
c
.
RUnlock
()
sectionKeys
:=
strings
.
Split
(
key
,
"::"
)
if
len
(
sectionKeys
)
>=
2
{
curValue
,
ok
:=
c
.
data
[
sectionKeys
[
0
]]
if
!
ok
{
return
nil
}
for
_
,
key
:=
range
sectionKey
[
1
:
]
{
for
_
,
key
:=
range
sectionKey
s
[
1
:
]
{
if
v
,
ok
:=
curValue
.
(
map
[
string
]
interface
{});
ok
{
if
curValue
,
ok
=
v
[
key
];
!
ok
{
return
nil
...
...
config/json_test.go
View file @
020bfbc
...
...
@@ -21,6 +21,7 @@ import (
var
jsoncontext
=
`{
"appname": "beeapi",
"testnames": "foo;bar",
"httpport": 8080,
"mysqlport": 3600,
"PI": 3.1415976,
...
...
@@ -28,8 +29,8 @@ var jsoncontext = `{
"autorender": false,
"copyrequestbody": true,
"database": {
"host": "host",
"port": "port",
"host": "host",
"port": "port",
"database": "database",
"username": "username",
"password": "password",
...
...
@@ -122,6 +123,12 @@ func TestJson(t *testing.T) {
if
jsonconf
.
String
(
"runmode"
)
!=
"dev"
{
t
.
Fatal
(
"runmode not equal to dev"
)
}
if
v
:=
jsonconf
.
Strings
(
"unknown"
);
len
(
v
)
>
0
{
t
.
Fatal
(
"unknown strings, the length should be 0"
)
}
if
v
:=
jsonconf
.
Strings
(
"testnames"
);
len
(
v
)
!=
2
{
t
.
Fatal
(
"testnames length should be 2"
)
}
if
v
,
err
:=
jsonconf
.
Bool
(
"autorender"
);
err
!=
nil
||
v
!=
false
{
t
.
Error
(
v
)
t
.
Fatal
(
err
)
...
...
@@ -179,4 +186,8 @@ func TestJson(t *testing.T) {
if
_
,
err
:=
jsonconf
.
Bool
(
"unknown"
);
err
==
nil
{
t
.
Error
(
"unknown keys should return an error when expecting a Bool"
)
}
if
!
jsonconf
.
DefaultBool
(
"unknow"
,
true
)
{
t
.
Error
(
"unknown keys with default value wrong"
)
}
}
...
...
context/context.go
View file @
020bfbc
...
...
@@ -31,7 +31,6 @@ import (
"strings"
"time"
"github.com/astaxie/beego/middleware"
"github.com/astaxie/beego/utils"
)
...
...
@@ -53,24 +52,10 @@ func (ctx *Context) Redirect(status int, localurl string) {
}
// Abort stops this request.
// if middleware.ErrorMaps exists, panic body.
// if middleware.HTTPExceptionMaps exists, panic HTTPException struct with status and body string.
// if beego.ErrorMaps exists, panic body.
func
(
ctx
*
Context
)
Abort
(
status
int
,
body
string
)
{
ctx
.
ResponseWriter
.
WriteHeader
(
status
)
// first panic from ErrorMaps, is is user defined error functions.
if
_
,
ok
:=
middleware
.
ErrorMaps
[
body
];
ok
{
panic
(
body
)
}
// second panic from HTTPExceptionMaps, it is system defined functions.
if
e
,
ok
:=
middleware
.
HTTPExceptionMaps
[
status
];
ok
{
if
len
(
body
)
>=
1
{
e
.
Description
=
body
}
panic
(
e
)
}
// last panic user string
ctx
.
ResponseWriter
.
Write
([]
byte
(
body
))
panic
(
"User stop run"
)
panic
(
body
)
}
// Write string to response body.
...
...
@@ -155,8 +140,11 @@ func (ctx *Context) CheckXsrfCookie() bool {
}
if
token
==
""
{
ctx
.
Abort
(
403
,
"'_xsrf' argument missing from POST"
)
}
else
if
ctx
.
_xsrf_token
!=
token
{
return
false
}
if
ctx
.
_xsrf_token
!=
token
{
ctx
.
Abort
(
403
,
"XSRF cookie does not match POST argument"
)
return
false
}
return
true
}
...
...
context/input.go
View file @
020bfbc
...
...
@@ -27,7 +27,7 @@ import (
"github.com/astaxie/beego/session"
)
// BeegoInput operates the http request header
,data ,
cookie and body.
// BeegoInput operates the http request header
, data,
cookie and body.
// it also contains router params and current session.
type
BeegoInput
struct
{
CruSession
session
.
SessionStore
...
...
@@ -72,11 +72,11 @@ func (input *BeegoInput) Site() string {
func
(
input
*
BeegoInput
)
Scheme
()
string
{
if
input
.
Request
.
URL
.
Scheme
!=
""
{
return
input
.
Request
.
URL
.
Scheme
}
else
if
input
.
Request
.
TLS
==
nil
{
}
if
input
.
Request
.
TLS
==
nil
{
return
"http"
}
else
{
return
"https"
}
return
"https"
}
// Domain returns host name.
...
...
@@ -153,12 +153,12 @@ func (input *BeegoInput) IsSecure() bool {
return
input
.
Scheme
()
==
"https"
}
// Is
Secure
returns boolean of this request is in webSocket.
// Is
Websocket
returns boolean of this request is in webSocket.
func
(
input
*
BeegoInput
)
IsWebsocket
()
bool
{
return
input
.
Header
(
"Upgrade"
)
==
"websocket"
}
// Is
Secure
returns boolean of whether file uploads in this request or not..
// Is
Upload
returns boolean of whether file uploads in this request or not..
func
(
input
*
BeegoInput
)
IsUpload
()
bool
{
return
strings
.
Contains
(
input
.
Header
(
"Content-Type"
),
"multipart/form-data"
)
}
...
...
@@ -189,16 +189,24 @@ func (input *BeegoInput) Proxy() []string {
return
[]
string
{}
}
// Referer returns http referer header.
func
(
input
*
BeegoInput
)
Referer
()
string
{
return
input
.
Header
(
"Referer"
)
}
// Refer returns http referer header.
func
(
input
*
BeegoInput
)
Refer
()
string
{
return
input
.
Header
(
"Referer"
)
return
input
.
Referer
(
)
}
// SubDomains returns sub domain string.
// if aa.bb.domain.com, returns aa.bb .
func
(
input
*
BeegoInput
)
SubDomains
()
string
{
parts
:=
strings
.
Split
(
input
.
Host
(),
"."
)
return
strings
.
Join
(
parts
[
len
(
parts
)
-
2
:
],
"."
)
if
len
(
parts
)
>=
3
{
return
strings
.
Join
(
parts
[
:
len
(
parts
)
-
2
],
"."
)
}
return
""
}
// Port returns request client port.
...
...
@@ -237,6 +245,7 @@ func (input *BeegoInput) Query(key string) string {
}
// Header returns request header item string by a given string.
// if non-existed, return empty string.
func
(
input
*
BeegoInput
)
Header
(
key
string
)
string
{
return
input
.
Request
.
Header
.
Get
(
key
)
}
...
...
@@ -252,11 +261,12 @@ func (input *BeegoInput) Cookie(key string) string {
}
// Session returns current session item value by a given key.
// if non-existed, return empty string.
func
(
input
*
BeegoInput
)
Session
(
key
interface
{})
interface
{}
{
return
input
.
CruSession
.
Get
(
key
)
}
// Body returns the raw request body data as bytes.
//
Copy
Body returns the raw request body data as bytes.
func
(
input
*
BeegoInput
)
CopyBody
()
[]
byte
{
requestbody
,
_
:=
ioutil
.
ReadAll
(
input
.
Request
.
Body
)
input
.
Request
.
Body
.
Close
()
...
...
context/input_test.go
View file @
020bfbc
...
...
@@ -70,3 +70,45 @@ func TestParse(t *testing.T) {
}
fmt
.
Println
(
user
)
}
func
TestSubDomain
(
t
*
testing
.
T
)
{
r
,
_
:=
http
.
NewRequest
(
"GET"
,
"http://www.example.com/?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&user.Name=astaxie"
,
nil
)
beegoInput
:=
NewInput
(
r
)
subdomain
:=
beegoInput
.
SubDomains
()
if
subdomain
!=
"www"
{
t
.
Fatal
(
"Subdomain parse error, got"
+
subdomain
)
}
r
,
_
=
http
.
NewRequest
(
"GET"
,
"http://localhost/"
,
nil
)
beegoInput
.
Request
=
r
if
beegoInput
.
SubDomains
()
!=
""
{
t
.
Fatal
(
"Subdomain parse error, should be empty, got "
+
beegoInput
.
SubDomains
())
}
r
,
_
=
http
.
NewRequest
(
"GET"
,
"http://aa.bb.example.com/"
,
nil
)
beegoInput
.
Request
=
r
if
beegoInput
.
SubDomains
()
!=
"aa.bb"
{
t
.
Fatal
(
"Subdomain parse error, got "
+
beegoInput
.
SubDomains
())
}
/* TODO Fix this
r, _ = http.NewRequest("GET", "http://127.0.0.1/", nil)
beegoInput.Request = r
if beegoInput.SubDomains() != "" {
t.Fatal("Subdomain parse error, got " + beegoInput.SubDomains())
}
*/
r
,
_
=
http
.
NewRequest
(
"GET"
,
"http://example.com/"
,
nil
)
beegoInput
.
Request
=
r
if
beegoInput
.
SubDomains
()
!=
""
{
t
.
Fatal
(
"Subdomain parse error, got "
+
beegoInput
.
SubDomains
())
}
r
,
_
=
http
.
NewRequest
(
"GET"
,
"http://aa.bb.cc.dd.example.com/"
,
nil
)
beegoInput
.
Request
=
r
if
beegoInput
.
SubDomains
()
!=
"aa.bb.cc.dd"
{
t
.
Fatal
(
"Subdomain parse error, got "
+
beegoInput
.
SubDomains
())
}
}
...
...
context/output.go
View file @
020bfbc
...
...
@@ -188,7 +188,7 @@ func sanitizeValue(v string) string {
// Json writes json to response body.
// if coding is true, it converts utf-8 to \u0000 type.
func
(
output
*
BeegoOutput
)
Json
(
data
interface
{},
hasIndent
bool
,
coding
bool
)
error
{
output
.
Header
(
"Content-Type"
,
"application/json;
charset=UTF
-8"
)
output
.
Header
(
"Content-Type"
,
"application/json;
charset=utf
-8"
)
var
content
[]
byte
var
err
error
if
hasIndent
{
...
...
@@ -209,7 +209,7 @@ func (output *BeegoOutput) Json(data interface{}, hasIndent bool, coding bool) e
// Jsonp writes jsonp to response body.
func
(
output
*
BeegoOutput
)
Jsonp
(
data
interface
{},
hasIndent
bool
)
error
{
output
.
Header
(
"Content-Type"
,
"application/javascript;
charset=UTF
-8"
)
output
.
Header
(
"Content-Type"
,
"application/javascript;
charset=utf
-8"
)
var
content
[]
byte
var
err
error
if
hasIndent
{
...
...
@@ -235,7 +235,7 @@ func (output *BeegoOutput) Jsonp(data interface{}, hasIndent bool) error {
// Xml writes xml string to response body.
func
(
output
*
BeegoOutput
)
Xml
(
data
interface
{},
hasIndent
bool
)
error
{
output
.
Header
(
"Content-Type"
,
"application/xml;
charset=UTF
-8"
)
output
.
Header
(
"Content-Type"
,
"application/xml;
charset=utf
-8"
)
var
content
[]
byte
var
err
error
if
hasIndent
{
...
...
controller.go
View file @
020bfbc
...
...
@@ -270,16 +270,22 @@ func (c *Controller) Redirect(url string, code int) {
// Aborts stops controller handler and show the error data if code is defined in ErrorMap or code string.
func
(
c
*
Controller
)
Abort
(
code
string
)
{
status
,
err
:=
strconv
.
Atoi
(
code
)
if
err
==
nil
{
c
.
Ctx
.
Abort
(
status
,
code
)
}
else
{
c
.
Ctx
.
Abort
(
200
,
code
)
if
err
!=
nil
{
status
=
200
}
c
.
CustomAbort
(
status
,
code
)
}
// CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
func
(
c
*
Controller
)
CustomAbort
(
status
int
,
body
string
)
{
c
.
Ctx
.
Abort
(
status
,
body
)
c
.
Ctx
.
ResponseWriter
.
WriteHeader
(
status
)
// first panic from ErrorMaps, is is user defined error functions.
if
_
,
ok
:=
ErrorMaps
[
body
];
ok
{
panic
(
body
)
}
// last panic user string
c
.
Ctx
.
ResponseWriter
.
Write
([]
byte
(
body
))
panic
(
USERSTOPRUN
)
}
// StopRun makes panic of USERSTOPRUN error and go to recover function if defined.
...
...
@@ -289,7 +295,7 @@ func (c *Controller) StopRun() {
// UrlFor does another controller handler in this request function.
// it goes to this controller method if endpoint is not clear.
func
(
c
*
Controller
)
UrlFor
(
endpoint
string
,
values
...
string
)
string
{
func
(
c
*
Controller
)
UrlFor
(
endpoint
string
,
values
...
interface
{}
)
string
{
if
len
(
endpoint
)
<=
0
{
return
""
}
...
...
@@ -363,67 +369,144 @@ func (c *Controller) ParseForm(obj interface{}) error {
return
ParseForm
(
c
.
Input
(),
obj
)
}
// GetString returns the input value by key string.
func
(
c
*
Controller
)
GetString
(
key
string
)
string
{
return
c
.
Ctx
.
Input
.
Query
(
key
)
// GetString returns the input value by key string or the default value while it's present and input is blank
func
(
c
*
Controller
)
GetString
(
key
string
,
def
...
string
)
string
{
var
defv
string
if
len
(
def
)
>
0
{
defv
=
def
[
0
]
}
if
v
:=
c
.
Ctx
.
Input
.
Query
(
key
);
v
!=
""
{
return
v
}
else
{
return
defv
}
}
// GetStrings returns the input string slice by key string
.
// GetStrings returns the input string slice by key string
or the default value while it's present and input is blank
// it's designed for multi-value input field such as checkbox(input[type=checkbox]), multi-selection.
func
(
c
*
Controller
)
GetStrings
(
key
string
)
[]
string
{
func
(
c
*
Controller
)
GetStrings
(
key
string
,
def
...
[]
string
)
[]
string
{
var
defv
[]
string
if
len
(
def
)
>
0
{
defv
=
def
[
0
]
}
f
:=
c
.
Input
()
if
f
==
nil
{
return
[]
string
{}
return
defv
}
vs
:=
f
[
key
]
if
len
(
vs
)
>
0
{
return
vs
}
else
{
return
defv
}
return
[]
string
{}
}
// GetInt returns input as an int
func
(
c
*
Controller
)
GetInt
(
key
string
)
(
int
,
error
)
{
return
strconv
.
Atoi
(
c
.
Ctx
.
Input
.
Query
(
key
))
// GetInt returns input as an int or the default value while it's present and input is blank
func
(
c
*
Controller
)
GetInt
(
key
string
,
def
...
int
)
(
int
,
error
)
{
var
defv
int
if
len
(
def
)
>
0
{
defv
=
def
[
0
]
}
if
strv
:=
c
.
Ctx
.
Input
.
Query
(
key
);
strv
!=
""
{
return
strconv
.
Atoi
(
strv
)
}
else
{
return
defv
,
nil
}
}
// GetInt8 return input as an int8
func
(
c
*
Controller
)
GetInt8
(
key
string
)
(
int8
,
error
)
{
i64
,
err
:=
strconv
.
ParseInt
(
c
.
Ctx
.
Input
.
Query
(
key
),
10
,
8
)
i8
:=
int8
(
i64
)
// GetInt8 return input as an int8 or the default value while it's present and input is blank
func
(
c
*
Controller
)
GetInt8
(
key
string
,
def
...
int8
)
(
int8
,
error
)
{
var
defv
int8
if
len
(
def
)
>
0
{
defv
=
def
[
0
]
}
return
i8
,
err
if
strv
:=
c
.
Ctx
.
Input
.
Query
(
key
);
strv
!=
""
{
i64
,
err
:=
strconv
.
ParseInt
(
strv
,
10
,
8
)
i8
:=
int8
(
i64
)
return
i8
,
err
}
else
{
return
defv
,
nil
}
}
// GetInt16 returns input as an int16
func
(
c
*
Controller
)
GetInt16
(
key
string
)
(
int16
,
error
)
{
i64
,
err
:=
strconv
.
ParseInt
(
c
.
Ctx
.
Input
.
Query
(
key
),
10
,
16
)
i16
:=
int16
(
i64
)
// GetInt16 returns input as an int16 or the default value while it's present and input is blank
func
(
c
*
Controller
)
GetInt16
(
key
string
,
def
...
int16
)
(
int16
,
error
)
{
var
defv
int16
if
len
(
def
)
>
0
{
defv
=
def
[
0
]
}
if
strv
:=
c
.
Ctx
.
Input
.
Query
(
key
);
strv
!=
""
{
i64
,
err
:=
strconv
.
ParseInt
(
strv
,
10
,
16
)
i16
:=
int16
(
i64
)
return
i16
,
err
return
i16
,
err
}
else
{
return
defv
,
nil
}
}
// GetInt32 returns input as an int32
func
(
c
*
Controller
)
GetInt32
(
key
string
)
(
int32
,
error
)
{
i64
,
err
:=
strconv
.
ParseInt
(
c
.
Ctx
.
Input
.
Query
(
key
),
10
,
32
)
i32
:=
int32
(
i64
)
// GetInt32 returns input as an int32 or the default value while it's present and input is blank
func
(
c
*
Controller
)
GetInt32
(
key
string
,
def
...
int32
)
(
int32
,
error
)
{
var
defv
int32
if
len
(
def
)
>
0
{
defv
=
def
[
0
]
}
return
i32
,
err
if
strv
:=
c
.
Ctx
.
Input
.
Query
(
key
);
strv
!=
""
{
i64
,
err
:=
strconv
.
ParseInt
(
c
.
Ctx
.
Input
.
Query
(
key
),
10
,
32
)
i32
:=
int32
(
i64
)
return
i32
,
err
}
else
{
return
defv
,
nil
}
}
// GetInt64 returns input value as int64.
func
(
c
*
Controller
)
GetInt64
(
key
string
)
(
int64
,
error
)
{
return
strconv
.
ParseInt
(
c
.
Ctx
.
Input
.
Query
(
key
),
10
,
64
)
// GetInt64 returns input value as int64 or the default value while it's present and input is blank.
func
(
c
*
Controller
)
GetInt64
(
key
string
,
def
...
int64
)
(
int64
,
error
)
{
var
defv
int64
if
len
(
def
)
>
0
{
defv
=
def
[
0
]
}
if
strv
:=
c
.
Ctx
.
Input
.
Query
(
key
);
strv
!=
""
{
return
strconv
.
ParseInt
(
strv
,
10
,
64
)
}
else
{
return
defv
,
nil
}
}
// GetBool returns input value as bool.
func
(
c
*
Controller
)
GetBool
(
key
string
)
(
bool
,
error
)
{
return
strconv
.
ParseBool
(
c
.
Ctx
.
Input
.
Query
(
key
))
// GetBool returns input value as bool or the default value while it's present and input is blank.
func
(
c
*
Controller
)
GetBool
(
key
string
,
def
...
bool
)
(
bool
,
error
)
{
var
defv
bool
if
len
(
def
)
>
0
{
defv
=
def
[
0
]
}
if
strv
:=
c
.
Ctx
.
Input
.
Query
(
key
);
strv
!=
""
{
return
strconv
.
ParseBool
(
strv
)
}
else
{
return
defv
,
nil
}
}
// GetFloat returns input value as float64.
func
(
c
*
Controller
)
GetFloat
(
key
string
)
(
float64
,
error
)
{
return
strconv
.
ParseFloat
(
c
.
Ctx
.
Input
.
Query
(
key
),
64
)
// GetFloat returns input value as float64 or the default value while it's present and input is blank.
func
(
c
*
Controller
)
GetFloat
(
key
string
,
def
...
float64
)
(
float64
,
error
)
{
var
defv
float64
if
len
(
def
)
>
0
{
defv
=
def
[
0
]
}
if
strv
:=
c
.
Ctx
.
Input
.
Query
(
key
);
strv
!=
""
{
return
strconv
.
ParseFloat
(
c
.
Ctx
.
Input
.
Query
(
key
),
64
)
}
else
{
return
defv
,
nil
}
}
// GetFile returns the file data in file upload field named as key.
...
...
middleware/
error.go
→
error.go
View file @
020bfbc
This diff is collapsed.
Click to expand it.
httplib/httplib.go
View file @
020bfbc
...
...
@@ -253,30 +253,20 @@ func (b *BeegoHttpRequest) Body(data interface{}) *BeegoHttpRequest {
return
b
}
func
(
b
*
BeegoHttpRequest
)
getResponse
()
(
*
http
.
Response
,
error
)
{
if
b
.
resp
.
StatusCode
!=
0
{
return
b
.
resp
,
nil
}
var
paramBody
string
if
len
(
b
.
params
)
>
0
{
var
buf
bytes
.
Buffer
for
k
,
v
:=
range
b
.
params
{
buf
.
WriteString
(
url
.
QueryEscape
(
k
))
buf
.
WriteByte
(
'='
)
buf
.
WriteString
(
url
.
QueryEscape
(
v
))
buf
.
WriteByte
(
'&'
)
}
paramBody
=
buf
.
String
()
paramBody
=
paramBody
[
0
:
len
(
paramBody
)
-
1
]
}
func
(
b
*
BeegoHttpRequest
)
buildUrl
(
paramBody
string
)
{
// build GET url with query string
if
b
.
req
.
Method
==
"GET"
&&
len
(
paramBody
)
>
0
{
if
strings
.
Index
(
b
.
url
,
"?"
)
!=
-
1
{
b
.
url
+=
"&"
+
paramBody
}
else
{
b
.
url
=
b
.
url
+
"?"
+
paramBody
}
}
else
if
b
.
req
.
Method
==
"POST"
&&
b
.
req
.
Body
==
nil
{
return
}
// build POST url and body
if
b
.
req
.
Method
==
"POST"
&&
b
.
req
.
Body
==
nil
{
// with files
if
len
(
b
.
files
)
>
0
{
pr
,
pw
:=
io
.
Pipe
()
bodyWriter
:=
multipart
.
NewWriter
(
pw
)
...
...
@@ -305,12 +295,35 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) {
}()
b
.
Header
(
"Content-Type"
,
bodyWriter
.
FormDataContentType
())
b
.
req
.
Body
=
ioutil
.
NopCloser
(
pr
)
}
else
if
len
(
paramBody
)
>
0
{
return
}
// with params
if
len
(
paramBody
)
>
0
{
b
.
Header
(
"Content-Type"
,
"application/x-www-form-urlencoded"
)
b
.
Body
(
paramBody
)
}
}
}
func
(
b
*
BeegoHttpRequest
)
getResponse
()
(
*
http
.
Response
,
error
)
{
if
b
.
resp
.
StatusCode
!=
0
{
return
b
.
resp
,
nil
}
var
paramBody
string
if
len
(
b
.
params
)
>
0
{
var
buf
bytes
.
Buffer
for
k
,
v
:=
range
b
.
params
{
buf
.
WriteString
(
url
.
QueryEscape
(
k
))
buf
.
WriteByte
(
'='
)
buf
.
WriteString
(
url
.
QueryEscape
(
v
))
buf
.
WriteByte
(
'&'
)
}
paramBody
=
buf
.
String
()
paramBody
=
paramBody
[
0
:
len
(
paramBody
)
-
1
]
}
b
.
buildUrl
(
paramBody
)
url
,
err
:=
url
.
Parse
(
b
.
url
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -342,14 +355,12 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) {
}
}
var
jar
http
.
CookieJar
var
jar
http
.
CookieJar
=
nil
if
b
.
setting
.
EnableCookie
{
if
defaultCookieJar
==
nil
{
createDefaultCookie
()
}
jar
=
defaultCookieJar
}
else
{
jar
=
nil
}
client
:=
&
http
.
Client
{
...
...
@@ -402,12 +413,11 @@ func (b *BeegoHttpRequest) Bytes() ([]byte, error) {
return
nil
,
nil
}
defer
resp
.
Body
.
Close
()
data
,
err
:
=
ioutil
.
ReadAll
(
resp
.
Body
)
b
.
body
,
err
=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
nil
,
err
}
b
.
body
=
data
return
data
,
nil
return
b
.
body
,
nil
}
// ToFile saves the body data in response to one file.
...
...
@@ -438,8 +448,7 @@ func (b *BeegoHttpRequest) ToJson(v interface{}) error {
if
err
!=
nil
{
return
err
}
err
=
json
.
Unmarshal
(
data
,
v
)
return
err
return
json
.
Unmarshal
(
data
,
v
)
}
// ToXml returns the map that marshals from the body bytes as xml in response .
...
...
@@ -449,8 +458,7 @@ func (b *BeegoHttpRequest) ToXml(v interface{}) error {
if
err
!=
nil
{
return
err
}
err
=
xml
.
Unmarshal
(
data
,
v
)
return
err
return
xml
.
Unmarshal
(
data
,
v
)
}
// Response executes request client gets response mannually.
...
...
logs/conn.go
View file @
020bfbc
...
...
@@ -43,11 +43,7 @@ func NewConn() LoggerInterface {
// init connection writer with json config.
// json config only need key "level".
func
(
c
*
ConnWriter
)
Init
(
jsonconfig
string
)
error
{
err
:=
json
.
Unmarshal
([]
byte
(
jsonconfig
),
c
)
if
err
!=
nil
{
return
err
}
return
nil
return
json
.
Unmarshal
([]
byte
(
jsonconfig
),
c
)
}
// write message in connection.
...
...
@@ -77,10 +73,9 @@ func (c *ConnWriter) Flush() {
// destroy connection writer and close tcp listener.
func
(
c
*
ConnWriter
)
Destroy
()
{
if
c
.
innerWriter
=
=
nil
{
return
if
c
.
innerWriter
!
=
nil
{
c
.
innerWriter
.
Close
()
}
c
.
innerWriter
.
Close
()
}
func
(
c
*
ConnWriter
)
connect
()
error
{
...
...
logs/console.go
View file @
020bfbc
...
...
@@ -50,9 +50,10 @@ type ConsoleWriter struct {
// create ConsoleWriter returning as LoggerInterface.
func
NewConsole
()
LoggerInterface
{
cw
:=
new
(
ConsoleWriter
)
cw
.
lg
=
log
.
New
(
os
.
Stdout
,
""
,
log
.
Ldate
|
log
.
Ltime
)
cw
.
Level
=
LevelDebug
cw
:=
&
ConsoleWriter
{
lg
:
log
.
New
(
os
.
Stdout
,
""
,
log
.
Ldate
|
log
.
Ltime
),
Level
:
LevelDebug
,
}
return
cw
}
...
...
@@ -62,11 +63,7 @@ func (c *ConsoleWriter) Init(jsonconfig string) error {
if
len
(
jsonconfig
)
==
0
{
return
nil
}
err
:=
json
.
Unmarshal
([]
byte
(
jsonconfig
),
c
)
if
err
!=
nil
{
return
err
}
return
nil
return
json
.
Unmarshal
([]
byte
(
jsonconfig
),
c
)
}
// write message in console.
...
...
@@ -76,9 +73,10 @@ func (c *ConsoleWriter) WriteMsg(msg string, level int) error {
}
if
goos
:=
runtime
.
GOOS
;
goos
==
"windows"
{
c
.
lg
.
Println
(
msg
)
}
else
{
c
.
lg
.
Println
(
colors
[
level
](
msg
))
return
nil
}
c
.
lg
.
Println
(
colors
[
level
](
msg
))
return
nil
}
...
...
logs/file.go
View file @
020bfbc
...
...
@@ -15,10 +15,11 @@
package
logs
import
(
"bytes"
"encoding/json"
"errors"
"fmt"
"io
/ioutil
"
"io"
"log"
"os"
"path/filepath"
...
...
@@ -122,11 +123,7 @@ func (w *FileLogWriter) startLogger() error {
return
err
}
w
.
mw
.
SetFd
(
fd
)
err
=
w
.
initFd
()
if
err
!=
nil
{
return
err
}
return
nil
return
w
.
initFd
()
}
func
(
w
*
FileLogWriter
)
docheck
(
size
int
)
{
...
...
@@ -169,18 +166,44 @@ func (w *FileLogWriter) initFd() error {
}
w
.
maxsize_cursize
=
int
(
finfo
.
Size
())
w
.
daily_opendate
=
time
.
Now
()
.
Day
()
w
.
maxlines_curlines
=
0
if
finfo
.
Size
()
>
0
{
co
ntent
,
err
:=
ioutil
.
ReadFile
(
w
.
Filename
)
co
unt
,
err
:=
w
.
lines
(
)
if
err
!=
nil
{
return
err
}
w
.
maxlines_curlines
=
len
(
strings
.
Split
(
string
(
content
),
"
\n
"
))
}
else
{
w
.
maxlines_curlines
=
0
w
.
maxlines_curlines
=
count
}
return
nil
}
func
(
w
*
FileLogWriter
)
lines
()
(
int
,
error
)
{
fd
,
err
:=
os
.
Open
(
w
.
Filename
)
if
err
!=
nil
{
return
0
,
err
}
defer
fd
.
Close
()
buf
:=
make
([]
byte
,
32768
)
// 32k
count
:=
0
lineSep
:=
[]
byte
{
'\n'
}
for
{
c
,
err
:=
fd
.
Read
(
buf
)
if
err
!=
nil
&&
err
!=
io
.
EOF
{
return
count
,
err
}
count
+=
bytes
.
Count
(
buf
[
:
c
],
lineSep
)
if
err
==
io
.
EOF
{
break
}
}
return
count
,
nil
}
// DoRotate means it need to write file in new file.
// new file name like xx.log.2013-01-01.2
func
(
w
*
FileLogWriter
)
DoRotate
()
error
{
...
...
logs/log.go
View file @
020bfbc
...
...
@@ -292,9 +292,9 @@ func (bl *BeeLogger) Close() {
fmt
.
Println
(
"ERROR, unable to WriteMsg (while closing logger):"
,
err
)
}
}
}
else
{
break
continue
}
break
}
for
_
,
l
:=
range
bl
.
outputs
{
l
.
Flush
()
...
...
logs/smtp.go
View file @
020bfbc
...
...
@@ -25,7 +25,8 @@ import (
)
const
(
subjectPhrase
=
"Diagnostic message from server"
// no usage
// subjectPhrase = "Diagnostic message from server"
)
// smtpWriter implements LoggerInterface and is used to send emails via given SMTP-server.
...
...
@@ -146,9 +147,7 @@ func (s *SmtpWriter) WriteMsg(msg string, level int) error {
mailmsg
:=
[]
byte
(
"To: "
+
strings
.
Join
(
s
.
RecipientAddresses
,
";"
)
+
"
\r\n
From: "
+
s
.
FromAddress
+
"<"
+
s
.
FromAddress
+
">
\r\n
Subject: "
+
s
.
Subject
+
"
\r\n
"
+
content_type
+
"
\r\n\r\n
"
+
fmt
.
Sprintf
(
".%s"
,
time
.
Now
()
.
Format
(
"2006-01-02 15:04:05"
))
+
msg
)
err
:=
s
.
sendMail
(
s
.
Host
,
auth
,
s
.
FromAddress
,
s
.
RecipientAddresses
,
mailmsg
)
return
err
return
s
.
sendMail
(
s
.
Host
,
auth
,
s
.
FromAddress
,
s
.
RecipientAddresses
,
mailmsg
)
}
// implementing method. empty.
...
...
middleware/exceptions.go
deleted
100644 → 0
View file @
d536f5b
// Copyright 2014 beego Author. All Rights Reserved.
//
// 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
middleware
import
"fmt"
// http exceptions
type
HTTPException
struct
{
StatusCode
int
// http status code 4xx, 5xx
Description
string
}
// return http exception error string, e.g. "400 Bad Request".
func
(
e
*
HTTPException
)
Error
()
string
{
return
fmt
.
Sprintf
(
"%d %s"
,
e
.
StatusCode
,
e
.
Description
)
}
// map of http exceptions for each http status code int.
// defined 400,401,403,404,405,500,502,503 and 504 default.
var
HTTPExceptionMaps
map
[
int
]
HTTPException
func
init
()
{
HTTPExceptionMaps
=
make
(
map
[
int
]
HTTPException
)
// Normal 4XX HTTP Status
HTTPExceptionMaps
[
400
]
=
HTTPException
{
400
,
"Bad Request"
}
HTTPExceptionMaps
[
401
]
=
HTTPException
{
401
,
"Unauthorized"
}
HTTPExceptionMaps
[
403
]
=
HTTPException
{
403
,
"Forbidden"
}
HTTPExceptionMaps
[
404
]
=
HTTPException
{
404
,
"Not Found"
}
HTTPExceptionMaps
[
405
]
=
HTTPException
{
405
,
"Method Not Allowed"
}
// Normal 5XX HTTP Status
HTTPExceptionMaps
[
500
]
=
HTTPException
{
500
,
"Internal Server Error"
}
HTTPExceptionMaps
[
502
]
=
HTTPException
{
502
,
"Bad Gateway"
}
HTTPExceptionMaps
[
503
]
=
HTTPException
{
503
,
"Service Unavailable"
}
HTTPExceptionMaps
[
504
]
=
HTTPException
{
504
,
"Gateway Timeout"
}
}
middleware/i18n.go
View file @
020bfbc
...
...
@@ -34,7 +34,6 @@ type Translation struct {
}
func
NewLocale
(
filepath
string
,
defaultlocal
string
)
*
Translation
{
i18n
:=
make
(
map
[
string
]
map
[
string
]
string
)
file
,
err
:=
os
.
Open
(
filepath
)
if
err
!=
nil
{
panic
(
"open "
+
filepath
+
" err :"
+
err
.
Error
())
...
...
@@ -43,8 +42,9 @@ func NewLocale(filepath string, defaultlocal string) *Translation {
if
err
!=
nil
{
panic
(
"read "
+
filepath
+
" err :"
+
err
.
Error
())
}
err
=
json
.
Unmarshal
(
data
,
&
i18n
)
if
err
!=
nil
{
i18n
:=
make
(
map
[
string
]
map
[
string
]
string
)
if
err
=
json
.
Unmarshal
(
data
,
&
i18n
);
err
!=
nil
{
panic
(
"json.Unmarshal "
+
filepath
+
" err :"
+
err
.
Error
())
}
return
&
Translation
{
...
...
namespace.go
View file @
020bfbc
...
...
@@ -19,7 +19,6 @@ import (
"strings"
beecontext
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/middleware"
)
type
namespaceCond
func
(
*
beecontext
.
Context
)
bool
...
...
@@ -57,7 +56,7 @@ func NewNamespace(prefix string, params ...innnerNamespace) *Namespace {
func
(
n
*
Namespace
)
Cond
(
cond
namespaceCond
)
*
Namespace
{
fn
:=
func
(
ctx
*
beecontext
.
Context
)
{
if
!
cond
(
ctx
)
{
middleware
.
Exception
(
"405"
,
ctx
.
ResponseWriter
,
ctx
.
Request
,
"Method not allowed"
)
exception
(
"405"
,
ctx
)
}
}
if
v
,
ok
:=
n
.
handlers
.
filters
[
BeforeRouter
];
ok
{
...
...
orm/cmd_utils.go
View file @
020bfbc
...
...
@@ -104,7 +104,11 @@ func getColumnAddQuery(al *alias, fi *fieldInfo) string {
typ
+=
" "
+
"NOT NULL"
}
return
fmt
.
Sprintf
(
"ALTER TABLE %s%s%s ADD COLUMN %s%s%s %s"
,
Q
,
fi
.
mi
.
table
,
Q
,
Q
,
fi
.
column
,
Q
,
typ
)
return
fmt
.
Sprintf
(
"ALTER TABLE %s%s%s ADD COLUMN %s%s%s %s %s"
,
Q
,
fi
.
mi
.
table
,
Q
,
Q
,
fi
.
column
,
Q
,
typ
,
getColumnDefault
(
fi
),
)
}
// create database creation string.
...
...
@@ -155,6 +159,9 @@ func getDbCreateSql(al *alias) (sqls []string, tableIndexes map[string][]dbIndex
//if fi.initial.String() != "" {
// column += " DEFAULT " + fi.initial.String()
//}
// Append attribute DEFAULT
column
+=
getColumnDefault
(
fi
)
if
fi
.
unique
{
column
+=
" "
+
"UNIQUE"
...
...
@@ -239,3 +246,44 @@ func getDbCreateSql(al *alias) (sqls []string, tableIndexes map[string][]dbIndex
return
}
// Get string value for the attribute "DEFAULT" for the CREATE, ALTER commands
func
getColumnDefault
(
fi
*
fieldInfo
)
string
{
var
(
v
,
t
,
d
string
)
// Skip default attribute if field is in relations
if
fi
.
rel
||
fi
.
reverse
{
return
v
}
t
=
" DEFAULT '%s' "
// These defaults will be useful if there no config value orm:"default" and NOT NULL is on
switch
fi
.
fieldType
{
case
TypeDateField
,
TypeDateTimeField
:
return
v
;
case
TypeBooleanField
,
TypeBitField
,
TypeSmallIntegerField
,
TypeIntegerField
,
TypeBigIntegerField
,
TypePositiveBitField
,
TypePositiveSmallIntegerField
,
TypePositiveIntegerField
,
TypePositiveBigIntegerField
,
TypeFloatField
,
TypeDecimalField
:
d
=
"0"
}
if
fi
.
colDefault
{
if
!
fi
.
initial
.
Exist
()
{
v
=
fmt
.
Sprintf
(
t
,
""
)
}
else
{
v
=
fmt
.
Sprintf
(
t
,
fi
.
initial
.
String
())
}
}
else
{
if
!
fi
.
null
{
v
=
fmt
.
Sprintf
(
t
,
d
)
}
}
return
v
}
...
...
orm/models_info_f.go
View file @
020bfbc
...
...
@@ -116,6 +116,7 @@ type fieldInfo struct {
null
bool
index
bool
unique
bool
colDefault
bool
initial
StrTo
size
int
auto_now
bool
...
...
@@ -280,6 +281,11 @@ checkType:
fi
.
pk
=
attrs
[
"pk"
]
fi
.
unique
=
attrs
[
"unique"
]
// Mark object property if there is attribute "default" in the orm configuration
if
_
,
ok
:=
tags
[
"default"
];
ok
{
fi
.
colDefault
=
true
}
switch
fieldType
{
case
RelManyToMany
,
RelReverseMany
,
RelReverseOne
:
fi
.
null
=
false
...
...
orm/orm.go
View file @
020bfbc
...
...
@@ -489,10 +489,6 @@ func (o *orm) Driver() Driver {
return
driver
(
o
.
alias
.
Name
)
}
func
(
o
*
orm
)
GetDB
()
dbQuerier
{
panic
(
ErrNotImplement
)
}
// create new orm
func
NewOrm
()
Ormer
{
BootStrap
()
// execute only once
...
...
orm/types.go
View file @
020bfbc
...
...
@@ -51,7 +51,6 @@ type Ormer interface {
Rollback
()
error
Raw
(
string
,
...
interface
{})
RawSeter
Driver
()
Driver
GetDB
()
dbQuerier
}
// insert prepared statement
...
...
parser.go
View file @
020bfbc
...
...
@@ -57,7 +57,7 @@ func parserPkg(pkgRealpath, pkgpath string) error {
rep
:=
strings
.
NewReplacer
(
"/"
,
"_"
,
"."
,
"_"
)
commentFilename
=
COMMENTFL
+
rep
.
Replace
(
pkgpath
)
+
".go"
if
!
compareFile
(
pkgRealpath
)
{
Info
(
pkgRealpath
+
"
don't has updated
"
)
Info
(
pkgRealpath
+
"
has not changed, not reloading
"
)
return
nil
}
genInfoList
=
make
(
map
[
string
][]
ControllerComments
)
...
...
plugins/cors/cors.go
View file @
020bfbc
...
...
@@ -217,6 +217,7 @@ func Allow(opts *Options) beego.FilterFunc {
ctx
.
Output
.
Header
(
key
,
value
)
}
ctx
.
Output
.
SetStatus
(
http
.
StatusOK
)
ctx
.
WriteString
(
""
)
return
}
headers
=
opts
.
Header
(
origin
)
...
...
router.go
View file @
020bfbc
...
...
@@ -30,7 +30,6 @@ import (
"time"
beecontext
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/middleware"
"github.com/astaxie/beego/toolbox"
"github.com/astaxie/beego/utils"
)
...
...
@@ -153,7 +152,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM
if
val
:=
reflectVal
.
MethodByName
(
colon
[
1
]);
val
.
IsValid
()
{
methods
[
strings
.
ToUpper
(
m
)]
=
colon
[
1
]
}
else
{
panic
(
colon
[
1
]
+
"
method doesn't exist in the controller "
+
t
.
Name
())
panic
(
"'"
+
colon
[
1
]
+
"'
method doesn't exist in the controller "
+
t
.
Name
())
}
}
else
{
panic
(
v
+
" is an invalid method mapping. Method doesn't exist "
+
m
)
...
...
@@ -429,7 +428,7 @@ func (p *ControllerRegistor) insertFilterRouter(pos int, mr *FilterRouter) error
// UrlFor does another controller handler in this request function.
// it can access any controller method.
func
(
p
*
ControllerRegistor
)
UrlFor
(
endpoint
string
,
values
...
string
)
string
{
func
(
p
*
ControllerRegistor
)
UrlFor
(
endpoint
string
,
values
...
interface
{}
)
string
{
paths
:=
strings
.
Split
(
endpoint
,
"."
)
if
len
(
paths
)
<=
1
{
Warn
(
"urlfor endpoint must like path.controller.method"
)
...
...
@@ -444,9 +443,9 @@ func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string {
key
:=
""
for
k
,
v
:=
range
values
{
if
k
%
2
==
0
{
key
=
v
key
=
fmt
.
Sprint
(
v
)
}
else
{
params
[
key
]
=
v
params
[
key
]
=
fmt
.
Sprint
(
v
)
}
}
}
...
...
@@ -577,7 +576,6 @@ func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName strin
// Implement http.Handler interface.
func
(
p
*
ControllerRegistor
)
ServeHTTP
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
defer
p
.
recoverPanic
(
rw
,
r
)
starttime
:=
time
.
Now
()
var
runrouter
reflect
.
Type
var
findrouter
bool
...
...
@@ -600,6 +598,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
context
.
Output
.
Context
=
context
context
.
Output
.
EnableGzip
=
EnableGzip
defer
p
.
recoverPanic
(
context
)
var
urlPath
string
if
!
RouterCaseSensitive
{
urlPath
=
strings
.
ToLower
(
r
.
URL
.
Path
)
...
...
@@ -648,7 +648,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
context
.
Input
.
CruSession
,
err
=
GlobalSessions
.
SessionStart
(
w
,
r
)
if
err
!=
nil
{
Error
(
err
)
middleware
.
Exception
(
"503"
,
rw
,
r
,
""
)
exception
(
"503"
,
context
)
return
}
defer
func
()
{
...
...
@@ -703,7 +703,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
//if no matches to url, throw a not found exception
if
!
findrouter
{
middleware
.
Exception
(
"404"
,
rw
,
r
,
""
)
exception
(
"404"
,
context
)
goto
Admin
}
...
...
@@ -719,7 +719,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
isRunable
=
true
routerInfo
.
runfunction
(
context
)
}
else
{
middleware
.
Exception
(
"405"
,
rw
,
r
,
"Method Not Allowed"
)
exception
(
"405"
,
context
)
goto
Admin
}
}
else
if
routerInfo
.
routerType
==
routerTypeHandler
{
...
...
@@ -830,7 +830,7 @@ Admin:
}
}
if
RunMode
==
"dev"
{
if
RunMode
==
"dev"
||
AccessLogs
{
var
devinfo
string
if
findrouter
{
if
routerInfo
!=
nil
{
...
...
@@ -852,28 +852,51 @@ Admin:
}
}
func
(
p
*
ControllerRegistor
)
recoverPanic
(
rw
http
.
ResponseWriter
,
r
*
http
.
Reques
t
)
{
func
(
p
*
ControllerRegistor
)
recoverPanic
(
context
*
beecontext
.
Contex
t
)
{
if
err
:=
recover
();
err
!=
nil
{
if
err
==
USERSTOPRUN
{
return
}
if
he
,
ok
:=
err
.
(
middleware
.
HTTPException
);
ok
{
rw
.
WriteHeader
(
he
.
StatusCode
)
rw
.
Write
([]
byte
(
he
.
Description
))
// catch intented errors, only for HTTP 4XX and 5XX
if
RunMode
==
"dev"
{
if
!
RecoverPanic
{
panic
(
err
)
}
else
{
if
ErrorsShow
{
if
handler
,
ok
:=
ErrorMaps
[
fmt
.
Sprint
(
err
)];
ok
{
executeError
(
handler
,
context
)
return
}
}
var
stack
string
Critical
(
"the request url is "
,
context
.
Input
.
Url
())
Critical
(
"Handler crashed with error"
,
err
)
for
i
:=
1
;
;
i
++
{
_
,
file
,
line
,
ok
:=
runtime
.
Caller
(
i
)
if
!
ok
{
break
}
Critical
(
fmt
.
Sprintf
(
"%s:%d"
,
file
,
line
))
stack
=
stack
+
fmt
.
Sprintln
(
fmt
.
Sprintf
(
"%s:%d"
,
file
,
line
))
}
showErr
(
err
,
context
,
stack
)
}
}
else
{
if
RunMode
==
"dev"
{
if
!
RecoverPanic
{
panic
(
err
)
}
else
{
if
ErrorsShow
{
if
handler
,
ok
:=
middleware
.
ErrorMaps
[
fmt
.
Sprint
(
err
)];
ok
{
handler
(
rw
,
r
)
return
}
if
!
RecoverPanic
{
panic
(
err
)
}
else
{
// in production model show all infomation
if
ErrorsShow
{
if
handler
,
ok
:=
ErrorMaps
[
fmt
.
Sprint
(
err
)];
ok
{
executeError
(
handler
,
context
)
return
}
else
if
handler
,
ok
:=
ErrorMaps
[
"503"
];
ok
{
executeError
(
handler
,
context
)
return
}
else
{
context
.
WriteString
(
fmt
.
Sprint
(
err
))
}
var
stack
string
Critical
(
"the request url is "
,
r
.
URL
.
Path
)
}
else
{
Critical
(
"the request url is "
,
context
.
Input
.
Url
()
)
Critical
(
"Handler crashed with error"
,
err
)
for
i
:=
1
;
;
i
++
{
_
,
file
,
line
,
ok
:=
runtime
.
Caller
(
i
)
...
...
@@ -881,39 +904,9 @@ func (p *ControllerRegistor) recoverPanic(rw http.ResponseWriter, r *http.Reques
break
}
Critical
(
fmt
.
Sprintf
(
"%s:%d"
,
file
,
line
))
stack
=
stack
+
fmt
.
Sprintln
(
fmt
.
Sprintf
(
"%s:%d"
,
file
,
line
))
}
middleware
.
ShowErr
(
err
,
rw
,
r
,
stack
)
}
}
else
{
if
!
RecoverPanic
{
panic
(
err
)
}
else
{
// in production model show all infomation
if
ErrorsShow
{
if
handler
,
ok
:=
middleware
.
ErrorMaps
[
fmt
.
Sprint
(
err
)];
ok
{
handler
(
rw
,
r
)
return
}
else
if
handler
,
ok
:=
middleware
.
ErrorMaps
[
"503"
];
ok
{
handler
(
rw
,
r
)
return
}
else
{
rw
.
Write
([]
byte
(
fmt
.
Sprint
(
err
)))
}
}
else
{
Critical
(
"the request url is "
,
r
.
URL
.
Path
)
Critical
(
"Handler crashed with error"
,
err
)
for
i
:=
1
;
;
i
++
{
_
,
file
,
line
,
ok
:=
runtime
.
Caller
(
i
)
if
!
ok
{
break
}
Critical
(
fmt
.
Sprintf
(
"%s:%d"
,
file
,
line
))
}
}
}
}
}
}
}
...
...
session/ledis/ledis_session.go
View file @
020bfbc
...
...
@@ -2,6 +2,8 @@ package session
import
(
"net/http"
"strconv"
"strings"
"sync"
"github.com/astaxie/beego/session"
...
...
@@ -74,19 +76,29 @@ func (ls *LedisSessionStore) SessionRelease(w http.ResponseWriter) {
type
LedisProvider
struct
{
maxlifetime
int64
savePath
string
db
int
}
// init ledis session
// savepath like ledis server saveDataPath,pool size
// e.g. 127.0.0.1:6379,100,astaxie
func
(
lp
*
LedisProvider
)
SessionInit
(
maxlifetime
int64
,
savePath
string
)
error
{
var
err
error
lp
.
maxlifetime
=
maxlifetime
lp
.
savePath
=
savePath
configs
:=
strings
.
Split
(
savepath
,
","
)
if
len
(
configs
)
==
1
{
lp
.
savePath
=
configs
[
0
]
}
else
if
len
(
configs
)
==
2
{
lp
.
savePath
=
configs
[
0
]
lp
.
db
,
err
=
strconv
.
Atoi
(
configs
[
1
])
if
err
!=
nil
{
return
err
}
}
cfg
:=
new
(
config
.
Config
)
cfg
.
DataDir
=
lp
.
savePath
var
err
error
nowLedis
,
err
:=
ledis
.
Open
(
cfg
)
c
,
err
=
nowLedis
.
Select
(
0
)
c
,
err
=
nowLedis
.
Select
(
lp
.
db
)
if
err
!=
nil
{
println
(
err
)
return
nil
...
...
session/redis/sess_redis.go
View file @
020bfbc
...
...
@@ -118,12 +118,13 @@ type RedisProvider struct {
savePath
string
poolsize
int
password
string
dbNum
int
poollist
*
redis
.
Pool
}
// init redis session
// savepath like redis server addr,pool size,password
// e.g. 127.0.0.1:6379,100,astaxie
// savepath like redis server addr,pool size,password
,dbnum
// e.g. 127.0.0.1:6379,100,astaxie
,0
func
(
rp
*
RedisProvider
)
SessionInit
(
maxlifetime
int64
,
savePath
string
)
error
{
rp
.
maxlifetime
=
maxlifetime
configs
:=
strings
.
Split
(
savePath
,
","
)
...
...
@@ -143,6 +144,16 @@ func (rp *RedisProvider) SessionInit(maxlifetime int64, savePath string) error {
if
len
(
configs
)
>
2
{
rp
.
password
=
configs
[
2
]
}
if
len
(
configs
)
>
3
{
dbnum
,
err
:=
strconv
.
Atoi
(
configs
[
1
])
if
err
!=
nil
||
dbnum
<
0
{
rp
.
dbNum
=
0
}
else
{
rp
.
dbNum
=
dbnum
}
}
else
{
rp
.
dbNum
=
0
}
rp
.
poollist
=
redis
.
NewPool
(
func
()
(
redis
.
Conn
,
error
)
{
c
,
err
:=
redis
.
Dial
(
"tcp"
,
rp
.
savePath
)
if
err
!=
nil
{
...
...
@@ -154,6 +165,11 @@ func (rp *RedisProvider) SessionInit(maxlifetime int64, savePath string) error {
return
nil
,
err
}
}
_
,
err
=
c
.
Do
(
"SELECT"
,
rp
.
dbNum
)
if
err
!=
nil
{
c
.
Close
()
return
nil
,
err
}
return
c
,
err
},
rp
.
poolsize
)
...
...
staticfile.go
View file @
020bfbc
...
...
@@ -22,7 +22,6 @@ import (
"strings"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/middleware"
"github.com/astaxie/beego/utils"
)
...
...
@@ -67,7 +66,7 @@ func serverStaticRouter(ctx *context.Context) {
//if the request is dir and DirectoryIndex is false then
if
finfo
.
IsDir
()
{
if
!
DirectoryIndex
{
middleware
.
Exception
(
"403"
,
ctx
.
ResponseWriter
,
ctx
.
Request
,
"403 Forbidden"
)
exception
(
"403"
,
ctx
)
return
}
else
if
ctx
.
Input
.
Request
.
URL
.
Path
[
len
(
ctx
.
Input
.
Request
.
URL
.
Path
)
-
1
]
!=
'/'
{
http
.
Redirect
(
ctx
.
ResponseWriter
,
ctx
.
Request
,
ctx
.
Input
.
Request
.
URL
.
Path
+
"/"
,
302
)
...
...
template.go
View file @
020bfbc
...
...
@@ -42,6 +42,9 @@ func init() {
beegoTplFuncMap
[
"dateformat"
]
=
DateFormat
beegoTplFuncMap
[
"date"
]
=
Date
beegoTplFuncMap
[
"compare"
]
=
Compare
beegoTplFuncMap
[
"compare_not"
]
=
CompareNot
beegoTplFuncMap
[
"not_nil"
]
=
NotNil
beegoTplFuncMap
[
"not_null"
]
=
NotNil
beegoTplFuncMap
[
"substr"
]
=
Substr
beegoTplFuncMap
[
"html2str"
]
=
Html2str
beegoTplFuncMap
[
"str2html"
]
=
Str2html
...
...
templatefunc.go
View file @
020bfbc
...
...
@@ -139,6 +139,14 @@ func Compare(a, b interface{}) (equal bool) {
return
}
func
CompareNot
(
a
,
b
interface
{})
(
equal
bool
)
{
return
!
Compare
(
a
,
b
)
}
func
NotNil
(
a
interface
{})
(
is_nil
bool
)
{
return
CompareNot
(
a
,
nil
)
}
func
Config
(
returnType
,
key
string
,
defaultVal
interface
{})
(
value
interface
{},
err
error
)
{
switch
returnType
{
case
"String"
:
...
...
@@ -246,7 +254,7 @@ func Htmlunquote(src string) string {
// /user/John%20Doe
//
// more detail http://beego.me/docs/mvc/controller/urlbuilding.md
func
UrlFor
(
endpoint
string
,
values
...
string
)
string
{
func
UrlFor
(
endpoint
string
,
values
...
interface
{}
)
string
{
return
BeeApp
.
Handlers
.
UrlFor
(
endpoint
,
values
...
)
}
...
...
@@ -350,11 +358,32 @@ func ParseForm(form url.Values, obj interface{}) error {
}
fieldV
.
Set
(
reflect
.
ValueOf
(
t
))
}
case
reflect
.
Slice
:
if
fieldT
.
Type
==
sliceOfInts
{
formVals
:=
form
[
tag
]
fieldV
.
Set
(
reflect
.
MakeSlice
(
reflect
.
SliceOf
(
reflect
.
TypeOf
(
int
(
1
))),
len
(
formVals
),
len
(
formVals
)))
for
i
:=
0
;
i
<
len
(
formVals
);
i
++
{
val
,
err
:=
strconv
.
Atoi
(
formVals
[
i
])
if
err
!=
nil
{
return
err
}
fieldV
.
Index
(
i
)
.
SetInt
(
int64
(
val
))
}
}
else
if
fieldT
.
Type
==
sliceOfStrings
{
formVals
:=
form
[
tag
]
fieldV
.
Set
(
reflect
.
MakeSlice
(
reflect
.
SliceOf
(
reflect
.
TypeOf
(
""
)),
len
(
formVals
),
len
(
formVals
)))
for
i
:=
0
;
i
<
len
(
formVals
);
i
++
{
fieldV
.
Index
(
i
)
.
SetString
(
formVals
[
i
])
}
}
}
}
return
nil
}
var
sliceOfInts
=
reflect
.
TypeOf
([]
int
(
nil
))
var
sliceOfStrings
=
reflect
.
TypeOf
([]
string
(
nil
))
var
unKind
=
map
[
reflect
.
Kind
]
bool
{
reflect
.
Uintptr
:
true
,
reflect
.
Complex64
:
true
,
...
...
templatefunc_test.go
View file @
020bfbc
...
...
@@ -72,7 +72,7 @@ func TestDate(t *testing.T) {
}
}
func
TestCompare
(
t
*
testing
.
T
)
{
func
TestCompare
Related
(
t
*
testing
.
T
)
{
if
!
Compare
(
"abc"
,
"abc"
)
{
t
.
Error
(
"should be equal"
)
}
...
...
@@ -82,6 +82,15 @@ func TestCompare(t *testing.T) {
if
!
Compare
(
"1"
,
1
)
{
t
.
Error
(
"should be equal"
)
}
if
CompareNot
(
"abc"
,
"abc"
)
{
t
.
Error
(
"should be equal"
)
}
if
!
CompareNot
(
"abc"
,
"aBc"
)
{
t
.
Error
(
"should be not equal"
)
}
if
!
NotNil
(
"a string"
)
{
t
.
Error
(
"should not be nil"
)
}
}
func
TestHtmlquote
(
t
*
testing
.
T
)
{
...
...
toolbox/task.go
View file @
020bfbc
...
...
@@ -84,6 +84,7 @@ type TaskFunc func() error
// task interface
type
Tasker
interface
{
GetSpec
()
string
GetStatus
()
string
Run
()
error
SetNext
(
time
.
Time
)
...
...
@@ -102,6 +103,7 @@ type taskerr struct {
type
Task
struct
{
Taskname
string
Spec
*
Schedule
SpecStr
string
DoFunc
TaskFunc
Prev
time
.
Time
Next
time
.
Time
...
...
@@ -116,16 +118,22 @@ func NewTask(tname string, spec string, f TaskFunc) *Task {
Taskname
:
tname
,
DoFunc
:
f
,
ErrLimit
:
100
,
SpecStr
:
spec
,
}
task
.
SetCron
(
spec
)
return
task
}
//get spec string
func
(
s
*
Task
)
GetSpec
()
string
{
return
s
.
SpecStr
}
// get current task status
func
(
tk
*
Task
)
GetStatus
()
string
{
var
str
string
for
_
,
v
:=
range
tk
.
Errlist
{
str
+=
v
.
t
.
String
()
+
":"
+
v
.
errinfo
+
"
\n
"
str
+=
v
.
t
.
String
()
+
":"
+
v
.
errinfo
+
"
<br>
"
}
return
str
}
...
...
tree.go
View file @
020bfbc
...
...
@@ -422,6 +422,9 @@ func (leaf *leafInfo) match(wildcardValues []string) (ok bool, params map[string
// "/admin/" -> ["admin"]
// "/admin/users" -> ["admin", "users"]
func
splitPath
(
key
string
)
[]
string
{
if
key
==
""
{
return
[]
string
{}
}
elements
:=
strings
.
Split
(
key
,
"/"
)
if
elements
[
0
]
==
""
{
elements
=
elements
[
1
:
]
...
...
tree_test.go
View file @
020bfbc
...
...
@@ -149,7 +149,11 @@ func TestAddTree2(t *testing.T) {
}
func
TestSplitPath
(
t
*
testing
.
T
)
{
a
:=
splitPath
(
"/"
)
a
:=
splitPath
(
""
)
if
len
(
a
)
!=
0
{
t
.
Fatal
(
"/ should retrun []"
)
}
a
=
splitPath
(
"/"
)
if
len
(
a
)
!=
0
{
t
.
Fatal
(
"/ should retrun []"
)
}
...
...
utils/pagination/controller.go
View file @
020bfbc
...
...
@@ -21,6 +21,6 @@ import (
// Instantiates a Paginator and assigns it to context.Input.Data["paginator"].
func
SetPaginator
(
context
*
context
.
Context
,
per
int
,
nums
int64
)
(
paginator
*
Paginator
)
{
paginator
=
NewPaginator
(
context
.
Request
,
per
,
nums
)
context
.
Input
.
Data
[
"paginator"
]
=
paginator
context
.
Input
.
Data
[
"paginator"
]
=
&
paginator
return
}
...
...
utils/pagination/paginator.go
View file @
020bfbc
...
...
@@ -114,7 +114,7 @@ func (p *Paginator) Pages() []int {
// Returns URL for a given page index.
func
(
p
*
Paginator
)
PageLink
(
page
int
)
string
{
link
,
_
:=
url
.
ParseRequestURI
(
p
.
Request
.
RequestURI
)
link
,
_
:=
url
.
ParseRequestURI
(
p
.
Request
.
URL
.
String
()
)
values
:=
link
.
Query
()
if
page
==
1
{
values
.
Del
(
"p"
)
...
...
Write
Preview
Styling with
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment