mirror of
https://github.com/rancher/steve.git
synced 2025-04-27 02:51:10 +00:00
125 lines
3.1 KiB
Go
125 lines
3.1 KiB
Go
package urlbuilder
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/rancher/steve/pkg/schemaserver/types"
|
|
"github.com/rancher/wrangler/pkg/name"
|
|
)
|
|
|
|
const (
|
|
PrefixHeader = "X-API-URL-Prefix"
|
|
ForwardedAPIHostHeader = "X-API-Host"
|
|
ForwardedHostHeader = "X-Forwarded-Host"
|
|
ForwardedProtoHeader = "X-Forwarded-Proto"
|
|
ForwardedPortHeader = "X-Forwarded-Port"
|
|
)
|
|
|
|
func NewPrefixed(r *http.Request, schemas *types.APISchemas, prefix string) (types.URLBuilder, error) {
|
|
return New(r, &DefaultPathResolver{
|
|
Prefix: prefix,
|
|
}, schemas)
|
|
}
|
|
|
|
func New(r *http.Request, resolver PathResolver, schemas *types.APISchemas) (types.URLBuilder, error) {
|
|
requestURL := ParseRequestURL(r)
|
|
responseURLBase, err := ParseResponseURLBase(requestURL, r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
builder := &DefaultURLBuilder{
|
|
schemas: schemas,
|
|
currentURL: requestURL,
|
|
responseURLBase: responseURLBase,
|
|
pathResolver: resolver,
|
|
query: r.URL.Query(),
|
|
}
|
|
|
|
return builder, nil
|
|
}
|
|
|
|
type PathResolver interface {
|
|
Schema(base string, schema *types.APISchema) string
|
|
}
|
|
|
|
type DefaultPathResolver struct {
|
|
Prefix string
|
|
}
|
|
|
|
func (d *DefaultPathResolver) Schema(base string, schema *types.APISchema) string {
|
|
return ConstructBasicURL(base, d.Prefix, schema.PluralName)
|
|
}
|
|
|
|
type DefaultURLBuilder struct {
|
|
pathResolver PathResolver
|
|
schemas *types.APISchemas
|
|
currentURL string
|
|
responseURLBase string
|
|
query url.Values
|
|
}
|
|
|
|
func (u *DefaultURLBuilder) Link(schema *types.APISchema, id string, linkName string) string {
|
|
return u.schemaURL(schema, id, linkName)
|
|
}
|
|
|
|
func (u *DefaultURLBuilder) ResourceLink(schema *types.APISchema, id string) string {
|
|
return u.schemaURL(schema, id)
|
|
}
|
|
|
|
func (u *DefaultURLBuilder) Current() string {
|
|
return u.currentURL
|
|
}
|
|
|
|
func (u *DefaultURLBuilder) RelativeToRoot(path string) string {
|
|
if len(path) > 0 && path[0] != '/' {
|
|
return u.responseURLBase + "/" + path
|
|
}
|
|
return u.responseURLBase + path
|
|
}
|
|
|
|
func (u *DefaultURLBuilder) Collection(schema *types.APISchema) string {
|
|
return u.schemaURL(schema)
|
|
}
|
|
|
|
func (u *DefaultURLBuilder) schemaURL(schema *types.APISchema, parts ...string) string {
|
|
base := []string{
|
|
u.pathResolver.Schema(u.responseURLBase, schema),
|
|
}
|
|
return ConstructBasicURL(append(base, parts...)...)
|
|
}
|
|
|
|
func ConstructBasicURL(parts ...string) string {
|
|
switch len(parts) {
|
|
case 0:
|
|
return ""
|
|
case 1:
|
|
return parts[0]
|
|
default:
|
|
base := parts[0]
|
|
rest := path.Join(parts[1:]...)
|
|
if !strings.HasSuffix(base, "/") && !strings.HasPrefix(rest, "/") {
|
|
return base + "/" + rest
|
|
}
|
|
return base + rest
|
|
}
|
|
}
|
|
|
|
func (u *DefaultURLBuilder) getPluralName(schema *types.APISchema) string {
|
|
if schema.PluralName == "" {
|
|
return strings.ToLower(name.GuessPluralName(schema.ID))
|
|
}
|
|
return strings.ToLower(schema.PluralName)
|
|
}
|
|
|
|
func (u *DefaultURLBuilder) Action(schema *types.APISchema, id, action string) string {
|
|
return u.schemaURL(schema, id) + "?action=" + url.QueryEscape(action)
|
|
}
|
|
|
|
func (u *DefaultURLBuilder) CollectionAction(schema *types.APISchema, action string) string {
|
|
return u.schemaURL(schema) + "?action=" + url.QueryEscape(action)
|
|
}
|