mirror of
https://github.com/niusmallnan/steve.git
synced 2025-07-02 01:11:55 +00:00
Small fixes and enhancements
This commit is contained in:
parent
265a7a8763
commit
5b94b82bc6
@ -1,7 +1,6 @@
|
|||||||
package proxy
|
package proxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
@ -124,7 +123,6 @@ func stripLeaveSlash(prefix string, h http.Handler) http.Handler {
|
|||||||
p = "/" + p
|
p = "/" + p
|
||||||
}
|
}
|
||||||
req.URL.Path = p
|
req.URL.Path = p
|
||||||
fmt.Println(req.Method, " ", req.URL.String())
|
|
||||||
h.ServeHTTP(w, req)
|
h.ServeHTTP(w, req)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package server
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/rancher/steve/pkg/schemaserver/builtin"
|
||||||
"github.com/rancher/steve/pkg/schemaserver/handlers"
|
"github.com/rancher/steve/pkg/schemaserver/handlers"
|
||||||
"github.com/rancher/steve/pkg/schemaserver/parse"
|
"github.com/rancher/steve/pkg/schemaserver/parse"
|
||||||
"github.com/rancher/steve/pkg/schemaserver/types"
|
"github.com/rancher/steve/pkg/schemaserver/types"
|
||||||
@ -39,7 +40,7 @@ type Defaults struct {
|
|||||||
|
|
||||||
func DefaultAPIServer() *Server {
|
func DefaultAPIServer() *Server {
|
||||||
s := &Server{
|
s := &Server{
|
||||||
Schemas: types.EmptyAPISchemas(),
|
Schemas: types.EmptyAPISchemas().MustAddSchemas(builtin.Schemas),
|
||||||
ResponseWriters: map[string]types.ResponseWriter{
|
ResponseWriters: map[string]types.ResponseWriter{
|
||||||
"json": &writer.EncodingResponseWriter{
|
"json": &writer.EncodingResponseWriter{
|
||||||
ContentType: "application/json",
|
ContentType: "application/json",
|
||||||
@ -150,6 +151,10 @@ func (s *Server) Handle(apiOp *types.APIRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handle(apiOp *types.APIRequest, parser parse.Parser) {
|
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 {
|
if err := parser(apiOp, parse.MuxURLParser); err != nil {
|
||||||
// ensure defaults set so writer is assigned
|
// ensure defaults set so writer is assigned
|
||||||
s.setDefaults(apiOp)
|
s.setDefaults(apiOp)
|
||||||
|
@ -38,9 +38,17 @@ func (a *APISchemas) MustImportAndCustomize(obj interface{}, f func(*APISchema))
|
|||||||
Schema: schema,
|
Schema: schema,
|
||||||
}
|
}
|
||||||
a.Schemas[schema.ID] = apiSchema
|
a.Schemas[schema.ID] = apiSchema
|
||||||
|
a.addToIndex(apiSchema)
|
||||||
f(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 {
|
func (a *APISchemas) AddSchemas(schema *APISchemas) error {
|
||||||
for _, schema := range schema.Schemas {
|
for _, schema := range schema.Schemas {
|
||||||
if err := a.AddSchema(*schema); err != nil {
|
if err := a.AddSchema(*schema); err != nil {
|
||||||
@ -50,14 +58,18 @@ func (a *APISchemas) AddSchemas(schema *APISchemas) error {
|
|||||||
return nil
|
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 {
|
func (a *APISchemas) AddSchema(schema APISchema) error {
|
||||||
if err := a.InternalSchemas.AddSchema(*schema.Schema); err != nil {
|
if err := a.InternalSchemas.AddSchema(*schema.Schema); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
schema.Schema = a.InternalSchemas.Schema(schema.ID)
|
schema.Schema = a.InternalSchemas.Schema(schema.ID)
|
||||||
a.Schemas[schema.ID] = &schema
|
a.Schemas[schema.ID] = &schema
|
||||||
a.index[strings.ToLower(schema.ID)] = &schema
|
a.addToIndex(&schema)
|
||||||
a.index[strings.ToLower(schema.PluralName)] = &schema
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
77
pkg/schemaserver/urlbuilder/redirect.go
Normal file
77
pkg/schemaserver/urlbuilder/redirect.go
Normal 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
|
||||||
|
}
|
@ -4,6 +4,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/rancher/steve/pkg/schemaserver/urlbuilder"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RouterFunc func(h Handlers) http.Handler
|
type RouterFunc func(h Handlers) http.Handler
|
||||||
@ -20,6 +21,7 @@ func Routes(h Handlers) http.Handler {
|
|||||||
m := mux.NewRouter()
|
m := mux.NewRouter()
|
||||||
m.UseEncodedPath()
|
m.UseEncodedPath()
|
||||||
m.StrictSlash(true)
|
m.StrictSlash(true)
|
||||||
|
m.Use(urlbuilder.RedirectRewrite)
|
||||||
|
|
||||||
m.Path("/").Handler(h.APIRoot).HeadersRegexp("Accepts", ".*json.*")
|
m.Path("/").Handler(h.APIRoot).HeadersRegexp("Accepts", ".*json.*")
|
||||||
m.Path("/{name:v1}").Handler(h.APIRoot)
|
m.Path("/{name:v1}").Handler(h.APIRoot)
|
||||||
|
Loading…
Reference in New Issue
Block a user