mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
add AllowDomain option for ghttp.CORS; add IsSubDomain function for gstr; improve grand.Intn
This commit is contained in:
@ -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")
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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
1
.gitignore
vendored
@ -14,3 +14,4 @@ bin/
|
||||
cbuild
|
||||
**/.DS_Store
|
||||
.vscode/
|
||||
go.sum
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user