add proxy mode to read non-local volumes

This commit is contained in:
zhangsong
2021-06-30 17:28:37 +08:00
parent e9eb15e56a
commit 7566782c2e
5 changed files with 52 additions and 15 deletions

View File

@@ -28,7 +28,7 @@ type VolumeServer struct {
needleMapKind storage.NeedleMapKind
FixJpgOrientation bool
ReadRedirect bool
ReadMode string
compactionBytePerSecond int64
metricsAddress string
metricsIntervalSec int
@@ -50,7 +50,7 @@ func NewVolumeServer(adminMux, publicMux *http.ServeMux, ip string,
dataCenter string, rack string,
whiteList []string,
fixJpgOrientation bool,
readRedirect bool,
readMode string,
compactionMBPerSecond int,
fileSizeLimitMB int,
concurrentUploadLimit int64,
@@ -72,7 +72,7 @@ func NewVolumeServer(adminMux, publicMux *http.ServeMux, ip string,
rack: rack,
needleMapKind: needleMapKind,
FixJpgOrientation: fixJpgOrientation,
ReadRedirect: readRedirect,
ReadMode: readMode,
grpcDialOption: security.LoadClientTLS(util.GetViper(), "grpc.volume"),
compactionBytePerSecond: int64(compactionMBPerSecond) * 1024 * 1024,
fileSizeLimitBytes: int64(fileSizeLimitMB) * 1024 * 1024,

View File

@@ -1,6 +1,7 @@
package weed_server
import (
"fmt"
"net/http"
"strconv"
"strings"
@@ -81,6 +82,7 @@ func getContentLength(r *http.Request) int64 {
}
func (vs *VolumeServer) publicReadOnlyHandler(w http.ResponseWriter, r *http.Request) {
fmt.Printf("publicReadOnlyHandler in.")
w.Header().Set("Server", "SeaweedFS Volume "+util.VERSION)
if r.Header.Get("Origin") != "" {
w.Header().Set("Access-Control-Allow-Origin", "*")

View File

@@ -58,14 +58,53 @@ func (vs *VolumeServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request)
hasVolume := vs.store.HasVolume(volumeId)
_, hasEcVolume := vs.store.FindEcVolume(volumeId)
if !hasVolume && !hasEcVolume {
if !vs.ReadRedirect {
glog.V(2).Infoln("volume is not local:", err, r.URL.Path)
if vs.ReadMode == "local" {
glog.V(0).Infoln("volume is not local:", err, r.URL.Path)
w.WriteHeader(http.StatusNotFound)
return
}
lookupResult, err := operation.Lookup(vs.GetMaster, volumeId.String())
glog.V(2).Infoln("volume", volumeId, "found on", lookupResult, "error", err)
if err == nil && len(lookupResult.Locations) > 0 {
if err != nil || len(lookupResult.Locations) <= 0{
glog.V(0).Infoln("lookup error:", err, r.URL.Path)
w.WriteHeader(http.StatusNotFound)
return
}
if vs.ReadMode == "remote" {
// proxy client request to target server
u, _ := url.Parse(util.NormalizeUrl(lookupResult.Locations[0].Url))
r.URL.Host = u.Host
r.URL.Scheme = u.Scheme
request, err := http.NewRequest("GET", r.URL.String(), nil)
if err != nil {
glog.V(0).Infof("failed to instance http request of url %s: %v", r.URL.String(), err)
w.WriteHeader(http.StatusInternalServerError)
return
}
for k, vv := range r.Header {
for _, v := range vv {
request.Header.Add(k, v)
}
}
response, err := client.Do(request)
if err != nil {
glog.V(0).Infof("request remote url %s: %v", r.URL.String(), err)
w.WriteHeader(http.StatusInternalServerError)
return
}
defer util.CloseResponse(response)
// proxy target response to client
for k, vv := range response.Header {
for _, v := range vv {
w.Header().Add(k, v)
}
}
w.WriteHeader(response.StatusCode)
io.Copy(w, response.Body)
return
} else {
// redirect
u, _ := url.Parse(util.NormalizeUrl(lookupResult.Locations[0].PublicUrl))
u.Path = fmt.Sprintf("%s/%s,%s", u.Path, vid, fid)
arg := url.Values{}
@@ -74,12 +113,8 @@ func (vs *VolumeServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request)
}
u.RawQuery = arg.Encode()
http.Redirect(w, r, u.String(), http.StatusMovedPermanently)
} else {
glog.V(2).Infoln("lookup error:", err, r.URL.Path)
w.WriteHeader(http.StatusNotFound)
return
}
return
}
cookie := n.Cookie