#313 support CORS for jsonrpc2

This commit is contained in:
smallnest
2019-03-26 16:30:19 +08:00
parent 48023c31be
commit dd4300b521
5 changed files with 93 additions and 6 deletions

View File

@@ -57,4 +57,8 @@ build-all:
test:
go test -race -tags "reuseport kcp quic zookeeper etcd consul ping utp rudp" ./...
update-libs:
GIT_TERMINAL_PROMPT=1 GO111MODULE=on go get -u -v .
mod-tidy:
GIT_TERMINAL_PROMPT=1 GO111MODULE=on go mod tidy

2
go.mod
View File

@@ -73,6 +73,7 @@ require (
github.com/prometheus/common v0.0.0-20190107103113-2998b132700a // indirect
github.com/prometheus/procfs v0.0.0-20190104112138-b1a0a9a36d74 // indirect
github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165
github.com/rs/cors v1.6.0
github.com/rubyist/circuitbreaker v2.2.1+incompatible
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec // indirect
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
@@ -91,6 +92,7 @@ require (
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 // indirect
gopkg.in/fsnotify.v1 v1.4.7 // indirect
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/vmihailenco/msgpack.v2 v2.9.1 // indirect
labix.org/v2/mgo v0.0.0-20140701140051-000000000287 // indirect

2
go.sum
View File

@@ -227,6 +227,8 @@ github.com/prometheus/procfs v0.0.0-20190104112138-b1a0a9a36d74 h1:d1Xoc24yp/pXm
github.com/prometheus/procfs v0.0.0-20190104112138-b1a0a9a36d74/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 h1:nkcn14uNmFEuGCb2mBZbBb24RdNRL08b/wb+xBOYpuk=
github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rubyist/circuitbreaker v2.2.1+incompatible h1:KUKd/pV8Geg77+8LNDwdow6rVCAYOp8+kHUyFvL6Mhk=
github.com/rubyist/circuitbreaker v2.2.1+incompatible/go.mod h1:Ycs3JgJADPuzJDwffe12k6BZT8hxVi6lFK+gWYJLN4A=
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8=

View File

@@ -8,6 +8,7 @@ import (
"net/http"
"strings"
"github.com/rs/cors"
"github.com/smallnest/rpcx/protocol"
)
@@ -96,8 +97,87 @@ func writeResponse(w http.ResponseWriter, res *jsonrpcRespone) {
w.Write(data)
}
type CORSOptions struct {
// AllowedOrigins is a list of origins a cross-domain request can be executed from.
// If the special "*" value is present in the list, all origins will be allowed.
// An origin may contain a wildcard (*) to replace 0 or more characters
// (i.e.: http://*.domain.com). Usage of wildcards implies a small performance penalty.
// Only one wildcard can be used per origin.
// Default value is ["*"]
AllowedOrigins []string
// AllowOriginFunc is a custom function to validate the origin. It take the origin
// as argument and returns true if allowed or false otherwise. If this option is
// set, the content of AllowedOrigins is ignored.
AllowOriginFunc func(origin string) bool
// AllowOriginFunc is a custom function to validate the origin. It takes the HTTP Request object and the origin as
// argument and returns true if allowed or false otherwise. If this option is set, the content of `AllowedOrigins`
// and `AllowOriginFunc` is ignored.
AllowOriginRequestFunc func(r *http.Request, origin string) bool
// AllowedMethods is a list of methods the client is allowed to use with
// cross-domain requests. Default value is simple methods (HEAD, GET and POST).
AllowedMethods []string
// AllowedHeaders is list of non simple headers the client is allowed to use with
// cross-domain requests.
// If the special "*" value is present in the list, all headers will be allowed.
// Default value is [] but "Origin" is always appended to the list.
AllowedHeaders []string
// ExposedHeaders indicates which headers are safe to expose to the API of a CORS
// API specification
ExposedHeaders []string
// MaxAge indicates how long (in seconds) the results of a preflight request
// can be cached
MaxAge int
// AllowCredentials indicates whether the request can include user credentials like
// cookies, HTTP authentication or client side SSL certificates.
AllowCredentials bool
// OptionsPassthrough instructs preflight to let other potential next handlers to
// process the OPTIONS method. Turn this on if your application handles OPTIONS.
OptionsPassthrough bool
// Debugging flag adds additional output to debug server side CORS issues
Debug bool
}
// AllowAllCORSOptions returns a option that allows access.
func AllowAllCORSOptions() *CORSOptions {
return &CORSOptions{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{
http.MethodHead,
http.MethodGet,
http.MethodPost,
http.MethodPut,
http.MethodPatch,
http.MethodDelete,
},
AllowedHeaders: []string{"*"},
AllowCredentials: false,
}
}
// SetCORS sets CORS options.
// for example:
//
// cors.Options{
// AllowedOrigins: []string{"foo.com"},
// AllowedMethods: []string{http.MethodGet, http.MethodPost, http.MethodDelete},
// AllowCredentials: true,
// }
//
func (s *Server) SetCORS(options *CORSOptions) {
s.corsOptions = options
}
func (s *Server) startJSONRPC2(ln net.Listener) {
newServer := http.NewServeMux()
newServer.HandleFunc("/", s.jsonrpcHandler)
go http.Serve(ln, newServer)
if s.corsOptions != nil {
opt := cors.Options(*s.corsOptions)
c := cors.New(opt)
mux := c.Handler(newServer)
go http.Serve(ln, mux)
} else {
go http.Serve(ln, newServer)
}
}

View File

@@ -79,10 +79,9 @@ type Server struct {
tlsConfig *tls.Config
// BlockCrypt for kcp.BlockCrypt
options map[string]interface{}
// // use for KCP
// KCPConfig KCPConfig
// // for QUIC
// QUICConfig QUICConfig
// CORS options
corsOptions *CORSOptions
Plugins PluginContainer