Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
B
beego
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
beego
Commits
82ca85dc
Commit
82ca85dc
authored
Apr 08, 2014
by
astaxie
Browse files
Options
Browse Files
Download
Plain Diff
release new version 1.1.4
parents
8cbea70e
f9cc9e9e
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
268 additions
and
213 deletions
+268
-213
admin.go
admin.go
+23
-23
beego.go
beego.go
+4
-2
memcache.go
cache/memcache/memcache.go
+3
-1
redis.go
cache/redis/redis.go
+3
-1
config.go
config.go
+2
-2
xml.go
config/xml/xml.go
+0
-0
xml_test.go
config/xml/xml_test.go
+0
-0
yaml.go
config/yaml/yaml.go
+0
-0
yaml_test.go
config/yaml/yaml_test.go
+0
-0
input.go
context/input.go
+59
-3
memzipfile.go
memzipfile.go
+20
-45
reload.go
reload.go
+0
-1
router.go
router.go
+14
-94
sess_couchbase.go
session/couchbase/sess_couchbase.go
+10
-7
sess_mysql.go
session/mysql/sess_mysql.go
+8
-6
sess_postgresql.go
session/postgres/sess_postgresql.go
+12
-9
sess_redis.go
session/redis/sess_redis.go
+8
-6
sess_file.go
session/sess_file.go
+3
-3
sess_test.go
session/sess_test.go
+2
-2
sess_utils.go
session/sess_utils.go
+6
-6
staticfile.go
staticfile.go
+90
-0
debug.go
toolbox/debug.go
+1
-2
No files found.
admin.go
View file @
82ca85dc
...
...
@@ -9,8 +9,8 @@ import (
"github.com/astaxie/beego/utils"
)
// BeeAdminApp is the default
A
dminApp used by admin module.
var
BeeAdminApp
*
A
dminApp
// BeeAdminApp is the default
a
dminApp used by admin module.
var
beeAdminApp
*
a
dminApp
// FilterMonitorFunc is default monitor filter when admin module is enable.
// if this func returns, admin module records qbs for this request by condition of this function logic.
...
...
@@ -31,22 +31,22 @@ var BeeAdminApp *AdminApp
var
FilterMonitorFunc
func
(
string
,
string
,
time
.
Duration
)
bool
func
init
()
{
BeeAdminApp
=
&
A
dminApp
{
beeAdminApp
=
&
a
dminApp
{
routers
:
make
(
map
[
string
]
http
.
HandlerFunc
),
}
BeeAdminApp
.
Route
(
"/"
,
A
dminIndex
)
BeeAdminApp
.
Route
(
"/qps"
,
Q
psIndex
)
BeeAdminApp
.
Route
(
"/prof"
,
P
rofIndex
)
BeeAdminApp
.
Route
(
"/healthcheck"
,
H
ealthcheck
)
BeeAdminApp
.
Route
(
"/task"
,
T
askStatus
)
BeeAdminApp
.
Route
(
"/runtask"
,
R
unTask
)
BeeAdminApp
.
Route
(
"/listconf"
,
L
istConf
)
beeAdminApp
.
Route
(
"/"
,
a
dminIndex
)
beeAdminApp
.
Route
(
"/qps"
,
q
psIndex
)
beeAdminApp
.
Route
(
"/prof"
,
p
rofIndex
)
beeAdminApp
.
Route
(
"/healthcheck"
,
h
ealthcheck
)
beeAdminApp
.
Route
(
"/task"
,
t
askStatus
)
beeAdminApp
.
Route
(
"/runtask"
,
r
unTask
)
beeAdminApp
.
Route
(
"/listconf"
,
l
istConf
)
FilterMonitorFunc
=
func
(
string
,
string
,
time
.
Duration
)
bool
{
return
true
}
}
// AdminIndex is the default http.Handler for admin module.
// it matches url pattern "/".
func
A
dminIndex
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
a
dminIndex
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
rw
.
Write
([]
byte
(
"Welcome to Admin Dashboard
\n
"
))
rw
.
Write
([]
byte
(
"There are servral functions:
\n
"
))
rw
.
Write
([]
byte
(
"1. Record all request and request time, http://localhost:8088/qps
\n
"
))
...
...
@@ -60,13 +60,13 @@ func AdminIndex(rw http.ResponseWriter, r *http.Request) {
// QpsIndex is the http.Handler for writing qbs statistics map result info in http.ResponseWriter.
// it's registered with url pattern "/qbs" in admin module.
func
Q
psIndex
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
q
psIndex
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
toolbox
.
StatisticsMap
.
GetMap
(
rw
)
}
// ListConf is the http.Handler of displaying all beego configuration values as key/value pair.
// it's registered with url pattern "/listconf" in admin module.
func
L
istConf
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
l
istConf
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
r
.
ParseForm
()
command
:=
r
.
Form
.
Get
(
"command"
)
if
command
!=
""
{
...
...
@@ -183,7 +183,7 @@ func ListConf(rw http.ResponseWriter, r *http.Request) {
// ProfIndex is a http.Handler for showing profile command.
// it's in url pattern "/prof" in admin module.
func
P
rofIndex
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
p
rofIndex
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
r
.
ParseForm
()
command
:=
r
.
Form
.
Get
(
"command"
)
if
command
!=
""
{
...
...
@@ -204,7 +204,7 @@ func ProfIndex(rw http.ResponseWriter, r *http.Request) {
// Healthcheck is a http.Handler calling health checking and showing the result.
// it's in "/healthcheck" pattern in admin module.
func
H
ealthcheck
(
rw
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
func
h
ealthcheck
(
rw
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
for
name
,
h
:=
range
toolbox
.
AdminCheckList
{
if
err
:=
h
.
Check
();
err
!=
nil
{
fmt
.
Fprintf
(
rw
,
"%s : ok
\n
"
,
name
)
...
...
@@ -216,7 +216,7 @@ func Healthcheck(rw http.ResponseWriter, req *http.Request) {
// TaskStatus is a http.Handler with running task status (task name, status and the last execution).
// it's in "/task" pattern in admin module.
func
T
askStatus
(
rw
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
func
t
askStatus
(
rw
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
for
tname
,
tk
:=
range
toolbox
.
AdminTaskList
{
fmt
.
Fprintf
(
rw
,
"%s:%s:%s"
,
tname
,
tk
.
GetStatus
(),
tk
.
GetPrev
()
.
String
())
}
...
...
@@ -224,7 +224,7 @@ func TaskStatus(rw http.ResponseWriter, req *http.Request) {
// RunTask is a http.Handler to run a Task from the "query string.
// the request url likes /runtask?taskname=sendmail.
func
R
unTask
(
rw
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
func
r
unTask
(
rw
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
req
.
ParseForm
()
taskname
:=
req
.
Form
.
Get
(
"taskname"
)
if
t
,
ok
:=
toolbox
.
AdminTaskList
[
taskname
];
ok
{
...
...
@@ -238,19 +238,19 @@ func RunTask(rw http.ResponseWriter, req *http.Request) {
}
}
//
AdminApp is an http.HandlerFunc map used as B
eeAdminApp.
type
A
dminApp
struct
{
//
adminApp is an http.HandlerFunc map used as b
eeAdminApp.
type
a
dminApp
struct
{
routers
map
[
string
]
http
.
HandlerFunc
}
// Route adds http.HandlerFunc to
A
dminApp with url pattern.
func
(
admin
*
A
dminApp
)
Route
(
pattern
string
,
f
http
.
HandlerFunc
)
{
// Route adds http.HandlerFunc to
a
dminApp with url pattern.
func
(
admin
*
a
dminApp
)
Route
(
pattern
string
,
f
http
.
HandlerFunc
)
{
admin
.
routers
[
pattern
]
=
f
}
// Run
A
dminApp http server.
// Run
a
dminApp http server.
// Its addr is defined in configuration file as adminhttpaddr and adminhttpport.
func
(
admin
*
A
dminApp
)
Run
()
{
func
(
admin
*
a
dminApp
)
Run
()
{
if
len
(
toolbox
.
AdminTaskList
)
>
0
{
toolbox
.
StartTask
()
}
...
...
beego.go
View file @
82ca85dc
// beego is an open-source, high-performance web framework for the Go programming language
package
beego
import
(
...
...
@@ -13,7 +14,7 @@ import (
)
// beego web framework version.
const
VERSION
=
"1.1.
3
"
const
VERSION
=
"1.1.
4
"
type
hookfunc
func
()
error
//hook function to run
var
hooks
[]
hookfunc
//hook function slice to store the hookfunc
...
...
@@ -137,6 +138,7 @@ func SetStaticPath(url string, path string) *App {
if
!
strings
.
HasPrefix
(
url
,
"/"
)
{
url
=
"/"
+
url
}
url
=
strings
.
TrimRight
(
url
,
"/"
)
StaticDir
[
url
]
=
path
return
BeeApp
}
...
...
@@ -178,7 +180,7 @@ func Run() {
initBeforeHttpRun
()
if
EnableAdmin
{
go
B
eeAdminApp
.
Run
()
go
b
eeAdminApp
.
Run
()
}
BeeApp
.
Run
()
...
...
cache/memcache.go
→
cache/memcache
/memcache
.go
View file @
82ca85dc
...
...
@@ -5,6 +5,8 @@ import (
"errors"
"github.com/beego/memcache"
"github.com/astaxie/beego/cache"
)
// Memcache adapter.
...
...
@@ -147,5 +149,5 @@ func (rc *MemcacheCache) connectInit() (*memcache.Connection, error) {
}
func
init
()
{
Register
(
"memcache"
,
NewMemCache
())
cache
.
Register
(
"memcache"
,
NewMemCache
())
}
cache/redis.go
→
cache/redis
/redis
.go
View file @
82ca85dc
...
...
@@ -6,6 +6,8 @@ import (
"time"
"github.com/beego/redigo/redis"
"github.com/astaxie/beego/cache"
)
var
(
...
...
@@ -130,5 +132,5 @@ func (rc *RedisCache) connectInit() {
}
func
init
()
{
Register
(
"redis"
,
NewRedisCache
())
cache
.
Register
(
"redis"
,
NewRedisCache
())
}
config.go
View file @
82ca85dc
...
...
@@ -306,9 +306,9 @@ func ParseConfig() (err error) {
sds
:=
strings
.
Fields
(
sd
)
for
_
,
v
:=
range
sds
{
if
url2fsmap
:=
strings
.
SplitN
(
v
,
":"
,
2
);
len
(
url2fsmap
)
==
2
{
StaticDir
[
"/"
+
url2fsmap
[
0
]
]
=
url2fsmap
[
1
]
StaticDir
[
"/"
+
strings
.
TrimRight
(
url2fsmap
[
0
],
"/"
)
]
=
url2fsmap
[
1
]
}
else
{
StaticDir
[
"/"
+
url2fsmap
[
0
]
]
=
url2fsmap
[
0
]
StaticDir
[
"/"
+
strings
.
TrimRight
(
url2fsmap
[
0
],
"/"
)
]
=
url2fsmap
[
0
]
}
}
}
...
...
config/xml.go
→
config/xml
/xml
.go
View file @
82ca85dc
File moved
config/xml_test.go
→
config/xml
/xml
_test.go
View file @
82ca85dc
File moved
config/yaml.go
→
config/yaml
/yaml
.go
View file @
82ca85dc
File moved
config/yaml_test.go
→
config/yaml
/yaml
_test.go
View file @
82ca85dc
File moved
context/input.go
View file @
82ca85dc
...
...
@@ -2,6 +2,7 @@ package context
import
(
"bytes"
"errors"
"io/ioutil"
"net/http"
"reflect"
...
...
@@ -92,6 +93,41 @@ func (input *BeegoInput) Is(method string) bool {
return
input
.
Method
()
==
method
}
// Is this a GET method request?
func
(
input
*
BeegoInput
)
IsGet
()
bool
{
return
input
.
Is
(
"GET"
)
}
// Is this a POST method request?
func
(
input
*
BeegoInput
)
IsPost
()
bool
{
return
input
.
Is
(
"POST"
)
}
// Is this a Head method request?
func
(
input
*
BeegoInput
)
IsHead
()
bool
{
return
input
.
Is
(
"HEAD"
)
}
// Is this a OPTIONS method request?
func
(
input
*
BeegoInput
)
IsOptions
()
bool
{
return
input
.
Is
(
"OPTIONS"
)
}
// Is this a PUT method request?
func
(
input
*
BeegoInput
)
IsPut
()
bool
{
return
input
.
Is
(
"PUT"
)
}
// Is this a DELETE method request?
func
(
input
*
BeegoInput
)
IsDelete
()
bool
{
return
input
.
Is
(
"DELETE"
)
}
// Is this a PATCH method request?
func
(
input
*
BeegoInput
)
IsPatch
()
bool
{
return
input
.
Is
(
"PATCH"
)
}
// IsAjax returns boolean of this request is generated by ajax.
func
(
input
*
BeegoInput
)
IsAjax
()
bool
{
return
input
.
Header
(
"X-Requested-With"
)
==
"XMLHttpRequest"
...
...
@@ -109,7 +145,7 @@ func (input *BeegoInput) IsWebsocket() bool {
// IsSecure returns boolean of whether file uploads in this request or not..
func
(
input
*
BeegoInput
)
IsUpload
()
bool
{
return
input
.
Request
.
MultipartForm
!=
nil
return
input
.
Header
(
"Content-Type"
)
==
"multipart/form-data"
}
// IP returns request client ip.
...
...
@@ -175,7 +211,9 @@ func (input *BeegoInput) Param(key string) string {
// Query returns input data item string by a given string.
func
(
input
*
BeegoInput
)
Query
(
key
string
)
string
{
input
.
Request
.
ParseForm
()
if
input
.
Request
.
Form
==
nil
{
input
.
Request
.
ParseForm
()
}
return
input
.
Request
.
Form
.
Get
(
key
)
}
...
...
@@ -200,7 +238,7 @@ func (input *BeegoInput) Session(key interface{}) interface{} {
}
// Body returns the raw request body data as bytes.
func
(
input
*
BeegoInput
)
Body
()
[]
byte
{
func
(
input
*
BeegoInput
)
Copy
Body
()
[]
byte
{
requestbody
,
_
:=
ioutil
.
ReadAll
(
input
.
Request
.
Body
)
input
.
Request
.
Body
.
Close
()
bf
:=
bytes
.
NewBuffer
(
requestbody
)
...
...
@@ -222,3 +260,21 @@ func (input *BeegoInput) GetData(key interface{}) interface{} {
func
(
input
*
BeegoInput
)
SetData
(
key
,
val
interface
{})
{
input
.
Data
[
key
]
=
val
}
func
(
input
*
BeegoInput
)
ParseFormOrMulitForm
(
maxMemory
int64
)
error
{
// Parse the body depending on the content type.
switch
input
.
Header
(
"Content-Type"
)
{
case
"application/x-www-form-urlencoded"
:
// Typical form.
if
err
:=
input
.
Request
.
ParseForm
();
err
!=
nil
{
return
errors
.
New
(
"Error parsing request body:"
+
err
.
Error
())
}
case
"multipart/form-data"
:
if
err
:=
input
.
Request
.
ParseMultipartForm
(
maxMemory
);
err
!=
nil
{
return
errors
.
New
(
"Error parsing request body:"
+
err
.
Error
())
}
}
return
nil
}
memzipfile.go
View file @
82ca85dc
...
...
@@ -14,12 +14,12 @@ import (
"time"
)
var
gmfim
map
[
string
]
*
MemFileInfo
=
make
(
map
[
string
]
*
M
emFileInfo
)
var
gmfim
map
[
string
]
*
memFileInfo
=
make
(
map
[
string
]
*
m
emFileInfo
)
var
lock
sync
.
RWMutex
// OpenMemZipFile returns MemFile object with a compressed static file.
// it's used for serve static file if gzip enable.
func
OpenMemZipFile
(
path
string
,
zip
string
)
(
*
M
emFile
,
error
)
{
func
openMemZipFile
(
path
string
,
zip
string
)
(
*
m
emFile
,
error
)
{
osfile
,
e
:=
os
.
Open
(
path
)
if
e
!=
nil
{
return
nil
,
e
...
...
@@ -36,12 +36,9 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) {
lock
.
RLock
()
cfi
,
ok
:=
gmfim
[
zip
+
":"
+
path
]
lock
.
RUnlock
()
if
ok
&&
cfi
.
ModTime
()
==
modtime
&&
cfi
.
fileSize
==
fileSize
{
}
else
{
if
!
(
ok
&&
cfi
.
ModTime
()
==
modtime
&&
cfi
.
fileSize
==
fileSize
)
{
var
content
[]
byte
if
zip
==
"gzip"
{
//将文件内容压缩到zipbuf中
var
zipbuf
bytes
.
Buffer
gzipwriter
,
e
:=
gzip
.
NewWriterLevel
(
&
zipbuf
,
gzip
.
BestCompression
)
if
e
!=
nil
{
...
...
@@ -52,13 +49,11 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) {
if
e
!=
nil
{
return
nil
,
e
}
//读zipbuf到content
content
,
e
=
ioutil
.
ReadAll
(
&
zipbuf
)
if
e
!=
nil
{
return
nil
,
e
}
}
else
if
zip
==
"deflate"
{
//将文件内容压缩到zipbuf中
var
zipbuf
bytes
.
Buffer
deflatewriter
,
e
:=
flate
.
NewWriter
(
&
zipbuf
,
flate
.
BestCompression
)
if
e
!=
nil
{
...
...
@@ -69,7 +64,6 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) {
if
e
!=
nil
{
return
nil
,
e
}
//将zipbuf读入到content
content
,
e
=
ioutil
.
ReadAll
(
&
zipbuf
)
if
e
!=
nil
{
return
nil
,
e
...
...
@@ -81,17 +75,17 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) {
}
}
cfi
=
&
M
emFileInfo
{
osfileinfo
,
modtime
,
content
,
int64
(
len
(
content
)),
fileSize
}
cfi
=
&
m
emFileInfo
{
osfileinfo
,
modtime
,
content
,
int64
(
len
(
content
)),
fileSize
}
lock
.
Lock
()
defer
lock
.
Unlock
()
gmfim
[
zip
+
":"
+
path
]
=
cfi
}
return
&
M
emFile
{
fi
:
cfi
,
offset
:
0
},
nil
return
&
m
emFile
{
fi
:
cfi
,
offset
:
0
},
nil
}
// MemFileInfo contains a compressed file bytes and file information.
// it implements os.FileInfo interface.
type
M
emFileInfo
struct
{
type
m
emFileInfo
struct
{
os
.
FileInfo
modTime
time
.
Time
content
[]
byte
...
...
@@ -100,62 +94,62 @@ type MemFileInfo struct {
}
// Name returns the compressed filename.
func
(
fi
*
M
emFileInfo
)
Name
()
string
{
func
(
fi
*
m
emFileInfo
)
Name
()
string
{
return
fi
.
Name
()
}
// Size returns the raw file content size, not compressed size.
func
(
fi
*
M
emFileInfo
)
Size
()
int64
{
func
(
fi
*
m
emFileInfo
)
Size
()
int64
{
return
fi
.
contentSize
}
// Mode returns file mode.
func
(
fi
*
M
emFileInfo
)
Mode
()
os
.
FileMode
{
func
(
fi
*
m
emFileInfo
)
Mode
()
os
.
FileMode
{
return
fi
.
Mode
()
}
// ModTime returns the last modified time of raw file.
func
(
fi
*
M
emFileInfo
)
ModTime
()
time
.
Time
{
func
(
fi
*
m
emFileInfo
)
ModTime
()
time
.
Time
{
return
fi
.
modTime
}
// IsDir returns the compressing file is a directory or not.
func
(
fi
*
M
emFileInfo
)
IsDir
()
bool
{
func
(
fi
*
m
emFileInfo
)
IsDir
()
bool
{
return
fi
.
IsDir
()
}
// return nil. implement the os.FileInfo interface method.
func
(
fi
*
M
emFileInfo
)
Sys
()
interface
{}
{
func
(
fi
*
m
emFileInfo
)
Sys
()
interface
{}
{
return
nil
}
// MemFile contains MemFileInfo and bytes offset when reading.
// it implements io.Reader,io.ReadCloser and io.Seeker.
type
M
emFile
struct
{
fi
*
M
emFileInfo
type
m
emFile
struct
{
fi
*
m
emFileInfo
offset
int64
}
// Close memfile.
func
(
f
*
M
emFile
)
Close
()
error
{
func
(
f
*
m
emFile
)
Close
()
error
{
return
nil
}
// Get os.FileInfo of memfile.
func
(
f
*
M
emFile
)
Stat
()
(
os
.
FileInfo
,
error
)
{
func
(
f
*
m
emFile
)
Stat
()
(
os
.
FileInfo
,
error
)
{
return
f
.
fi
,
nil
}
// read os.FileInfo of files in directory of memfile.
// it returns empty slice.
func
(
f
*
M
emFile
)
Readdir
(
count
int
)
([]
os
.
FileInfo
,
error
)
{
func
(
f
*
m
emFile
)
Readdir
(
count
int
)
([]
os
.
FileInfo
,
error
)
{
infos
:=
[]
os
.
FileInfo
{}
return
infos
,
nil
}
// Read bytes from the compressed file bytes.
func
(
f
*
M
emFile
)
Read
(
p
[]
byte
)
(
n
int
,
err
error
)
{
func
(
f
*
m
emFile
)
Read
(
p
[]
byte
)
(
n
int
,
err
error
)
{
if
len
(
f
.
fi
.
content
)
-
int
(
f
.
offset
)
>=
len
(
p
)
{
n
=
len
(
p
)
}
else
{
...
...
@@ -171,7 +165,7 @@ var errWhence = errors.New("Seek: invalid whence")
var
errOffset
=
errors
.
New
(
"Seek: invalid offset"
)
// Read bytes from the compressed file bytes by seeker.
func
(
f
*
M
emFile
)
Seek
(
offset
int64
,
whence
int
)
(
ret
int64
,
err
error
)
{
func
(
f
*
m
emFile
)
Seek
(
offset
int64
,
whence
int
)
(
ret
int64
,
err
error
)
{
switch
whence
{
default
:
return
0
,
errWhence
...
...
@@ -191,7 +185,7 @@ func (f *MemFile) Seek(offset int64, whence int) (ret int64, err error) {
// GetAcceptEncodingZip returns accept encoding format in http header.
// zip is first, then deflate if both accepted.
// If no accepted, return empty string.
func
G
etAcceptEncodingZip
(
r
*
http
.
Request
)
string
{
func
g
etAcceptEncodingZip
(
r
*
http
.
Request
)
string
{
ss
:=
r
.
Header
.
Get
(
"Accept-Encoding"
)
ss
=
strings
.
ToLower
(
ss
)
if
strings
.
Contains
(
ss
,
"gzip"
)
{
...
...
@@ -203,22 +197,3 @@ func GetAcceptEncodingZip(r *http.Request) string {
}
return
""
}
// CloseZWriter closes the io.Writer after compressing static file.
func
CloseZWriter
(
zwriter
io
.
Writer
)
{
if
zwriter
==
nil
{
return
}
switch
zwriter
.
(
type
)
{
case
*
gzip
.
Writer
:
zwriter
.
(
*
gzip
.
Writer
)
.
Close
()
case
*
flate
.
Writer
:
zwriter
.
(
*
flate
.
Writer
)
.
Close
()
//其他情况不close, 保持和默认(非压缩)行为一致
/*
case io.WriteCloser:
zwriter.(io.WriteCloser).Close()
*/
}
}
reload.go
View file @
82ca85dc
// Zero-downtime restarts in Go.
package
beego
import
(
...
...
router.go
View file @
82ca85dc
...
...
@@ -7,8 +7,6 @@ import (
"net"
"net/http"
"net/url"
"os"
"path"
"reflect"
"regexp"
"runtime"
...
...
@@ -33,7 +31,7 @@ const (
var
(
// supported http methods.
HTTPMETHOD
=
[]
string
{
"get"
,
"post"
,
"put"
,
"delete"
,
"patch"
,
"options"
,
"head"
}
HTTPMETHOD
=
[]
string
{
"get"
,
"post"
,
"put"
,
"delete"
,
"patch"
,
"options"
,
"head"
,
"trace"
,
"connect"
}
// these beego.Controller's methods shouldn't reflect to AutoRouter
exceptMethod
=
[]
string
{
"Init"
,
"Prepare"
,
"Finish"
,
"Render"
,
"RenderString"
,
"RenderBytes"
,
"Redirect"
,
"Abort"
,
"StopRun"
,
"UrlFor"
,
"ServeJson"
,
"ServeJsonp"
,
...
...
@@ -544,86 +542,24 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
http
.
Error
(
w
,
"Method Not Allowed"
,
405
)
goto
Admin
}
if
do_filter
(
BeforeRouter
)
{
//static file server
if
serverStaticRouter
(
context
)
{
goto
Admin
}
//static file server
for
prefix
,
staticDir
:=
range
StaticDir
{
if
len
(
prefix
)
==
0
{
continue
}
if
r
.
URL
.
Path
==
"/favicon.ico"
{
file
:=
path
.
Join
(
staticDir
,
r
.
URL
.
Path
)
if
utils
.
FileExists
(
file
)
{
http
.
ServeFile
(
w
,
r
,
file
)
w
.
started
=
true
goto
Admin
}
}
if
strings
.
HasPrefix
(
r
.
URL
.
Path
,
prefix
)
{
if
len
(
r
.
URL
.
Path
)
>
len
(
prefix
)
&&
r
.
URL
.
Path
[
len
(
prefix
)]
!=
'/'
{
continue
}
if
r
.
URL
.
Path
==
prefix
&&
prefix
[
len
(
prefix
)
-
1
]
!=
'/'
{
http
.
Redirect
(
rw
,
r
,
r
.
URL
.
Path
+
"/"
,
302
)
goto
Admin
}
file
:=
path
.
Join
(
staticDir
,
r
.
URL
.
Path
[
len
(
prefix
)
:
])
finfo
,
err
:=
os
.
Stat
(
file
)
if
err
!=
nil
{
if
RunMode
==
"dev"
{
Warn
(
err
)
}
http
.
NotFound
(
w
,
r
)
goto
Admin
}
//if the request is dir and DirectoryIndex is false then
if
finfo
.
IsDir
()
&&
!
DirectoryIndex
{
middleware
.
Exception
(
"403"
,
rw
,
r
,
"403 Forbidden"
)
goto
Admin
}
//This block obtained from (https://github.com/smithfox/beego) - it should probably get merged into astaxie/beego after a pull request
isStaticFileToCompress
:=
false
if
StaticExtensionsToGzip
!=
nil
&&
len
(
StaticExtensionsToGzip
)
>
0
{
for
_
,
statExtension
:=
range
StaticExtensionsToGzip
{
if
strings
.
HasSuffix
(
strings
.
ToLower
(
file
),
strings
.
ToLower
(
statExtension
))
{
isStaticFileToCompress
=
true
break
}
}
}
if
isStaticFileToCompress
{
if
EnableGzip
{
w
.
contentEncoding
=
GetAcceptEncodingZip
(
r
)
}
memzipfile
,
err
:=
OpenMemZipFile
(
file
,
w
.
contentEncoding
)
if
err
!=
nil
{
return
}
w
.
InitHeadContent
(
finfo
.
Size
())
http
.
ServeContent
(
w
,
r
,
file
,
finfo
.
ModTime
(),
memzipfile
)
}
else
{
http
.
ServeFile
(
w
,
r
,
file
)
}
w
.
started
=
true
goto
Admin
if
context
.
Input
.
IsPost
()
{
if
CopyRequestBody
&&
!
context
.
Input
.
IsUpload
()
{
context
.
Input
.
CopyBody
()
}
context
.
Input
.
ParseFormOrMulitForm
(
MaxMemory
)
}
if
do_filter
(
AfterStatic
)
{
if
do_filter
(
BeforeRouter
)
{
goto
Admin
}
if
CopyRequestBody
{
context
.
Input
.
Body
()
if
do_filter
(
AfterStatic
)
{
goto
Admin
}
if
context
.
Input
.
RunController
!=
nil
&&
context
.
Input
.
RunMethod
!=
""
{
...
...
@@ -757,9 +693,6 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
}
if
findrouter
{
if
r
.
Method
==
"POST"
{
r
.
ParseMultipartForm
(
MaxMemory
)
}
//execute middleware filters
if
do_filter
(
BeforeExec
)
{
goto
Admin
...
...
@@ -830,9 +763,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
}
}
Admin
:
do_filter
(
FinishRouter
)
Admin
:
//admin module record QPS
if
EnableAdmin
{
timeend
:=
time
.
Since
(
starttime
)
...
...
@@ -891,10 +823,9 @@ func (p *ControllerRegistor) getRunMethod(method string, context *beecontext.Con
//responseWriter is a wrapper for the http.ResponseWriter
//started set to true if response was written to then don't execute other handler
type
responseWriter
struct
{
writer
http
.
ResponseWriter
started
bool
status
int
contentEncoding
string
writer
http
.
ResponseWriter
started
bool
status
int
}
// Header returns the header map that will be sent by WriteHeader.
...
...
@@ -902,17 +833,6 @@ func (w *responseWriter) Header() http.Header {
return
w
.
writer
.
Header
()
}
// Init content-length header.
func
(
w
*
responseWriter
)
InitHeadContent
(
contentlength
int64
)
{
if
w
.
contentEncoding
==
"gzip"
{
w
.
Header
()
.
Set
(
"Content-Encoding"
,
"gzip"
)
}
else
if
w
.
contentEncoding
==
"deflate"
{
w
.
Header
()
.
Set
(
"Content-Encoding"
,
"deflate"
)
}
else
{
w
.
Header
()
.
Set
(
"Content-Length"
,
strconv
.
FormatInt
(
contentlength
,
10
))
}
}
// Write writes the data to the connection as part of an HTTP reply,
// and sets `started` to true.
// started means the response has sent out.
...
...
session/sess_couchbase.go
→
session/
couchbase/
sess_couchbase.go
View file @
82ca85dc
package
session
import
(
"github.com/couchbaselabs/go-couchbase"
"net/http"
"strings"
"sync"
"github.com/couchbaselabs/go-couchbase"
"github.com/astaxie/beego/session"
)
var
couchbpder
=
&
CouchbaseProvider
{}
...
...
@@ -70,7 +73,7 @@ func (cs *CouchbaseSessionStore) SessionRelease(w http.ResponseWriter) {
return
}
bo
,
err
:=
e
ncodeGob
(
cs
.
values
)
bo
,
err
:=
session
.
E
ncodeGob
(
cs
.
values
)
if
err
!=
nil
{
return
}
...
...
@@ -117,7 +120,7 @@ func (cp *CouchbaseProvider) SessionInit(maxlifetime int64, savePath string) err
}
// read couchbase session by sid
func
(
cp
*
CouchbaseProvider
)
SessionRead
(
sid
string
)
(
SessionStore
,
error
)
{
func
(
cp
*
CouchbaseProvider
)
SessionRead
(
sid
string
)
(
session
.
SessionStore
,
error
)
{
cp
.
b
=
cp
.
getBucket
()
var
doc
[]
byte
...
...
@@ -127,7 +130,7 @@ func (cp *CouchbaseProvider) SessionRead(sid string) (SessionStore, error) {
if
doc
==
nil
{
kv
=
make
(
map
[
interface
{}]
interface
{})
}
else
{
kv
,
err
=
d
ecodeGob
(
doc
)
kv
,
err
=
session
.
D
ecodeGob
(
doc
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -150,7 +153,7 @@ func (cp *CouchbaseProvider) SessionExist(sid string) bool {
}
}
func
(
cp
*
CouchbaseProvider
)
SessionRegenerate
(
oldsid
,
sid
string
)
(
SessionStore
,
error
)
{
func
(
cp
*
CouchbaseProvider
)
SessionRegenerate
(
oldsid
,
sid
string
)
(
session
.
SessionStore
,
error
)
{
cp
.
b
=
cp
.
getBucket
()
var
doc
[]
byte
...
...
@@ -172,7 +175,7 @@ func (cp *CouchbaseProvider) SessionRegenerate(oldsid, sid string) (SessionStore
if
doc
==
nil
{
kv
=
make
(
map
[
interface
{}]
interface
{})
}
else
{
kv
,
err
=
d
ecodeGob
(
doc
)
kv
,
err
=
session
.
D
ecodeGob
(
doc
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -199,5 +202,5 @@ func (cp *CouchbaseProvider) SessionAll() int {
}
func
init
()
{
Register
(
"couchbase"
,
couchbpder
)
session
.
Register
(
"couchbase"
,
couchbpder
)
}
session/sess_mysql.go
→
session/
mysql/
sess_mysql.go
View file @
82ca85dc
...
...
@@ -14,6 +14,8 @@ import (
"sync"
"time"
"github.com/astaxie/beego/session"
_
"github.com/go-sql-driver/mysql"
)
...
...
@@ -73,7 +75,7 @@ func (st *MysqlSessionStore) SessionID() string {
// must call this method to save values to database.
func
(
st
*
MysqlSessionStore
)
SessionRelease
(
w
http
.
ResponseWriter
)
{
defer
st
.
c
.
Close
()
b
,
err
:=
e
ncodeGob
(
st
.
values
)
b
,
err
:=
session
.
E
ncodeGob
(
st
.
values
)
if
err
!=
nil
{
return
}
...
...
@@ -106,7 +108,7 @@ func (mp *MysqlProvider) SessionInit(maxlifetime int64, savePath string) error {
}
// get mysql session by sid
func
(
mp
*
MysqlProvider
)
SessionRead
(
sid
string
)
(
SessionStore
,
error
)
{
func
(
mp
*
MysqlProvider
)
SessionRead
(
sid
string
)
(
session
.
SessionStore
,
error
)
{
c
:=
mp
.
connectInit
()
row
:=
c
.
QueryRow
(
"select session_data from session where session_key=?"
,
sid
)
var
sessiondata
[]
byte
...
...
@@ -119,7 +121,7 @@ func (mp *MysqlProvider) SessionRead(sid string) (SessionStore, error) {
if
len
(
sessiondata
)
==
0
{
kv
=
make
(
map
[
interface
{}]
interface
{})
}
else
{
kv
,
err
=
d
ecodeGob
(
sessiondata
)
kv
,
err
=
session
.
D
ecodeGob
(
sessiondata
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -143,7 +145,7 @@ func (mp *MysqlProvider) SessionExist(sid string) bool {
}
// generate new sid for mysql session
func
(
mp
*
MysqlProvider
)
SessionRegenerate
(
oldsid
,
sid
string
)
(
SessionStore
,
error
)
{
func
(
mp
*
MysqlProvider
)
SessionRegenerate
(
oldsid
,
sid
string
)
(
session
.
SessionStore
,
error
)
{
c
:=
mp
.
connectInit
()
row
:=
c
.
QueryRow
(
"select session_data from session where session_key=?"
,
oldsid
)
var
sessiondata
[]
byte
...
...
@@ -156,7 +158,7 @@ func (mp *MysqlProvider) SessionRegenerate(oldsid, sid string) (SessionStore, er
if
len
(
sessiondata
)
==
0
{
kv
=
make
(
map
[
interface
{}]
interface
{})
}
else
{
kv
,
err
=
d
ecodeGob
(
sessiondata
)
kv
,
err
=
session
.
D
ecodeGob
(
sessiondata
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -194,5 +196,5 @@ func (mp *MysqlProvider) SessionAll() int {
}
func
init
()
{
Register
(
"mysql"
,
mysqlpder
)
session
.
Register
(
"mysql"
,
mysqlpder
)
}
session/sess_postgresql.go
→
session/
postgres/
sess_postgresql.go
View file @
82ca85dc
...
...
@@ -34,6 +34,9 @@ import (
"net/http"
"sync"
"time"
"github.com/astaxie/beego/session"
_
"github.com/lib/pq"
)
...
...
@@ -93,7 +96,7 @@ func (st *PostgresqlSessionStore) SessionID() string {
// must call this method to save values to database.
func
(
st
*
PostgresqlSessionStore
)
SessionRelease
(
w
http
.
ResponseWriter
)
{
defer
st
.
c
.
Close
()
b
,
err
:=
e
ncodeGob
(
st
.
values
)
b
,
err
:=
session
.
E
ncodeGob
(
st
.
values
)
if
err
!=
nil
{
return
}
...
...
@@ -126,7 +129,7 @@ func (mp *PostgresqlProvider) SessionInit(maxlifetime int64, savePath string) er
}
// get postgresql session by sid
func
(
mp
*
PostgresqlProvider
)
SessionRead
(
sid
string
)
(
SessionStore
,
error
)
{
func
(
mp
*
PostgresqlProvider
)
SessionRead
(
sid
string
)
(
session
.
SessionStore
,
error
)
{
c
:=
mp
.
connectInit
()
row
:=
c
.
QueryRow
(
"select session_data from session where session_key=$1"
,
sid
)
var
sessiondata
[]
byte
...
...
@@ -138,7 +141,7 @@ func (mp *PostgresqlProvider) SessionRead(sid string) (SessionStore, error) {
if
err
!=
nil
{
return
nil
,
err
}
}
else
if
err
!=
nil
{
}
else
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -146,7 +149,7 @@ func (mp *PostgresqlProvider) SessionRead(sid string) (SessionStore, error) {
if
len
(
sessiondata
)
==
0
{
kv
=
make
(
map
[
interface
{}]
interface
{})
}
else
{
kv
,
err
=
d
ecodeGob
(
sessiondata
)
kv
,
err
=
session
.
D
ecodeGob
(
sessiondata
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -162,7 +165,7 @@ func (mp *PostgresqlProvider) SessionExist(sid string) bool {
row
:=
c
.
QueryRow
(
"select session_data from session where session_key=$1"
,
sid
)
var
sessiondata
[]
byte
err
:=
row
.
Scan
(
&
sessiondata
)
if
err
==
sql
.
ErrNoRows
{
return
false
}
else
{
...
...
@@ -171,21 +174,21 @@ func (mp *PostgresqlProvider) SessionExist(sid string) bool {
}
// generate new sid for postgresql session
func
(
mp
*
PostgresqlProvider
)
SessionRegenerate
(
oldsid
,
sid
string
)
(
SessionStore
,
error
)
{
func
(
mp
*
PostgresqlProvider
)
SessionRegenerate
(
oldsid
,
sid
string
)
(
session
.
SessionStore
,
error
)
{
c
:=
mp
.
connectInit
()
row
:=
c
.
QueryRow
(
"select session_data from session where session_key=$1"
,
oldsid
)
var
sessiondata
[]
byte
err
:=
row
.
Scan
(
&
sessiondata
)
if
err
==
sql
.
ErrNoRows
{
c
.
Exec
(
"insert into session(session_key,session_data,session_expiry) values($1,$2,$3)"
,
oldsid
,
""
,
time
.
Now
()
.
Format
(
time
.
RFC3339
))
oldsid
,
""
,
time
.
Now
()
.
Format
(
time
.
RFC3339
))
}
c
.
Exec
(
"update session set session_key=$1 where session_key=$2"
,
sid
,
oldsid
)
var
kv
map
[
interface
{}]
interface
{}
if
len
(
sessiondata
)
==
0
{
kv
=
make
(
map
[
interface
{}]
interface
{})
}
else
{
kv
,
err
=
d
ecodeGob
(
sessiondata
)
kv
,
err
=
session
.
D
ecodeGob
(
sessiondata
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -223,5 +226,5 @@ func (mp *PostgresqlProvider) SessionAll() int {
}
func
init
()
{
Register
(
"postgresql"
,
postgresqlpder
)
session
.
Register
(
"postgresql"
,
postgresqlpder
)
}
session/sess_redis.go
→
session/
redis/
sess_redis.go
View file @
82ca85dc
...
...
@@ -6,6 +6,8 @@ import (
"strings"
"sync"
"github.com/astaxie/beego/session"
"github.com/beego/redigo/redis"
)
...
...
@@ -77,7 +79,7 @@ func (rs *RedisSessionStore) SessionRelease(w http.ResponseWriter) {
return
}
b
,
err
:=
e
ncodeGob
(
rs
.
values
)
b
,
err
:=
session
.
E
ncodeGob
(
rs
.
values
)
if
err
!=
nil
{
return
}
...
...
@@ -134,7 +136,7 @@ func (rp *RedisProvider) SessionInit(maxlifetime int64, savePath string) error {
}
// read redis session by sid
func
(
rp
*
RedisProvider
)
SessionRead
(
sid
string
)
(
SessionStore
,
error
)
{
func
(
rp
*
RedisProvider
)
SessionRead
(
sid
string
)
(
session
.
SessionStore
,
error
)
{
c
:=
rp
.
poollist
.
Get
()
defer
c
.
Close
()
...
...
@@ -143,7 +145,7 @@ func (rp *RedisProvider) SessionRead(sid string) (SessionStore, error) {
if
len
(
kvs
)
==
0
{
kv
=
make
(
map
[
interface
{}]
interface
{})
}
else
{
kv
,
err
=
d
ecodeGob
([]
byte
(
kvs
))
kv
,
err
=
session
.
D
ecodeGob
([]
byte
(
kvs
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -166,7 +168,7 @@ func (rp *RedisProvider) SessionExist(sid string) bool {
}
// generate new sid for redis session
func
(
rp
*
RedisProvider
)
SessionRegenerate
(
oldsid
,
sid
string
)
(
SessionStore
,
error
)
{
func
(
rp
*
RedisProvider
)
SessionRegenerate
(
oldsid
,
sid
string
)
(
session
.
SessionStore
,
error
)
{
c
:=
rp
.
poollist
.
Get
()
defer
c
.
Close
()
...
...
@@ -185,7 +187,7 @@ func (rp *RedisProvider) SessionRegenerate(oldsid, sid string) (SessionStore, er
if
len
(
kvs
)
==
0
{
kv
=
make
(
map
[
interface
{}]
interface
{})
}
else
{
kv
,
err
=
d
ecodeGob
([]
byte
(
kvs
))
kv
,
err
=
session
.
D
ecodeGob
([]
byte
(
kvs
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -215,5 +217,5 @@ func (rp *RedisProvider) SessionAll() int {
}
func
init
()
{
Register
(
"redis"
,
redispder
)
session
.
Register
(
"redis"
,
redispder
)
}
session/sess_file.go
View file @
82ca85dc
...
...
@@ -70,7 +70,7 @@ func (fs *FileSessionStore) SessionID() string {
// Write file session to local file with Gob string
func
(
fs
*
FileSessionStore
)
SessionRelease
(
w
http
.
ResponseWriter
)
{
defer
fs
.
f
.
Close
()
b
,
err
:=
e
ncodeGob
(
fs
.
values
)
b
,
err
:=
E
ncodeGob
(
fs
.
values
)
if
err
!=
nil
{
return
}
...
...
@@ -123,7 +123,7 @@ func (fp *FileProvider) SessionRead(sid string) (SessionStore, error) {
if
len
(
b
)
==
0
{
kv
=
make
(
map
[
interface
{}]
interface
{})
}
else
{
kv
,
err
=
d
ecodeGob
(
b
)
kv
,
err
=
D
ecodeGob
(
b
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -222,7 +222,7 @@ func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (SessionStore, err
if
len
(
b
)
==
0
{
kv
=
make
(
map
[
interface
{}]
interface
{})
}
else
{
kv
,
err
=
d
ecodeGob
(
b
)
kv
,
err
=
D
ecodeGob
(
b
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
session/sess_test.go
View file @
82ca85dc
...
...
@@ -10,11 +10,11 @@ func Test_gob(t *testing.T) {
a
:=
make
(
map
[
interface
{}]
interface
{})
a
[
"username"
]
=
"astaxie"
a
[
12
]
=
234
b
,
err
:=
e
ncodeGob
(
a
)
b
,
err
:=
E
ncodeGob
(
a
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
c
,
err
:=
d
ecodeGob
(
b
)
c
,
err
:=
D
ecodeGob
(
b
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
...
...
session/sess_utils.go
View file @
82ca85dc
...
...
@@ -27,7 +27,7 @@ func init() {
gob
.
Register
(
map
[
int
]
int64
{})
}
func
e
ncodeGob
(
obj
map
[
interface
{}]
interface
{})
([]
byte
,
error
)
{
func
E
ncodeGob
(
obj
map
[
interface
{}]
interface
{})
([]
byte
,
error
)
{
buf
:=
bytes
.
NewBuffer
(
nil
)
enc
:=
gob
.
NewEncoder
(
buf
)
err
:=
enc
.
Encode
(
obj
)
...
...
@@ -37,7 +37,7 @@ func encodeGob(obj map[interface{}]interface{}) ([]byte, error) {
return
buf
.
Bytes
(),
nil
}
func
d
ecodeGob
(
encoded
[]
byte
)
(
map
[
interface
{}]
interface
{},
error
)
{
func
D
ecodeGob
(
encoded
[]
byte
)
(
map
[
interface
{}]
interface
{},
error
)
{
buf
:=
bytes
.
NewBuffer
(
encoded
)
dec
:=
gob
.
NewDecoder
(
buf
)
var
out
map
[
interface
{}]
interface
{}
...
...
@@ -97,8 +97,8 @@ func decrypt(block cipher.Block, value []byte) ([]byte, error) {
func
encodeCookie
(
block
cipher
.
Block
,
hashKey
,
name
string
,
value
map
[
interface
{}]
interface
{})
(
string
,
error
)
{
var
err
error
var
b
[]
byte
// 1.
e
ncodeGob.
if
b
,
err
=
e
ncodeGob
(
value
);
err
!=
nil
{
// 1.
E
ncodeGob.
if
b
,
err
=
E
ncodeGob
(
value
);
err
!=
nil
{
return
""
,
err
}
// 2. Encrypt (optional).
...
...
@@ -158,8 +158,8 @@ func decodeCookie(block cipher.Block, hashKey, name, value string, gcmaxlifetime
if
b
,
err
=
decrypt
(
block
,
b
);
err
!=
nil
{
return
nil
,
err
}
// 5.
d
ecodeGob.
if
dst
,
err
:=
d
ecodeGob
(
b
);
err
!=
nil
{
// 5.
D
ecodeGob.
if
dst
,
err
:=
D
ecodeGob
(
b
);
err
!=
nil
{
return
nil
,
err
}
else
{
return
dst
,
nil
...
...
staticfile.go
0 → 100644
View file @
82ca85dc
package
beego
import
(
"net/http"
"os"
"path"
"strconv"
"strings"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/middleware"
"github.com/astaxie/beego/utils"
)
func
serverStaticRouter
(
ctx
*
context
.
Context
)
bool
{
requestPath
:=
path
.
Clean
(
ctx
.
Input
.
Request
.
URL
.
Path
)
for
prefix
,
staticDir
:=
range
StaticDir
{
if
len
(
prefix
)
==
0
{
continue
}
if
requestPath
==
"/favicon.ico"
{
file
:=
path
.
Join
(
staticDir
,
requestPath
)
if
utils
.
FileExists
(
file
)
{
http
.
ServeFile
(
ctx
.
ResponseWriter
,
ctx
.
Request
,
file
)
return
true
}
}
if
strings
.
HasPrefix
(
requestPath
,
prefix
)
{
if
len
(
requestPath
)
>
len
(
prefix
)
&&
requestPath
[
len
(
prefix
)]
!=
'/'
{
continue
}
if
requestPath
==
prefix
&&
prefix
[
len
(
prefix
)
-
1
]
!=
'/'
{
http
.
Redirect
(
ctx
.
ResponseWriter
,
ctx
.
Request
,
requestPath
+
"/"
,
302
)
return
true
}
file
:=
path
.
Join
(
staticDir
,
requestPath
[
len
(
prefix
)
:
])
finfo
,
err
:=
os
.
Stat
(
file
)
if
err
!=
nil
{
if
RunMode
==
"dev"
{
Warn
(
err
)
}
http
.
NotFound
(
ctx
.
ResponseWriter
,
ctx
.
Request
)
return
true
}
//if the request is dir and DirectoryIndex is false then
if
finfo
.
IsDir
()
&&
!
DirectoryIndex
{
middleware
.
Exception
(
"403"
,
ctx
.
ResponseWriter
,
ctx
.
Request
,
"403 Forbidden"
)
return
true
}
//This block obtained from (https://github.com/smithfox/beego) - it should probably get merged into astaxie/beego after a pull request
isStaticFileToCompress
:=
false
if
StaticExtensionsToGzip
!=
nil
&&
len
(
StaticExtensionsToGzip
)
>
0
{
for
_
,
statExtension
:=
range
StaticExtensionsToGzip
{
if
strings
.
HasSuffix
(
strings
.
ToLower
(
file
),
strings
.
ToLower
(
statExtension
))
{
isStaticFileToCompress
=
true
break
}
}
}
if
isStaticFileToCompress
{
var
contentEncoding
string
if
EnableGzip
{
contentEncoding
=
getAcceptEncodingZip
(
ctx
.
Request
)
}
memzipfile
,
err
:=
openMemZipFile
(
file
,
contentEncoding
)
if
err
!=
nil
{
return
true
}
if
contentEncoding
==
"gzip"
{
ctx
.
Output
.
Header
(
"Content-Encoding"
,
"gzip"
)
}
else
if
contentEncoding
==
"deflate"
{
ctx
.
Output
.
Header
(
"Content-Encoding"
,
"deflate"
)
}
else
{
ctx
.
Output
.
Header
(
"Content-Length"
,
strconv
.
FormatInt
(
finfo
.
Size
(),
10
))
}
http
.
ServeContent
(
ctx
.
ResponseWriter
,
ctx
.
Request
,
file
,
finfo
.
ModTime
(),
memzipfile
)
}
else
{
http
.
ServeFile
(
ctx
.
ResponseWriter
,
ctx
.
Request
,
file
)
}
return
true
}
}
return
false
}
toolbox/debug.go
View file @
82ca85dc
//
most reference from github.com/realint/dbgutil
//
Here are the features: healthcheck, profile, statistics and task.
package
toolbox
import
(
...
...
@@ -34,7 +34,6 @@ func Display(data ...interface{}) {
display
(
true
,
data
...
)
}
// return data print string
func
GetDisplayString
(
data
...
interface
{})
string
{
return
display
(
false
,
data
...
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
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 comment