Small fixes and enhancements

This commit is contained in:
Darren Shepherd 2020-02-20 16:06:43 -07:00
parent 265a7a8763
commit 5b94b82bc6
5 changed files with 99 additions and 5 deletions

View File

@ -1,7 +1,6 @@
package proxy
import (
"fmt"
"net/http"
"net/url"
"strings"
@ -124,7 +123,6 @@ func stripLeaveSlash(prefix string, h http.Handler) http.Handler {
p = "/" + p
}
req.URL.Path = p
fmt.Println(req.Method, " ", req.URL.String())
h.ServeHTTP(w, req)
})
}

View File

@ -3,6 +3,7 @@ package server
import (
"net/http"
"github.com/rancher/steve/pkg/schemaserver/builtin"
"github.com/rancher/steve/pkg/schemaserver/handlers"
"github.com/rancher/steve/pkg/schemaserver/parse"
"github.com/rancher/steve/pkg/schemaserver/types"
@ -39,7 +40,7 @@ type Defaults struct {
func DefaultAPIServer() *Server {
s := &Server{
Schemas: types.EmptyAPISchemas(),
Schemas: types.EmptyAPISchemas().MustAddSchemas(builtin.Schemas),
ResponseWriters: map[string]types.ResponseWriter{
"json": &writer.EncodingResponseWriter{
ContentType: "application/json",
@ -150,6 +151,10 @@ func (s *Server) Handle(apiOp *types.APIRequest) {
}
func (s *Server) handle(apiOp *types.APIRequest, parser parse.Parser) {
if apiOp.Schemas == nil {
apiOp.Schemas = s.Schemas
}
if err := parser(apiOp, parse.MuxURLParser); err != nil {
// ensure defaults set so writer is assigned
s.setDefaults(apiOp)

View File

@ -38,9 +38,17 @@ func (a *APISchemas) MustImportAndCustomize(obj interface{}, f func(*APISchema))
Schema: schema,
}
a.Schemas[schema.ID] = apiSchema
a.addToIndex(apiSchema)
f(apiSchema)
}
func (a *APISchemas) MustAddSchemas(schemas *APISchemas) *APISchemas {
if err := a.AddSchemas(schemas); err != nil {
logrus.Fatalf("failed to add schemas: %v", err)
}
return a
}
func (a *APISchemas) AddSchemas(schema *APISchemas) error {
for _, schema := range schema.Schemas {
if err := a.AddSchema(*schema); err != nil {
@ -50,14 +58,18 @@ func (a *APISchemas) AddSchemas(schema *APISchemas) error {
return nil
}
func (a *APISchemas) addToIndex(schema *APISchema) {
a.index[strings.ToLower(schema.ID)] = schema
a.index[strings.ToLower(schema.PluralName)] = schema
}
func (a *APISchemas) AddSchema(schema APISchema) error {
if err := a.InternalSchemas.AddSchema(*schema.Schema); err != nil {
return err
}
schema.Schema = a.InternalSchemas.Schema(schema.ID)
a.Schemas[schema.ID] = &schema
a.index[strings.ToLower(schema.ID)] = &schema
a.index[strings.ToLower(schema.PluralName)] = &schema
a.addToIndex(&schema)
return nil
}

View File

@ -0,0 +1,77 @@
package urlbuilder
import (
"bytes"
"net/http"
"net/url"
"strings"
)
func RedirectRewrite(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
prefix := req.Header.Get(PrefixHeader)
if prefix == "" {
next.ServeHTTP(rw, req)
return
}
r := &redirector{
ResponseWriter: rw,
prefix: prefix,
}
next.ServeHTTP(r, req)
r.Close()
})
}
type redirector struct {
http.ResponseWriter
prefix string
from, to string
tempBuffer *bytes.Buffer
}
func (r *redirector) Write(content []byte) (int, error) {
if r.tempBuffer == nil {
return r.ResponseWriter.Write(content)
}
return r.tempBuffer.Write(content)
}
func (r *redirector) Close() error {
if r.tempBuffer == nil || r.from == "" || r.to == "" {
return nil
}
content := bytes.Replace(r.tempBuffer.Bytes(), []byte(r.from), []byte(r.to), -1)
_, err := r.ResponseWriter.Write(content)
r.tempBuffer = nil
return err
}
func (r *redirector) WriteHeader(statusCode int) {
defer func() {
// the anonymous func is so that we take the new value of statusCode,
// not copy it at invocation
r.ResponseWriter.WriteHeader(statusCode)
}()
if statusCode != http.StatusMovedPermanently && statusCode != http.StatusFound {
return
}
l := r.Header().Get("Location")
if l == "" {
return
}
u, _ := url.Parse(l)
if !strings.HasPrefix(u.Path, r.prefix) {
r.from = u.Path
u.Path = r.prefix + u.Path
r.Header().Set("Location", u.String())
r.to = u.Path
r.tempBuffer = &bytes.Buffer{}
}
statusCode = http.StatusFound
}

View File

@ -4,6 +4,7 @@ import (
"net/http"
"github.com/gorilla/mux"
"github.com/rancher/steve/pkg/schemaserver/urlbuilder"
)
type RouterFunc func(h Handlers) http.Handler
@ -20,6 +21,7 @@ func Routes(h Handlers) http.Handler {
m := mux.NewRouter()
m.UseEncodedPath()
m.StrictSlash(true)
m.Use(urlbuilder.RedirectRewrite)
m.Path("/").Handler(h.APIRoot).HeadersRegexp("Accepts", ".*json.*")
m.Path("/{name:v1}").Handler(h.APIRoot)