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
8716185d
authored
2014-10-01 22:10:33 +0800
by
astaxie
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
fix #794
1 parent
31e61334
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
246 additions
and
205 deletions
config.go
config.go
View file @
8716185
...
...
@@ -15,7 +15,6 @@
package
beego
import
(
"errors"
"fmt"
"html/template"
"os"
...
...
@@ -48,8 +47,8 @@ var (
RecoverPanic
bool
// flag of auto recover panic
AutoRender
bool
// flag of render template automatically
ViewsPath
string
RunMode
string
// run mode, "dev" or "prod"
AppConfig
config
.
ConfigContainer
AppConfig
*
beegoAppConfig
RunMode
string
// run mode, "dev" or "prod"
GlobalSessions
*
session
.
Manager
// global session mananger
SessionOn
bool
// flag of starting session auto. default is false.
SessionProvider
string
// default session provider, memory, mysql , redis ,etc.
...
...
@@ -84,6 +83,107 @@ var (
RouterCaseSensitive
bool
// router case sensitive default is true
)
type
beegoAppConfig
struct
{
innerConfig
config
.
ConfigContainer
}
func
newAppConfig
(
AppConfigProvider
,
AppConfigPath
string
)
*
beegoAppConfig
{
ac
,
err
:=
config
.
NewConfig
(
AppConfigProvider
,
AppConfigPath
)
if
err
!=
nil
{
ac
=
config
.
NewFakeConfig
()
}
rac
:=
&
beegoAppConfig
{
ac
}
return
rac
}
func
(
b
*
beegoAppConfig
)
Set
(
key
,
val
string
)
error
{
return
b
.
innerConfig
.
Set
(
key
,
val
)
}
func
(
b
*
beegoAppConfig
)
String
(
key
string
)
string
{
v
:=
b
.
innerConfig
.
String
(
RunMode
+
"::"
+
key
)
if
v
==
""
{
return
b
.
innerConfig
.
String
(
key
)
}
return
v
}
func
(
b
*
beegoAppConfig
)
Strings
(
key
string
)
[]
string
{
v
:=
b
.
innerConfig
.
Strings
(
RunMode
+
"::"
+
key
)
if
len
(
v
)
==
0
{
return
b
.
innerConfig
.
Strings
(
key
)
}
return
v
}
func
(
b
*
beegoAppConfig
)
Int
(
key
string
)
(
int
,
error
)
{
v
,
err
:=
b
.
innerConfig
.
Int
(
RunMode
+
"::"
+
key
)
if
err
!=
nil
{
return
b
.
innerConfig
.
Int
(
key
)
}
return
v
,
nil
}
func
(
b
*
beegoAppConfig
)
Int64
(
key
string
)
(
int64
,
error
)
{
v
,
err
:=
b
.
innerConfig
.
Int64
(
RunMode
+
"::"
+
key
)
if
err
!=
nil
{
return
b
.
innerConfig
.
Int64
(
key
)
}
return
v
,
nil
}
func
(
b
*
beegoAppConfig
)
Bool
(
key
string
)
(
bool
,
error
)
{
v
,
err
:=
b
.
innerConfig
.
Bool
(
RunMode
+
"::"
+
key
)
if
err
!=
nil
{
return
b
.
innerConfig
.
Bool
(
key
)
}
return
v
,
nil
}
func
(
b
*
beegoAppConfig
)
Float
(
key
string
)
(
float64
,
error
)
{
v
,
err
:=
b
.
innerConfig
.
Float
(
RunMode
+
"::"
+
key
)
if
err
!=
nil
{
return
b
.
innerConfig
.
Float
(
key
)
}
return
v
,
nil
}
func
(
b
*
beegoAppConfig
)
DefaultString
(
key
string
,
defaultval
string
)
string
{
return
b
.
innerConfig
.
DefaultString
(
key
,
defaultval
)
}
func
(
b
*
beegoAppConfig
)
DefaultStrings
(
key
string
,
defaultval
[]
string
)
[]
string
{
return
b
.
innerConfig
.
DefaultStrings
(
key
,
defaultval
)
}
func
(
b
*
beegoAppConfig
)
DefaultInt
(
key
string
,
defaultval
int
)
int
{
return
b
.
innerConfig
.
DefaultInt
(
key
,
defaultval
)
}
func
(
b
*
beegoAppConfig
)
DefaultInt64
(
key
string
,
defaultval
int64
)
int64
{
return
b
.
innerConfig
.
DefaultInt64
(
key
,
defaultval
)
}
func
(
b
*
beegoAppConfig
)
DefaultBool
(
key
string
,
defaultval
bool
)
bool
{
return
b
.
innerConfig
.
DefaultBool
(
key
,
defaultval
)
}
func
(
b
*
beegoAppConfig
)
DefaultFloat
(
key
string
,
defaultval
float64
)
float64
{
return
b
.
innerConfig
.
DefaultFloat
(
key
,
defaultval
)
}
func
(
b
*
beegoAppConfig
)
DIY
(
key
string
)
(
interface
{},
error
)
{
return
b
.
innerConfig
.
DIY
(
key
)
}
func
(
b
*
beegoAppConfig
)
GetSection
(
section
string
)
(
map
[
string
]
string
,
error
)
{
return
b
.
innerConfig
.
GetSection
(
section
)
}
func
(
b
*
beegoAppConfig
)
SaveConfigFile
(
filename
string
)
error
{
return
b
.
innerConfig
.
SaveConfigFile
(
filename
)
}
func
init
()
{
// create beego application
BeeApp
=
NewApp
()
...
...
@@ -186,255 +286,196 @@ func init() {
// ParseConfig parsed default config file.
// now only support ini, next will support json.
func
ParseConfig
()
(
err
error
)
{
AppConfig
,
err
=
config
.
NewConfig
(
AppConfigProvider
,
AppConfigPath
)
if
err
!=
nil
{
AppConfig
=
config
.
NewFakeConfig
()
return
err
}
else
{
AppConfig
=
newAppConfig
(
AppConfigProvider
,
AppConfigPath
)
if
v
,
err
:=
GetConfig
(
"string"
,
"HttpAddr"
);
err
==
nil
{
HttpAddr
=
v
.
(
string
)
}
// set the runmode first
if
runmode
:=
AppConfig
.
String
(
"RunMode"
);
runmode
!=
""
{
RunMode
=
runmode
}
if
v
,
err
:=
GetConfig
(
"int"
,
"HttpPort"
);
err
==
nil
{
HttpPort
=
v
.
(
int
)
}
HttpAddr
=
AppConfig
.
String
(
"HttpAddr"
)
if
v
,
err
:=
GetConfig
(
"bool"
,
"EnableHttpListen
"
);
err
==
nil
{
EnableHttpListen
=
v
.
(
bool
)
}
if
v
,
err
:=
AppConfig
.
Int
(
"HttpPort
"
);
err
==
nil
{
HttpPort
=
v
}
if
maxmemory
,
err
:=
GetConfig
(
"int64"
,
"MaxMemory
"
);
err
==
nil
{
MaxMemory
=
maxmemory
.
(
int64
)
}
if
v
,
err
:=
AppConfig
.
Bool
(
"EnableHttpListen
"
);
err
==
nil
{
EnableHttpListen
=
v
}
if
appname
,
_
:=
GetConfig
(
"string"
,
"AppName"
);
appname
!=
""
{
AppName
=
appname
.
(
string
)
}
if
maxmemory
,
err
:=
AppConfig
.
Int64
(
"MaxMemory"
);
err
==
nil
{
MaxMemory
=
maxmemory
}
if
runmode
,
_
:=
GetConfig
(
"string"
,
"RunMode"
);
runmod
e
!=
""
{
RunMode
=
runmode
.
(
string
)
}
if
appname
:=
AppConfig
.
String
(
"AppName"
);
appnam
e
!=
""
{
AppName
=
appname
}
if
autorender
,
err
:=
GetConfig
(
"bool"
,
"AutoRender"
);
err
==
nil
{
AutoRender
=
autorender
.
(
bool
)
}
if
autorender
,
err
:=
AppConfig
.
Bool
(
"AutoRender"
);
err
==
nil
{
AutoRender
=
autorender
}
if
autorecover
,
err
:=
GetConfig
(
"bool"
,
"RecoverPanic"
);
err
==
nil
{
RecoverPanic
=
autorecover
.
(
bool
)
}
if
autorecover
,
err
:=
AppConfig
.
Bool
(
"RecoverPanic"
);
err
==
nil
{
RecoverPanic
=
autorecover
}
if
views
,
_
:=
GetConfig
(
"string"
,
"ViewsPath"
);
views
!=
""
{
ViewsPath
=
views
.
(
string
)
}
if
views
:=
AppConfig
.
String
(
"ViewsPath"
);
views
!=
""
{
ViewsPath
=
views
}
if
sessionon
,
err
:=
GetConfig
(
"bool"
,
"SessionOn"
);
err
==
nil
{
SessionOn
=
sessionon
.
(
bool
)
}
if
sessionon
,
err
:=
AppConfig
.
Bool
(
"SessionOn"
);
err
==
nil
{
SessionOn
=
sessionon
}
if
sessProvider
,
_
:=
GetConfig
(
"string"
,
"SessionProvider"
);
sessProvider
!=
""
{
SessionProvider
=
sessProvider
.
(
string
)
}
if
sessProvider
:=
AppConfig
.
String
(
"SessionProvider"
);
sessProvider
!=
""
{
SessionProvider
=
sessProvider
}
if
sessName
,
_
:=
GetConfig
(
"string"
,
"SessionName"
);
sessName
!=
""
{
SessionName
=
sessName
.
(
string
)
}
if
sessName
:=
AppConfig
.
String
(
"SessionName"
);
sessName
!=
""
{
SessionName
=
sessName
}
if
sesssavepath
,
_
:=
GetConfig
(
"string"
,
"SessionSavePath"
);
sesssavepath
!=
""
{
SessionSavePath
=
sesssavepath
.
(
string
)
}
if
sesssavepath
:=
AppConfig
.
String
(
"SessionSavePath"
);
sesssavepath
!=
""
{
SessionSavePath
=
sesssavepath
}
if
sesshashfunc
,
_
:=
GetConfig
(
"string"
,
"SessionHashFunc"
);
sesshashfunc
!=
""
{
SessionHashFunc
=
sesshashfunc
.
(
string
)
}
if
sesshashfunc
:=
AppConfig
.
String
(
"SessionHashFunc"
);
sesshashfunc
!=
""
{
SessionHashFunc
=
sesshashfunc
}
if
sesshashkey
,
_
:=
GetConfig
(
"string"
,
"SessionHashKey"
);
sesshashkey
!=
""
{
SessionHashKey
=
sesshashkey
.
(
string
)
}
if
sesshashkey
:=
AppConfig
.
String
(
"SessionHashKey"
);
sesshashkey
!=
""
{
SessionHashKey
=
sesshashkey
}
if
sessMaxLifeTime
,
err
:=
GetConfig
(
"int64"
,
"SessionGCMaxLifetime"
);
err
==
nil
&&
sessMaxLifeTime
!=
0
{
SessionGCMaxLifetime
=
sessMaxLifeTime
.
(
int64
)
}
if
sessMaxLifeTime
,
err
:=
AppConfig
.
Int64
(
"SessionGCMaxLifetime"
);
err
==
nil
&&
sessMaxLifeTime
!=
0
{
SessionGCMaxLifetime
=
sessMaxLifeTime
}
if
sesscookielifetime
,
err
:=
GetConfig
(
"int"
,
"SessionCookieLifeTime"
);
err
==
nil
&&
sesscookielifetime
!=
0
{
SessionCookieLifeTime
=
sesscookielifetime
.
(
int
)
}
if
sesscookielifetime
,
err
:=
AppConfig
.
Int
(
"SessionCookieLifeTime"
);
err
==
nil
&&
sesscookielifetime
!=
0
{
SessionCookieLifeTime
=
sesscookielifetime
}
if
usefcgi
,
err
:=
GetConfig
(
"bool"
,
"UseFcgi"
);
err
==
nil
{
UseFcgi
=
usefcgi
.
(
bool
)
}
if
usefcgi
,
err
:=
AppConfig
.
Bool
(
"UseFcgi"
);
err
==
nil
{
UseFcgi
=
usefcgi
}
if
enablegzip
,
err
:=
GetConfig
(
"bool"
,
"EnableGzip"
);
err
==
nil
{
EnableGzip
=
enablegzip
.
(
bool
)
}
if
enablegzip
,
err
:=
AppConfig
.
Bool
(
"EnableGzip"
);
err
==
nil
{
EnableGzip
=
enablegzip
}
if
directoryindex
,
err
:=
GetConfig
(
"bool"
,
"DirectoryIndex"
);
err
==
nil
{
DirectoryIndex
=
directoryindex
.
(
bool
)
}
if
directoryindex
,
err
:=
AppConfig
.
Bool
(
"DirectoryIndex"
);
err
==
nil
{
DirectoryIndex
=
directoryindex
}
if
timeout
,
err
:=
GetConfig
(
"int64"
,
"HttpServerTimeOut"
);
err
==
nil
{
HttpServerTimeOut
=
timeout
.
(
int64
)
}
if
timeout
,
err
:=
AppConfig
.
Int64
(
"HttpServerTimeOut"
);
err
==
nil
{
HttpServerTimeOut
=
timeout
}
if
errorsshow
,
err
:=
GetConfig
(
"bool"
,
"ErrorsShow"
);
err
==
nil
{
ErrorsShow
=
errorsshow
.
(
bool
)
}
if
errorsshow
,
err
:=
AppConfig
.
Bool
(
"ErrorsShow"
);
err
==
nil
{
ErrorsShow
=
errorsshow
}
if
copyrequestbody
,
err
:=
GetConfig
(
"bool"
,
"CopyRequestBody"
);
err
==
nil
{
CopyRequestBody
=
copyrequestbody
.
(
bool
)
}
if
copyrequestbody
,
err
:=
AppConfig
.
Bool
(
"CopyRequestBody"
);
err
==
nil
{
CopyRequestBody
=
copyrequestbody
}
if
xsrfkey
,
_
:=
GetConfig
(
"string"
,
"XSRFKEY"
);
xsrfkey
!=
""
{
XSRFKEY
=
xsrfkey
.
(
string
)
}
if
xsrfkey
:=
AppConfig
.
String
(
"XSRFKEY"
);
xsrfkey
!=
""
{
XSRFKEY
=
xsrfkey
}
if
enablexsrf
,
err
:=
GetConfig
(
"bool"
,
"EnableXSRF"
);
err
==
nil
{
EnableXSRF
=
enablexsrf
.
(
bool
)
}
if
enablexsrf
,
err
:=
AppConfig
.
Bool
(
"EnableXSRF"
);
err
==
nil
{
EnableXSRF
=
enablexsrf
}
if
expire
,
err
:=
GetConfig
(
"int"
,
"XSRFExpire"
);
err
==
nil
{
XSRFExpire
=
expire
.
(
int
)
}
if
expire
,
err
:=
AppConfig
.
Int
(
"XSRFExpire"
);
err
==
nil
{
XSRFExpire
=
expire
}
if
tplleft
,
_
:=
GetConfig
(
"string"
,
"TemplateLeft"
);
tplleft
!=
""
{
TemplateLeft
=
tplleft
.
(
string
)
}
if
tplleft
:=
AppConfig
.
String
(
"TemplateLeft"
);
tplleft
!=
""
{
TemplateLeft
=
tplleft
}
if
tplright
,
_
:=
GetConfig
(
"string"
,
"TemplateRight"
);
tplright
!=
""
{
TemplateRight
=
tplright
.
(
string
)
}
if
tplright
:=
AppConfig
.
String
(
"TemplateRight"
);
tplright
!=
""
{
TemplateRight
=
tplright
}
if
httptls
,
err
:=
GetConfig
(
"bool"
,
"EnableHttpTLS"
);
err
==
nil
{
EnableHttpTLS
=
httptls
.
(
bool
)
}
if
httptls
,
err
:=
AppConfig
.
Bool
(
"EnableHttpTLS"
);
err
==
nil
{
EnableHttpTLS
=
httptls
}
if
httpsport
,
err
:=
GetConfig
(
"int"
,
"HttpsPort"
);
err
==
nil
{
HttpsPort
=
httpsport
.
(
int
)
}
if
httpsport
,
err
:=
AppConfig
.
Int
(
"HttpsPort"
);
err
==
nil
{
HttpsPort
=
httpsport
}
if
certfile
,
_
:=
GetConfig
(
"string"
,
"HttpCertFile"
);
certfile
!=
""
{
HttpCertFile
=
certfile
.
(
string
)
}
if
certfile
:=
AppConfig
.
String
(
"HttpCertFile"
);
certfile
!=
""
{
HttpCertFile
=
certfile
}
if
keyfile
,
_
:=
GetConfig
(
"string"
,
"HttpKeyFile"
);
keyfile
!=
""
{
HttpKeyFile
=
keyfile
.
(
string
)
}
if
keyfile
:=
AppConfig
.
String
(
"HttpKeyFile"
);
keyfile
!=
""
{
HttpKeyFile
=
keyfile
}
if
serverName
,
_
:=
GetConfig
(
"string"
,
"BeegoServerName"
);
serverName
!=
""
{
BeegoServerName
=
serverName
.
(
string
)
}
if
serverName
:=
AppConfig
.
String
(
"BeegoServerName"
);
serverName
!=
""
{
BeegoServerName
=
serverName
}
if
flashname
,
_
:=
GetConfig
(
"string"
,
"FlashName"
);
flashname
!=
""
{
FlashName
=
flashname
.
(
string
)
}
if
flashname
:=
AppConfig
.
String
(
"FlashName"
);
flashname
!=
""
{
FlashName
=
flashname
}
if
flashseperator
,
_
:=
GetConfig
(
"string"
,
"FlashSeperator"
);
flashseperator
!=
""
{
FlashSeperator
=
flashseperator
.
(
string
)
}
if
flashseperator
:=
AppConfig
.
String
(
"FlashSeperator"
);
flashseperator
!=
""
{
FlashSeperator
=
flashseperator
}
if
sd
,
_
:=
GetConfig
(
"string"
,
"StaticDir"
);
sd
!=
""
{
for
k
:=
range
StaticDir
{
delete
(
StaticDir
,
k
)
}
sds
:=
strings
.
Fields
(
sd
.
(
string
))
for
_
,
v
:=
range
sds
{
if
url2fsmap
:=
strings
.
SplitN
(
v
,
":"
,
2
);
len
(
url2fsmap
)
==
2
{
StaticDir
[
"/"
+
strings
.
TrimRight
(
url2fsmap
[
0
],
"/"
)]
=
url2fsmap
[
1
]
}
else
{
StaticDir
[
"/"
+
strings
.
TrimRight
(
url2fsmap
[
0
],
"/"
)]
=
url2fsmap
[
0
]
}
if
sd
:=
AppConfig
.
String
(
"StaticDir"
);
sd
!=
""
{
for
k
:=
range
StaticDir
{
delete
(
StaticDir
,
k
)
}
sds
:=
strings
.
Fields
(
sd
)
for
_
,
v
:=
range
sds
{
if
url2fsmap
:=
strings
.
SplitN
(
v
,
":"
,
2
);
len
(
url2fsmap
)
==
2
{
StaticDir
[
"/"
+
strings
.
TrimRight
(
url2fsmap
[
0
],
"/"
)]
=
url2fsmap
[
1
]
}
else
{
StaticDir
[
"/"
+
strings
.
TrimRight
(
url2fsmap
[
0
],
"/"
)]
=
url2fsmap
[
0
]
}
}
}
if
sgz
,
_
:=
GetConfig
(
"string"
,
"StaticExtensionsToGzip"
);
sgz
!=
""
{
extensions
:=
strings
.
Split
(
sgz
.
(
string
),
","
)
if
len
(
extensions
)
>
0
{
StaticExtensionsToGzip
=
[]
string
{}
for
_
,
ext
:=
range
extensions
{
if
len
(
ext
)
==
0
{
continue
}
extWithDot
:=
ext
if
extWithDot
[
:
1
]
!=
"."
{
extWithDot
=
"."
+
extWithDot
}
StaticExtensionsToGzip
=
append
(
StaticExtensionsToGzip
,
extWithDot
)
if
sgz
:=
AppConfig
.
String
(
"StaticExtensionsToGzip"
);
sgz
!=
""
{
extensions
:=
strings
.
Split
(
sgz
,
","
)
if
len
(
extensions
)
>
0
{
StaticExtensionsToGzip
=
[]
string
{}
for
_
,
ext
:=
range
extensions
{
if
len
(
ext
)
==
0
{
continue
}
extWithDot
:=
ext
if
extWithDot
[
:
1
]
!=
"."
{
extWithDot
=
"."
+
extWithDot
}
StaticExtensionsToGzip
=
append
(
StaticExtensionsToGzip
,
extWithDot
)
}
}
}
if
enableadmin
,
err
:=
GetConfig
(
"bool"
,
"EnableAdmin"
);
err
==
nil
{
EnableAdmin
=
enableadmin
.
(
bool
)
}
if
adminhttpaddr
,
_
:=
GetConfig
(
"string"
,
"AdminHttpAddr"
);
adminhttpaddr
!=
""
{
AdminHttpAddr
=
adminhttpaddr
.
(
string
)
}
if
enableadmin
,
err
:=
AppConfig
.
Bool
(
"EnableAdmin"
);
err
==
nil
{
EnableAdmin
=
enableadmin
}
if
adminhttpport
,
err
:=
GetConfig
(
"int"
,
"AdminHttpPort"
);
err
==
nil
{
AdminHttpPort
=
adminhttpport
.
(
int
)
}
if
adminhttpaddr
:=
AppConfig
.
String
(
"AdminHttpAddr"
);
adminhttpaddr
!=
""
{
AdminHttpAddr
=
adminhttpaddr
}
if
enabledocs
,
err
:=
GetConfig
(
"bool"
,
"EnableDocs
"
);
err
==
nil
{
EnableDocs
=
enabledocs
.
(
bool
)
}
if
adminhttpport
,
err
:=
AppConfig
.
Int
(
"AdminHttpPort
"
);
err
==
nil
{
AdminHttpPort
=
adminhttpport
}
if
casesensitive
,
err
:=
GetConfig
(
"bool"
,
"RouterCaseSensitive"
);
err
==
nil
{
RouterCaseSensitive
=
casesensitive
.
(
bool
)
}
if
enabledocs
,
err
:=
AppConfig
.
Bool
(
"EnableDocs"
);
err
==
nil
{
EnableDocs
=
enabledocs
}
return
nil
}
// Getconfig throw the Runmode
// [dev]
// name = astaixe
// IsEnable = false
// [prod]
// name = slene
// IsEnable = true
//
// usage:
// GetConfig("string", "name")
// GetConfig("bool", "IsEnable")
func
GetConfig
(
typ
,
key
string
)
(
interface
{},
error
)
{
switch
typ
{
case
"string"
:
v
:=
AppConfig
.
String
(
RunMode
+
"::"
+
key
)
if
v
==
""
{
v
=
AppConfig
.
String
(
key
)
}
return
v
,
nil
case
"strings"
:
v
:=
AppConfig
.
Strings
(
RunMode
+
"::"
+
key
)
if
len
(
v
)
==
0
{
v
=
AppConfig
.
Strings
(
key
)
}
return
v
,
nil
case
"int"
:
v
,
err
:=
AppConfig
.
Int
(
RunMode
+
"::"
+
key
)
if
err
!=
nil
||
v
==
0
{
return
AppConfig
.
Int
(
key
)
}
return
v
,
nil
case
"bool"
:
v
,
err
:=
AppConfig
.
Bool
(
RunMode
+
"::"
+
key
)
if
err
!=
nil
{
return
AppConfig
.
Bool
(
key
)
}
return
v
,
nil
case
"int64"
:
v
,
err
:=
AppConfig
.
Int64
(
RunMode
+
"::"
+
key
)
if
err
!=
nil
||
v
==
0
{
return
AppConfig
.
Int64
(
key
)
}
return
v
,
nil
case
"float"
:
v
,
err
:=
AppConfig
.
Float
(
RunMode
+
"::"
+
key
)
if
err
!=
nil
||
v
==
0
{
return
AppConfig
.
Float
(
key
)
}
return
v
,
nil
if
casesensitive
,
err
:=
AppConfig
.
Bool
(
"RouterCaseSensitive"
);
err
==
nil
{
RouterCaseSensitive
=
casesensitive
}
return
""
,
errors
.
New
(
"not support type"
)
return
nil
}
...
...
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