From 937cfacc01c0acd27f352f1f57b8abd6f1e8bc56 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Sat, 23 Jan 2021 03:43:48 -0800 Subject: [PATCH] filer: add "proxyToFileId" to reverse proxy to a volume server --- weed/server/filer_server_handlers.go | 13 ++++- weed/server/filer_server_handlers_proxy.go | 66 ++++++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 weed/server/filer_server_handlers_proxy.go diff --git a/weed/server/filer_server_handlers.go b/weed/server/filer_server_handlers.go index 451e2a2de..5b93c6d08 100644 --- a/weed/server/filer_server_handlers.go +++ b/weed/server/filer_server_handlers.go @@ -17,9 +17,16 @@ func (fs *FilerServer) filerHandler(w http.ResponseWriter, r *http.Request) { start := time.Now() switch r.Method { case "GET": - stats.FilerRequestCounter.WithLabelValues("get").Inc() - fs.GetOrHeadHandler(w, r, true) - stats.FilerRequestHistogram.WithLabelValues("get").Observe(time.Since(start).Seconds()) + fileId := r.FormValue("proxyToFileId") + if fileId != "" { + stats.FilerRequestCounter.WithLabelValues("proxy").Inc() + fs.proxyToVolumeServer(w,r,fileId) + stats.FilerRequestHistogram.WithLabelValues("proxy").Observe(time.Since(start).Seconds()) + } else { + stats.FilerRequestCounter.WithLabelValues("get").Inc() + fs.GetOrHeadHandler(w, r, true) + stats.FilerRequestHistogram.WithLabelValues("get").Observe(time.Since(start).Seconds()) + } case "HEAD": stats.FilerRequestCounter.WithLabelValues("head").Inc() fs.GetOrHeadHandler(w, r, false) diff --git a/weed/server/filer_server_handlers_proxy.go b/weed/server/filer_server_handlers_proxy.go new file mode 100644 index 000000000..5ba42e71d --- /dev/null +++ b/weed/server/filer_server_handlers_proxy.go @@ -0,0 +1,66 @@ +package weed_server + +import ( + "github.com/chrislusf/seaweedfs/weed/glog" + "github.com/chrislusf/seaweedfs/weed/util" + "io" + "math/rand" + "net/http" +) + +var ( + client *http.Client +) + +func init() { + client = &http.Client{Transport: &http.Transport{ + MaxIdleConnsPerHost: 1024, + }} +} + +func (fs *FilerServer) proxyToVolumeServer(w http.ResponseWriter, r *http.Request, fileId string) { + + urlStrings, err := fs.filer.MasterClient.GetLookupFileIdFunction()(fileId) + if err != nil { + glog.Errorf("locate %s: %v", fileId, err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + if len(urlStrings) == 0 { + w.WriteHeader(http.StatusNotFound) + return + } + + proxyReq, err := http.NewRequest("GET", urlStrings[rand.Intn(len(urlStrings))], r.Body) + if err != nil { + glog.Errorf("NewRequest %s: %v", urlStrings[0], err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + proxyReq.Header.Set("Host", r.Host) + proxyReq.Header.Set("X-Forwarded-For", r.RemoteAddr) + + for header, values := range r.Header { + for _, value := range values { + proxyReq.Header.Add(header, value) + } + } + + proxyResponse, postErr := client.Do(proxyReq) + + if postErr != nil { + glog.Errorf("post to filer: %v", postErr) + w.WriteHeader(http.StatusInternalServerError) + return + } + defer util.CloseResponse(proxyResponse) + + for k, v := range proxyResponse.Header { + w.Header()[k] = v + } + w.WriteHeader(proxyResponse.StatusCode) + io.Copy(w, proxyResponse.Body) + +}