add AllowDomain option for ghttp.CORS; add IsSubDomain function for gstr; improve grand.Intn

This commit is contained in:
John
2019-09-23 19:25:03 +08:00
parent 3218c89f17
commit 51d9fe5253
13 changed files with 66 additions and 43 deletions

View File

@ -7,7 +7,7 @@ import (
func main() {
s := g.Server()
s.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_FULLNAME)
s.SetNameToUriType(ghttp.URI_TYPE_FULLNAME)
s.EnableAdmin()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.Write("hello world")

View File

@ -17,10 +17,10 @@ func main() {
s3 := g.Server(3)
s4 := g.Server(4)
s1.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_DEFAULT)
s2.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_FULLNAME)
s3.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_ALLLOWER)
s4.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_CAMEL)
s1.SetNameToUriType(ghttp.URI_TYPE_DEFAULT)
s2.SetNameToUriType(ghttp.URI_TYPE_FULLNAME)
s3.SetNameToUriType(ghttp.URI_TYPE_ALLLOWER)
s4.SetNameToUriType(ghttp.URI_TYPE_CAMEL)
s1.BindObject("/{.struct}/{.method}", new(User))
s2.BindObject("/{.struct}/{.method}", new(User))

View File

@ -9,7 +9,7 @@ import (
func main() {
s := g.Server()
s.SetServerRoot("public")
s.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_ALLLOWER)
s.SetNameToUriType(ghttp.URI_TYPE_ALLLOWER)
s.SetErrorLogEnabled(true)
s.SetAccessLogEnabled(true)
s.SetPort(2333)

1
.gitignore vendored
View File

@ -14,3 +14,4 @@ bin/
cbuild
**/.DS_Store
.vscode/
go.sum

View File

@ -6,9 +6,11 @@
package g
import "github.com/gogf/gf/container/gvar"
import (
"github.com/gogf/gf/container/gvar"
)
// Universal variable type, like generics.
// Var is a universal variable type, like generics.
type Var = gvar.Var
// Frequently-used map type alias.

View File

@ -74,7 +74,7 @@ func newRequest(s *Server, r *http.Request, w http.ResponseWriter) *Request {
// 获取Web Socket连接对象(如果是非WS请求会失败注意检查返回的error结果)
func (r *Request) WebSocket() (*WebSocket, error) {
if conn, err := wsUpgrader.Upgrade(r.Response.ResponseWriter.ResponseWriter, r.Request, nil); err == nil {
if conn, err := wsUpgrader.Upgrade(r.Response.Writer, r.Request, nil); err == nil {
return &WebSocket{
conn,
}, nil

View File

@ -8,6 +8,8 @@
package ghttp
import (
"net/url"
"github.com/gogf/gf/text/gstr"
"github.com/gogf/gf/util/gconv"
)
@ -47,26 +49,20 @@ func (r *Response) DefaultCORSOptions() CORSOptions {
// See https://www.w3.org/TR/cors/ .
func (r *Response) CORS(options CORSOptions) {
if options.AllowDomain != nil {
//origin := r.request.Header.Get("Origin")
//if origin == "" {
// return
//}
//parsed, err := url.Parse(origin)
//if err != nil {
// return
//}
//for k, v := range options.AllowDomain {
// if gstr.Contains(v, "*") {
// // Regular expression.
// gstr.ReplaceByArray(v, []string{
// ".", "\\.", "*", "[^\\.]*",
// })
// } else if len(parsed.Host) >= len(v) && parsed.Host[len(parsed.Host)-len(v):] == v {
// // Last domain.
// r.Header().Set("Access-Control-Allow-Origin", origin)
// break
// }
//}
origin := r.request.Header.Get("Origin")
if origin == "" {
return
}
parsed, err := url.Parse(origin)
if err != nil {
return
}
for _, v := range options.AllowDomain {
if gstr.IsSubDomain(parsed.Host, v) {
r.Header().Set("Access-Control-Allow-Origin", origin)
break
}
}
} else if options.AllowOrigin != "" {
r.Header().Set("Access-Control-Allow-Origin", options.AllowOrigin)
}

View File

@ -26,10 +26,10 @@ import (
const (
gDEFAULT_HTTP_ADDR = ":80" // 默认HTTP监听地址
gDEFAULT_HTTPS_ADDR = ":443" // 默认HTTPS监听地址
NAME_TO_URI_TYPE_DEFAULT = 0 // 服务注册时对象和方法名称转换为URI时全部转为小写单词以'-'连接符号连接
NAME_TO_URI_TYPE_FULLNAME = 1 // 不处理名称以原有名称构建成URI
NAME_TO_URI_TYPE_ALLLOWER = 2 // 仅转为小写,单词间不使用连接符号
NAME_TO_URI_TYPE_CAMEL = 3 // 采用驼峰命名方式
URI_TYPE_DEFAULT = 0 // 服务注册时对象和方法名称转换为URI时全部转为小写单词以'-'连接符号连接
URI_TYPE_FULLNAME = 1 // 不处理名称以原有名称构建成URI
URI_TYPE_ALLLOWER = 2 // 仅转为小写,单词间不使用连接符号
URI_TYPE_CAMEL = 3 // 采用驼峰命名方式
gCHANGE_CONFIG_WHILE_RUNNING_ERROR = "server's configuration cannot be changed while running"
)

View File

@ -77,13 +77,13 @@ func (s *Server) mergeBuildInNameToPattern(pattern string, structName, methodNam
// 规则3: 采用驼峰命名方式
func (s *Server) nameToUrlPart(name string) string {
switch s.config.NameToUriType {
case NAME_TO_URI_TYPE_FULLNAME:
case URI_TYPE_FULLNAME:
return name
case NAME_TO_URI_TYPE_ALLLOWER:
case URI_TYPE_ALLLOWER:
return strings.ToLower(name)
case NAME_TO_URI_TYPE_CAMEL:
case URI_TYPE_CAMEL:
part := bytes.NewBuffer(nil)
if gstr.IsLetterUpper(name[0]) {
part.WriteByte(name[0] + 32)
@ -93,7 +93,7 @@ func (s *Server) nameToUrlPart(name string) string {
part.WriteString(name[1:])
return part.String()
case NAME_TO_URI_TYPE_DEFAULT:
case URI_TYPE_DEFAULT:
fallthrough
default:
part := bytes.NewBuffer(nil)

View File

@ -25,7 +25,7 @@ func (o *NamesObject) ShowName(r *ghttp.Request) {
func Test_NameToUri_FullName(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_FULLNAME)
s.SetNameToUriType(ghttp.URI_TYPE_FULLNAME)
s.BindObject("/{.struct}/{.method}", new(NamesObject))
s.SetPort(p)
s.SetDumpRouteMap(false)
@ -47,7 +47,7 @@ func Test_NameToUri_FullName(t *testing.T) {
func Test_NameToUri_AllLower(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_ALLLOWER)
s.SetNameToUriType(ghttp.URI_TYPE_ALLLOWER)
s.BindObject("/{.struct}/{.method}", new(NamesObject))
s.SetPort(p)
s.SetDumpRouteMap(false)
@ -69,7 +69,7 @@ func Test_NameToUri_AllLower(t *testing.T) {
func Test_NameToUri_Camel(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_CAMEL)
s.SetNameToUriType(ghttp.URI_TYPE_CAMEL)
s.BindObject("/{.struct}/{.method}", new(NamesObject))
s.SetPort(p)
s.SetDumpRouteMap(false)
@ -91,7 +91,7 @@ func Test_NameToUri_Camel(t *testing.T) {
func Test_NameToUri_Default(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_DEFAULT)
s.SetNameToUriType(ghttp.URI_TYPE_DEFAULT)
s.BindObject("/{.struct}/{.method}", new(NamesObject))
s.SetPort(p)
s.SetDumpRouteMap(false)

View File

@ -11,6 +11,12 @@ import "strings"
// IsSubDomain checks whether <subDomain> is sub-domain of mainDomain.
// It supports '*' in <mainDomain>.
func IsSubDomain(subDomain string, mainDomain string) bool {
if p := strings.IndexByte(subDomain, ':'); p != -1 {
subDomain = subDomain[0:p]
}
if p := strings.IndexByte(mainDomain, ':'); p != -1 {
mainDomain = mainDomain[0:p]
}
subArray := strings.Split(subDomain, ".")
mainArray := strings.Split(mainDomain, ".")
subLength := len(subArray)

View File

@ -21,6 +21,7 @@ func Test_IsSubDomain(t *testing.T) {
gtest.Assert(gstr.IsSubDomain("goframe.org", main), true)
gtest.Assert(gstr.IsSubDomain("s.goframe.org", main), true)
gtest.Assert(gstr.IsSubDomain("s.s.goframe.org", main), true)
gtest.Assert(gstr.IsSubDomain("s.s.goframe.org:8080", main), true)
gtest.Assert(gstr.IsSubDomain("johng.cn", main), false)
gtest.Assert(gstr.IsSubDomain("s.johng.cn", main), false)
gtest.Assert(gstr.IsSubDomain("s.s.johng.cn", main), false)
@ -29,6 +30,7 @@ func Test_IsSubDomain(t *testing.T) {
main := "*.goframe.org"
gtest.Assert(gstr.IsSubDomain("goframe.org", main), true)
gtest.Assert(gstr.IsSubDomain("s.goframe.org", main), true)
gtest.Assert(gstr.IsSubDomain("s.goframe.org:80", main), true)
gtest.Assert(gstr.IsSubDomain("s.s.goframe.org", main), false)
gtest.Assert(gstr.IsSubDomain("johng.cn", main), false)
gtest.Assert(gstr.IsSubDomain("s.johng.cn", main), false)
@ -39,6 +41,18 @@ func Test_IsSubDomain(t *testing.T) {
gtest.Assert(gstr.IsSubDomain("goframe.org", main), true)
gtest.Assert(gstr.IsSubDomain("s.goframe.org", main), true)
gtest.Assert(gstr.IsSubDomain("s.s.goframe.org", main), true)
gtest.Assert(gstr.IsSubDomain("s.s.goframe.org:8000", main), true)
gtest.Assert(gstr.IsSubDomain("s.s.s.goframe.org", main), false)
gtest.Assert(gstr.IsSubDomain("johng.cn", main), false)
gtest.Assert(gstr.IsSubDomain("s.johng.cn", main), false)
gtest.Assert(gstr.IsSubDomain("s.s.johng.cn", main), false)
})
gtest.Case(t, func() {
main := "*.*.goframe.org:8080"
gtest.Assert(gstr.IsSubDomain("goframe.org", main), true)
gtest.Assert(gstr.IsSubDomain("s.goframe.org", main), true)
gtest.Assert(gstr.IsSubDomain("s.s.goframe.org", main), true)
gtest.Assert(gstr.IsSubDomain("s.s.goframe.org:8000", main), true)
gtest.Assert(gstr.IsSubDomain("s.s.s.goframe.org", main), false)
gtest.Assert(gstr.IsSubDomain("johng.cn", main), false)
gtest.Assert(gstr.IsSubDomain("s.johng.cn", main), false)

View File

@ -58,9 +58,13 @@ func init() {
// Intn returns a int number which is between 0 and max - [0, max).
//
// Note:
// 1. The result is greater than or equal to 0, but less than <max>;
// 2. The result number is 32bit and less than math.MaxUint32.
// 1. The <max> can only be geater than 0, or else it return <max> directly;
// 2. The result is greater than or equal to 0, but less than <max>;
// 3. The result number is 32bit and less than math.MaxUint32.
func Intn(max int) int {
if max <= 0 {
return max
}
n := int(<-bufferChan) % max
if (max > 0 && n < 0) || (max < 0 && n > 0) {
return -n