@@ -38,6 +38,7 @@ import (
3838 "github.com/kube-bind/kube-bind/backend/kubernetes"
3939 "github.com/kube-bind/kube-bind/backend/session"
4040 "github.com/kube-bind/kube-bind/backend/spaserver"
41+ "github.com/kube-bind/kube-bind/backend/static"
4142 bindversion "github.com/kube-bind/kube-bind/pkg/version"
4243 kubebindv1alpha2 "github.com/kube-bind/kube-bind/sdk/apis/kubebind/v1alpha2"
4344)
@@ -93,7 +94,7 @@ func NewHandler(
9394 }, nil
9495}
9596
96- func (h * handler ) AddRoutes (mux * mux.Router ) {
97+ func (h * handler ) AddRoutes (mux * mux.Router ) error {
9798 // API routes - Server contains double routes for when backend is multi-cluster aware or single cluster.
9899 // When called multi-cluster aware route in single cluster mode, it will ignore cluster parameter.
99100 mux .HandleFunc ("/api/clusters/{cluster}/exports" , h .handleServiceExport ).Methods (http .MethodGet )
@@ -120,16 +121,24 @@ func (h *handler) AddRoutes(mux *mux.Router) {
120121 mux .HandleFunc ("/clusters/{cluster}/exports" , h .handleExportsRedirect ).Methods (http .MethodGet )
121122 mux .HandleFunc ("/exports" , h .handleExportsRedirect ).Methods (http .MethodGet )
122123
123- if strings .HasPrefix (h .frontend , "http://" ) {
124+ switch {
125+ case strings .HasPrefix (h .frontend , "http://" ):
126+ // Development mode: proxy to frontend dev server
124127 spaserver , err := spaserver .NewSPAReverseProxyServer (h .frontend )
125128 if err != nil {
126- panic ( fmt . Sprintf ( "failed to create SPA reverse proxy server: %v" , err )) // Development only.
129+ return err
127130 }
128131 mux .PathPrefix ("/" ).Handler (spaserver )
129- } else {
132+ case h .frontend == "embedded" :
133+ // Production mode: serve embedded static files
134+ fileSystem := static .GetFileSystem ()
135+ mux .PathPrefix ("/" ).Handler (spaserver .NewSPAFileServer (fileSystem ))
136+ default :
137+ // Custom filesystem path
130138 fileSystem := http .Dir (h .frontend )
131139 mux .PathPrefix ("/" ).Handler (spaserver .NewSPAFileServer (fileSystem ))
132140 }
141+ return nil
133142}
134143
135144func (h * handler ) handleExportsRedirect (w http.ResponseWriter , r * http.Request ) {
@@ -579,10 +588,25 @@ func (h *handler) handleBindPost(w http.ResponseWriter, r *http.Request) {
579588 }
580589
581590 // Parse JSON request body
591+ // Parse JSON request body
592+ const maxBodySize = 1 << 20 // 1 MB
593+ r .Body = http .MaxBytesReader (w , r .Body , maxBodySize )
582594 var bindRequest kubebindv1alpha2.BindableResourcesRequest
583595 if err := json .NewDecoder (r .Body ).Decode (& bindRequest ); err != nil {
584596 logger .Error (err , "failed to parse JSON request body" )
585- http .Error (w , "invalid JSON request body" , http .StatusBadRequest )
597+ var maxBytesError * http.MaxBytesError
598+ if errors .As (err , & maxBytesError ) {
599+ http .Error (w , "request body too large" , http .StatusRequestEntityTooLarge )
600+ } else {
601+ http .Error (w , "invalid JSON request body" , http .StatusBadRequest )
602+ }
603+ return
604+ }
605+
606+ err = bindRequest .Validate ()
607+ if err != nil {
608+ logger .Error (err , "validation failed for bind request" )
609+ http .Error (w , fmt .Sprintf ("invalid bind request: %v" , err ), http .StatusBadRequest )
586610 return
587611 }
588612
0 commit comments