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
d3b54c46
Commit
d3b54c46
authored
Mar 22, 2016
by
astaxie
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1808 from JessonChan/gzip_improve
Gzip improve
parents
ba7a809d
7bad3d1c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
75 additions
and
28 deletions
+75
-28
beego.go
beego.go
+2
-0
config.go
config.go
+1
-1
acceptencoder.go
context/acceptencoder.go
+60
-27
hooks.go
hooks.go
+12
-0
No files found.
beego.go
View file @
d3b54c46
...
...
@@ -51,6 +51,7 @@ func AddAPPStartHook(hf hookfunc) {
// beego.Run(":8089")
// beego.Run("127.0.0.1:8089")
func
Run
(
params
...
string
)
{
initBeforeHTTPRun
()
if
len
(
params
)
>
0
&&
params
[
0
]
!=
""
{
...
...
@@ -74,6 +75,7 @@ func initBeforeHTTPRun() {
AddAPPStartHook
(
registerDocs
)
AddAPPStartHook
(
registerTemplate
)
AddAPPStartHook
(
registerAdmin
)
AddAPPStartHook
(
registerGzip
)
for
_
,
hk
:=
range
hooks
{
if
err
:=
hk
();
err
!=
nil
{
...
...
config.go
View file @
d3b54c46
...
...
@@ -353,7 +353,7 @@ func (b *beegoAppConfig) String(key string) string {
}
func
(
b
*
beegoAppConfig
)
Strings
(
key
string
)
[]
string
{
if
v
:=
b
.
innerConfig
.
Strings
(
BConfig
.
RunMode
+
"::"
+
key
);
v
[
0
]
!=
""
{
if
v
:=
b
.
innerConfig
.
Strings
(
BConfig
.
RunMode
+
"::"
+
key
);
len
(
v
)
>
0
{
return
v
}
return
b
.
innerConfig
.
Strings
(
key
)
...
...
context/acceptencoder.go
View file @
d3b54c46
...
...
@@ -27,6 +27,33 @@ import (
"sync"
)
var
(
//Default size==20B same as nginx
defaultGzipMinLength
=
20
//Content will only be compressed if content length is either unknown or greater than gzipMinLength.
gzipMinLength
=
defaultGzipMinLength
//The compression level used for deflate compression. (0-9).
gzipCompressLevel
int
//List of HTTP methods to compress. If not set, only GET requests are compressed.
includedMethods
map
[
string
]
bool
getMethodOnly
bool
)
func
InitGzip
(
minLength
,
compressLevel
int
,
methods
[]
string
)
{
if
minLength
>=
0
{
gzipMinLength
=
minLength
}
gzipCompressLevel
=
compressLevel
if
gzipCompressLevel
<
flate
.
NoCompression
||
gzipCompressLevel
>
flate
.
BestCompression
{
gzipCompressLevel
=
flate
.
BestSpeed
}
getMethodOnly
=
(
len
(
methods
)
==
0
)
||
(
len
(
methods
)
==
1
&&
strings
.
ToUpper
(
methods
[
0
])
==
"GET"
)
includedMethods
=
make
(
map
[
string
]
bool
,
len
(
methods
))
for
_
,
v
:=
range
methods
{
includedMethods
[
strings
.
ToUpper
(
v
)]
=
true
}
}
type
resetWriter
interface
{
io
.
Writer
Reset
(
w
io
.
Writer
)
...
...
@@ -41,20 +68,20 @@ func (n nopResetWriter) Reset(w io.Writer) {
}
type
acceptEncoder
struct
{
name
string
levelEncode
func
(
int
)
resetWriter
bestSpeedPool
*
sync
.
Pool
bestCompressionPool
*
sync
.
Pool
name
string
levelEncode
func
(
int
)
resetWriter
customCompressLevelPool
*
sync
.
Pool
bestCompressionPool
*
sync
.
Pool
}
func
(
ac
acceptEncoder
)
encode
(
wr
io
.
Writer
,
level
int
)
resetWriter
{
if
ac
.
bestSpeed
Pool
==
nil
||
ac
.
bestCompressionPool
==
nil
{
if
ac
.
customCompressLevel
Pool
==
nil
||
ac
.
bestCompressionPool
==
nil
{
return
nopResetWriter
{
wr
}
}
var
rwr
resetWriter
switch
level
{
case
flate
.
BestSpeed
:
rwr
=
ac
.
bestSpeed
Pool
.
Get
()
.
(
resetWriter
)
rwr
=
ac
.
customCompressLevel
Pool
.
Get
()
.
(
resetWriter
)
case
flate
.
BestCompression
:
rwr
=
ac
.
bestCompressionPool
.
Get
()
.
(
resetWriter
)
default
:
...
...
@@ -65,13 +92,18 @@ func (ac acceptEncoder) encode(wr io.Writer, level int) resetWriter {
}
func
(
ac
acceptEncoder
)
put
(
wr
resetWriter
,
level
int
)
{
if
ac
.
bestSpeed
Pool
==
nil
||
ac
.
bestCompressionPool
==
nil
{
if
ac
.
customCompressLevel
Pool
==
nil
||
ac
.
bestCompressionPool
==
nil
{
return
}
wr
.
Reset
(
nil
)
//notice
//compressionLevel==BestCompression DOES NOT MATTER
//sync.Pool will not memory leak
switch
level
{
case
flate
.
BestSpeed
:
ac
.
bestSpeed
Pool
.
Put
(
wr
)
case
gzipCompressLevel
:
ac
.
customCompressLevel
Pool
.
Put
(
wr
)
case
flate
.
BestCompression
:
ac
.
bestCompressionPool
.
Put
(
wr
)
}
...
...
@@ -79,28 +111,22 @@ func (ac acceptEncoder) put(wr resetWriter, level int) {
var
(
noneCompressEncoder
=
acceptEncoder
{
""
,
nil
,
nil
,
nil
}
gzipCompressEncoder
=
acceptEncoder
{
"gzip"
,
func
(
level
int
)
resetWriter
{
wr
,
_
:=
gzip
.
NewWriterLevel
(
nil
,
level
);
return
wr
},
&
sync
.
Pool
{
New
:
func
()
interface
{}
{
wr
,
_
:=
gzip
.
NewWriterLevel
(
nil
,
flate
.
BestSpeed
);
return
wr
},
},
&
sync
.
Pool
{
New
:
func
()
interface
{}
{
wr
,
_
:=
gzip
.
NewWriterLevel
(
nil
,
flate
.
BestCompression
);
return
wr
},
},
gzipCompressEncoder
=
acceptEncoder
{
name
:
"gzip"
,
levelEncode
:
func
(
level
int
)
resetWriter
{
wr
,
_
:=
gzip
.
NewWriterLevel
(
nil
,
level
);
return
wr
},
customCompressLevelPool
:
&
sync
.
Pool
{
New
:
func
()
interface
{}
{
wr
,
_
:=
gzip
.
NewWriterLevel
(
nil
,
gzipCompressLevel
);
return
wr
}},
bestCompressionPool
:
&
sync
.
Pool
{
New
:
func
()
interface
{}
{
wr
,
_
:=
gzip
.
NewWriterLevel
(
nil
,
flate
.
BestCompression
);
return
wr
}},
}
//according to the sec :http://tools.ietf.org/html/rfc2616#section-3.5 ,the deflate compress in http is zlib indeed
//deflate
//The "zlib" format defined in RFC 1950 [31] in combination with
//the "deflate" compression mechanism described in RFC 1951 [29].
deflateCompressEncoder
=
acceptEncoder
{
"deflate"
,
func
(
level
int
)
resetWriter
{
wr
,
_
:=
zlib
.
NewWriterLevel
(
nil
,
level
);
return
wr
},
&
sync
.
Pool
{
New
:
func
()
interface
{}
{
wr
,
_
:=
zlib
.
NewWriterLevel
(
nil
,
flate
.
BestSpeed
);
return
wr
},
},
&
sync
.
Pool
{
New
:
func
()
interface
{}
{
wr
,
_
:=
zlib
.
NewWriterLevel
(
nil
,
flate
.
BestCompression
);
return
wr
},
},
deflateCompressEncoder
=
acceptEncoder
{
name
:
"deflate"
,
levelEncode
:
func
(
level
int
)
resetWriter
{
wr
,
_
:=
zlib
.
NewWriterLevel
(
nil
,
level
);
return
wr
},
customCompressLevelPool
:
&
sync
.
Pool
{
New
:
func
()
interface
{}
{
wr
,
_
:=
zlib
.
NewWriterLevel
(
nil
,
gzipCompressLevel
);
return
wr
}},
bestCompressionPool
:
&
sync
.
Pool
{
New
:
func
()
interface
{}
{
wr
,
_
:=
zlib
.
NewWriterLevel
(
nil
,
flate
.
BestCompression
);
return
wr
}},
}
)
...
...
@@ -120,7 +146,11 @@ func WriteFile(encoding string, writer io.Writer, file *os.File) (bool, string,
// WriteBody reads writes content to writer by the specific encoding(gzip/deflate)
func
WriteBody
(
encoding
string
,
writer
io
.
Writer
,
content
[]
byte
)
(
bool
,
string
,
error
)
{
return
writeLevel
(
encoding
,
writer
,
bytes
.
NewReader
(
content
),
flate
.
BestSpeed
)
if
encoding
==
""
||
len
(
content
)
<
gzipMinLength
{
_
,
err
:=
writer
.
Write
(
content
)
return
false
,
""
,
err
}
return
writeLevel
(
encoding
,
writer
,
bytes
.
NewReader
(
content
),
gzipCompressLevel
)
}
// writeLevel reads from reader,writes to writer by specific encoding and compress level
...
...
@@ -156,7 +186,10 @@ func ParseEncoding(r *http.Request) string {
if
r
==
nil
{
return
""
}
return
parseEncoding
(
r
)
if
(
getMethodOnly
&&
r
.
Method
==
"GET"
)
||
includedMethods
[
r
.
Method
]
{
return
parseEncoding
(
r
)
}
return
""
}
type
q
struct
{
...
...
hooks.go
View file @
d3b54c46
...
...
@@ -6,6 +6,7 @@ import (
"net/http"
"path/filepath"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/session"
)
...
...
@@ -91,3 +92,14 @@ func registerAdmin() error {
}
return
nil
}
func
registerGzip
()
error
{
if
BConfig
.
EnableGzip
{
context
.
InitGzip
(
AppConfig
.
DefaultInt
(
"gzipMinLength"
,
-
1
),
AppConfig
.
DefaultInt
(
"gzipCompressLevel"
,
-
1
),
AppConfig
.
DefaultStrings
(
"includedMethods"
,
[]
string
{
"GET"
}),
)
}
return
nil
}
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