storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/web-router.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2016 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package cmd
    18  
    19  import (
    20  	"fmt"
    21  	"io/fs"
    22  	"net/http"
    23  
    24  	"github.com/gorilla/handlers"
    25  	"github.com/gorilla/mux"
    26  
    27  	"storj.io/minio/browser"
    28  	"storj.io/minio/cmd/logger"
    29  	jsonrpc "storj.io/minio/pkg/rpc"
    30  	"storj.io/minio/pkg/rpc/json2"
    31  )
    32  
    33  // webAPI container for Web API.
    34  type webAPIHandlers struct {
    35  	ObjectAPI func() ObjectLayer
    36  	CacheAPI  func() CacheObjectLayer
    37  }
    38  
    39  // indexHandler - Handler to serve index.html
    40  type indexHandler struct {
    41  	handler http.Handler
    42  }
    43  
    44  func (h indexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    45  	r.URL.Path = minioReservedBucketPath + SlashSeparator
    46  	h.handler.ServeHTTP(w, r)
    47  }
    48  
    49  const assetPrefix = "production"
    50  
    51  // specialAssets are files which are unique files not embedded inside index_bundle.js.
    52  const specialAssets = "index_bundle.*.js|loader.css|logo.svg|firefox.png|safari.png|chrome.png|favicon-16x16.png|favicon-32x32.png|favicon-96x96.png"
    53  
    54  // registerWebRouter - registers web router for serving minio browser.
    55  func registerWebRouter(router *mux.Router) error {
    56  	// Initialize Web.
    57  	web := &webAPIHandlers{
    58  		ObjectAPI: newObjectLayerFn,
    59  		CacheAPI:  newCachedObjectLayerFn,
    60  	}
    61  
    62  	// Initialize a new json2 codec.
    63  	codec := json2.NewCodec()
    64  
    65  	// MinIO browser router.
    66  	webBrowserRouter := router.PathPrefix(minioReservedBucketPath).HeadersRegexp("User-Agent", ".*Mozilla.*").Subrouter()
    67  
    68  	// Initialize json rpc handlers.
    69  	webRPC := jsonrpc.NewServer()
    70  	webRPC.RegisterCodec(codec, "application/json")
    71  	webRPC.RegisterCodec(codec, "application/json; charset=UTF-8")
    72  	webRPC.RegisterAfterFunc(func(ri *jsonrpc.RequestInfo) {
    73  		if ri != nil {
    74  			claims, _, _ := webRequestAuthenticate(ri.Request)
    75  			bucketName, objectName := extractBucketObject(ri.Args)
    76  			ri.Request = mux.SetURLVars(ri.Request, map[string]string{
    77  				"bucket": bucketName,
    78  				"object": objectName,
    79  			})
    80  			if globalTrace.NumSubscribers() > 0 {
    81  				globalTrace.Publish(WebTrace(ri))
    82  			}
    83  			ctx := NewContext(ri.Request, ri.ResponseWriter, ri.Method)
    84  			logger.AuditLog(ctx, ri.ResponseWriter, ri.Request, claims.Map())
    85  		}
    86  	})
    87  
    88  	// Register RPC handlers with server
    89  	if err := webRPC.RegisterService(web, "web"); err != nil {
    90  		return err
    91  	}
    92  
    93  	// RPC handler at URI - /minio/webrpc
    94  	webBrowserRouter.Methods(http.MethodPost).Path("/webrpc").Handler(webRPC)
    95  	webBrowserRouter.Methods(http.MethodPut).Path("/upload/{bucket}/{object:.+}").HandlerFunc(HTTPTraceHdrs(web.Upload))
    96  
    97  	// These methods use short-expiry tokens in the URLs. These tokens may unintentionally
    98  	// be logged, so a new one must be generated for each request.
    99  	webBrowserRouter.Methods(http.MethodGet).Path("/download/{bucket}/{object:.+}").Queries("token", "{token:.*}").HandlerFunc(HTTPTraceHdrs(web.Download))
   100  	webBrowserRouter.Methods(http.MethodPost).Path("/zip").Queries("token", "{token:.*}").HandlerFunc(HTTPTraceHdrs(web.DownloadZip))
   101  
   102  	// Create compressed assets handler
   103  	assetFS, err := fs.Sub(browser.GetStaticAssets(), assetPrefix)
   104  	if err != nil {
   105  		panic(err)
   106  	}
   107  	compressAssets := handlers.CompressHandler(http.StripPrefix(minioReservedBucketPath, http.FileServer(http.FS(assetFS))))
   108  
   109  	// Serve javascript files and favicon from assets.
   110  	webBrowserRouter.Path(fmt.Sprintf("/{assets:%s}", specialAssets)).Handler(compressAssets)
   111  
   112  	// Serve index.html from assets for rest of the requests.
   113  	webBrowserRouter.Path("/{index:.*}").Handler(indexHandler{compressAssets})
   114  
   115  	return nil
   116  }