Initial QSfera import
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// NewOptions wires options together.
|
||||
func NewOptions(opts ...Option) Options {
|
||||
var options Options
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
if options.Namespace == nil {
|
||||
options.Namespace = StaticNamespace("go.micro")
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
// WithHandler sets the handler being used.
|
||||
func WithHandler(h string) Option {
|
||||
return func(o *Options) {
|
||||
o.Handler = h
|
||||
}
|
||||
}
|
||||
|
||||
// WithNamespace sets the function which determines the namespace for a request.
|
||||
func WithNamespace(n func(*http.Request) string) Option {
|
||||
return func(o *Options) {
|
||||
o.Namespace = n
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Package resolver resolves a http request to an endpoint
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNotFound = errors.New("not found")
|
||||
ErrInvalidPath = errors.New("invalid path")
|
||||
)
|
||||
|
||||
// Resolver resolves requests to endpoints.
|
||||
type Resolver interface {
|
||||
Resolve(r *http.Request) (*Endpoint, error)
|
||||
String() string
|
||||
}
|
||||
|
||||
// Endpoint is the endpoint for a http request.
|
||||
type Endpoint struct {
|
||||
// e.g greeter
|
||||
Name string
|
||||
// HTTP Host e.g example.com
|
||||
Host string
|
||||
// HTTP Methods e.g GET, POST
|
||||
Method string
|
||||
// HTTP Path e.g /greeter.
|
||||
Path string
|
||||
}
|
||||
|
||||
// Options is a struct of available options.
|
||||
type Options struct {
|
||||
Namespace func(*http.Request) string
|
||||
Handler string
|
||||
}
|
||||
|
||||
// Option is a helper for a single option.
|
||||
type Option func(o *Options)
|
||||
|
||||
// StaticNamespace returns the same namespace for each request.
|
||||
func StaticNamespace(ns string) func(*http.Request) string {
|
||||
return func(*http.Request) string {
|
||||
return ns
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Package vpath resolves using http path and recognized versioned urls
|
||||
package vpath
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"go-micro.dev/v4/api/resolver"
|
||||
)
|
||||
|
||||
// NewResolver returns a new vpath resolver.
|
||||
func NewResolver(opts ...resolver.Option) resolver.Resolver {
|
||||
return &Resolver{opts: resolver.NewOptions(opts...)}
|
||||
}
|
||||
|
||||
// Resolver is a vpath resolver.
|
||||
type Resolver struct {
|
||||
opts resolver.Options
|
||||
}
|
||||
|
||||
var (
|
||||
re = regexp.MustCompile("^v[0-9]+$")
|
||||
)
|
||||
|
||||
// Resolve resolves a http.Request to an grpc Endpoint.
|
||||
func (r *Resolver) Resolve(req *http.Request) (*resolver.Endpoint, error) {
|
||||
if req.URL.Path == "/" {
|
||||
return nil, errors.New("unknown name")
|
||||
}
|
||||
|
||||
parts := strings.Split(req.URL.Path[1:], "/")
|
||||
if len(parts) == 1 {
|
||||
return &resolver.Endpoint{
|
||||
Name: r.withNamespace(req, parts...),
|
||||
Host: req.Host,
|
||||
Method: req.Method,
|
||||
Path: req.URL.Path,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// /v1/foo
|
||||
if re.MatchString(parts[0]) {
|
||||
return &resolver.Endpoint{
|
||||
Name: r.withNamespace(req, parts[0:2]...),
|
||||
Host: req.Host,
|
||||
Method: req.Method,
|
||||
Path: req.URL.Path,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &resolver.Endpoint{
|
||||
Name: r.withNamespace(req, parts[0]),
|
||||
Host: req.Host,
|
||||
Method: req.Method,
|
||||
Path: req.URL.Path,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *Resolver) String() string {
|
||||
return "path"
|
||||
}
|
||||
|
||||
func (r *Resolver) withNamespace(req *http.Request, parts ...string) string {
|
||||
ns := r.opts.Namespace(req)
|
||||
if len(ns) == 0 {
|
||||
return strings.Join(parts, ".")
|
||||
}
|
||||
|
||||
return strings.Join(append([]string{ns}, parts...), ".")
|
||||
}
|
||||
Reference in New Issue
Block a user