aboutsummaryrefslogtreecommitdiff
path: root/weed/server
diff options
context:
space:
mode:
Diffstat (limited to 'weed/server')
-rw-r--r--weed/server/filer_server_handlers.go25
-rw-r--r--weed/server/filer_server_handlers_read.go19
-rw-r--r--weed/server/filer_server_handlers_write_autochunk.go38
-rw-r--r--weed/server/filer_ui/templates.go2
-rw-r--r--weed/server/volume_grpc_client_to_master.go18
-rw-r--r--weed/server/volume_grpc_copy.go10
-rw-r--r--weed/server/volume_server_handlers.go19
7 files changed, 126 insertions, 5 deletions
diff --git a/weed/server/filer_server_handlers.go b/weed/server/filer_server_handlers.go
index 18f78881c..555036feb 100644
--- a/weed/server/filer_server_handlers.go
+++ b/weed/server/filer_server_handlers.go
@@ -10,6 +10,10 @@ import (
func (fs *FilerServer) filerHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Server", "SeaweedFS Filer "+util.VERSION)
+ if r.Header.Get("Origin") != "" {
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Access-Control-Allow-Credentials", "true")
+ }
start := time.Now()
switch r.Method {
case "GET":
@@ -32,11 +36,19 @@ func (fs *FilerServer) filerHandler(w http.ResponseWriter, r *http.Request) {
stats.FilerRequestCounter.WithLabelValues("post").Inc()
fs.PostHandler(w, r)
stats.FilerRequestHistogram.WithLabelValues("post").Observe(time.Since(start).Seconds())
+ case "OPTIONS":
+ stats.FilerRequestCounter.WithLabelValues("options").Inc()
+ OptionsHandler(w, r, false)
+ stats.FilerRequestHistogram.WithLabelValues("head").Observe(time.Since(start).Seconds())
}
}
func (fs *FilerServer) readonlyFilerHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Server", "SeaweedFS Filer "+util.VERSION)
+ if r.Header.Get("Origin") != "" {
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Access-Control-Allow-Credentials", "true")
+ }
start := time.Now()
switch r.Method {
case "GET":
@@ -47,5 +59,18 @@ func (fs *FilerServer) readonlyFilerHandler(w http.ResponseWriter, r *http.Reque
stats.FilerRequestCounter.WithLabelValues("head").Inc()
fs.GetOrHeadHandler(w, r, false)
stats.FilerRequestHistogram.WithLabelValues("head").Observe(time.Since(start).Seconds())
+ case "OPTIONS":
+ stats.FilerRequestCounter.WithLabelValues("options").Inc()
+ OptionsHandler(w, r, true)
+ stats.FilerRequestHistogram.WithLabelValues("head").Observe(time.Since(start).Seconds())
+ }
+}
+
+func OptionsHandler(w http.ResponseWriter, r *http.Request, isReadOnly bool) {
+ if isReadOnly {
+ w.Header().Add("Access-Control-Allow-Methods", "GET, OPTIONS")
+ } else {
+ w.Header().Add("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS")
}
+ w.Header().Add("Access-Control-Allow-Headers", "*")
}
diff --git a/weed/server/filer_server_handlers_read.go b/weed/server/filer_server_handlers_read.go
index fbd45d6b9..69d485e90 100644
--- a/weed/server/filer_server_handlers_read.go
+++ b/weed/server/filer_server_handlers_read.go
@@ -15,6 +15,7 @@ import (
"github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/images"
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
+ xhttp "github.com/chrislusf/seaweedfs/weed/s3api/http"
"github.com/chrislusf/seaweedfs/weed/stats"
"github.com/chrislusf/seaweedfs/weed/util"
)
@@ -93,6 +94,24 @@ func (fs *FilerServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request,
}
}
+ // print out the header from extended properties
+ for k, v := range entry.Extended {
+ w.Header().Set(k, string(v))
+ }
+
+ //set tag count
+ if r.Method == "GET" {
+ tagCount := 0
+ for k := range entry.Extended {
+ if strings.HasPrefix(k, xhttp.AmzObjectTagging+"-") {
+ tagCount++
+ }
+ }
+ if tagCount > 0 {
+ w.Header().Set(xhttp.AmzTagCount, strconv.Itoa(tagCount))
+ }
+ }
+
// set etag
etag := filer.ETagEntry(entry)
if inm := r.Header.Get("If-None-Match"); inm == "\""+etag+"\"" {
diff --git a/weed/server/filer_server_handlers_write_autochunk.go b/weed/server/filer_server_handlers_write_autochunk.go
index d86d49b2a..ee0af9aab 100644
--- a/weed/server/filer_server_handlers_write_autochunk.go
+++ b/weed/server/filer_server_handlers_write_autochunk.go
@@ -18,8 +18,10 @@ import (
"github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/operation"
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
+ xhttp "github.com/chrislusf/seaweedfs/weed/s3api/http"
"github.com/chrislusf/seaweedfs/weed/security"
"github.com/chrislusf/seaweedfs/weed/stats"
+ "github.com/chrislusf/seaweedfs/weed/storage/needle"
"github.com/chrislusf/seaweedfs/weed/util"
)
@@ -176,6 +178,18 @@ func (fs *FilerServer) saveMetaData(ctx context.Context, r *http.Request, fileNa
Size: chunkOffset,
}
+ if entry.Extended == nil {
+ entry.Extended = make(map[string][]byte)
+ }
+
+ fs.saveAmzMetaData(r, entry)
+
+ for k, v := range r.Header {
+ if len(v) > 0 && strings.HasPrefix(k, needle.PairNamePrefix) {
+ entry.Extended[k] = []byte(v[0])
+ }
+ }
+
if dbErr := fs.filer.CreateEntry(ctx, entry, false, false, nil); dbErr != nil {
fs.filer.DeleteChunks(entry.Chunks)
replyerr = dbErr
@@ -308,3 +322,27 @@ func (fs *FilerServer) mkdir(ctx context.Context, w http.ResponseWriter, r *http
}
return filerResult, replyerr
}
+
+func (fs *FilerServer) saveAmzMetaData(r *http.Request, entry *filer.Entry) {
+
+ if sc := r.Header.Get(xhttp.AmzStorageClass); sc != "" {
+ entry.Extended[xhttp.AmzStorageClass] = []byte(sc)
+ }
+
+ if tags := r.Header.Get(xhttp.AmzObjectTagging); tags != "" {
+ for _, v := range strings.Split(tags, "&") {
+ tag := strings.Split(v, "=")
+ if len(tag) == 2 {
+ entry.Extended[xhttp.AmzObjectTagging+"-"+tag[0]] = []byte(tag[1])
+ }
+ }
+ }
+
+ for header, values := range r.Header {
+ if strings.HasPrefix(header, xhttp.AmzUserMetaPrefix) {
+ for _, value := range values {
+ entry.Extended[header] = []byte(value)
+ }
+ }
+ }
+}
diff --git a/weed/server/filer_ui/templates.go b/weed/server/filer_ui/templates.go
index f86dde5b1..3f0647119 100644
--- a/weed/server/filer_ui/templates.go
+++ b/weed/server/filer_ui/templates.go
@@ -25,7 +25,7 @@ var StatusTpl = template.Must(template.New("status").Funcs(funcMap).Parse(`<!DOC
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/seaweedfsstatic/bootstrap/3.3.1/css/bootstrap.min.css">
<style>
-body { padding-bottom: 70px; }
+body { padding-bottom: 128px; }
#drop-area {
border: 1px transparent;
}
diff --git a/weed/server/volume_grpc_client_to_master.go b/weed/server/volume_grpc_client_to_master.go
index 199f8faba..2f594fa2b 100644
--- a/weed/server/volume_grpc_client_to_master.go
+++ b/weed/server/volume_grpc_client_to_master.go
@@ -203,6 +203,7 @@ func (vs *VolumeServer) doHeartbeat(masterNode, masterGrpcAddress string, grpcDi
}
case <-volumeTickChan:
glog.V(4).Infof("volume server %s:%d heartbeat", vs.store.Ip, vs.store.Port)
+ vs.store.MaybeAdjustVolumeMax()
if err = stream.Send(vs.store.CollectHeartbeat()); err != nil {
glog.V(0).Infof("Volume Server Failed to talk with master %s: %v", masterNode, err)
return "", err
@@ -216,6 +217,23 @@ func (vs *VolumeServer) doHeartbeat(masterNode, masterGrpcAddress string, grpcDi
case err = <-doneChan:
return
case <-vs.stopChan:
+ var volumeMessages []*master_pb.VolumeInformationMessage
+ emptyBeat := &master_pb.Heartbeat{
+ Ip: vs.store.Ip,
+ Port: uint32(vs.store.Port),
+ PublicUrl: vs.store.PublicUrl,
+ MaxVolumeCount: uint32(0),
+ MaxFileKey: uint64(0),
+ DataCenter: vs.store.GetDataCenter(),
+ Rack: vs.store.GetRack(),
+ Volumes: volumeMessages,
+ HasNoVolumes: len(volumeMessages) == 0,
+ }
+ glog.V(1).Infof("volume server %s:%d stops and deletes all volumes", vs.store.Ip, vs.store.Port)
+ if err = stream.Send(emptyBeat); err != nil {
+ glog.V(0).Infof("Volume Server Failed to update to master %s: %v", masterNode, err)
+ return "", err
+ }
return
}
}
diff --git a/weed/server/volume_grpc_copy.go b/weed/server/volume_grpc_copy.go
index cd2b53c8a..2aecb140f 100644
--- a/weed/server/volume_grpc_copy.go
+++ b/weed/server/volume_grpc_copy.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
+ "io/ioutil"
"math"
"os"
"time"
@@ -60,13 +61,14 @@ func (vs *VolumeServer) VolumeCopy(ctx context.Context, req *volume_server_pb.Vo
volumeFileName = storage.VolumeFileName(location.Directory, volFileInfoResp.Collection, int(req.VolumeId))
+ ioutil.WriteFile(volumeFileName+".note", []byte(fmt.Sprintf("copying from %s", req.SourceDataNode)), 0755)
+
// println("source:", volFileInfoResp.String())
- // copy ecx file
- if err := vs.doCopyFile(client, false, req.Collection, req.VolumeId, volFileInfoResp.CompactionRevision, volFileInfoResp.IdxFileSize, volumeFileName, ".idx", false, false); err != nil {
+ if err := vs.doCopyFile(client, false, req.Collection, req.VolumeId, volFileInfoResp.CompactionRevision, volFileInfoResp.DatFileSize, volumeFileName, ".dat", false, true); err != nil {
return err
}
- if err := vs.doCopyFile(client, false, req.Collection, req.VolumeId, volFileInfoResp.CompactionRevision, volFileInfoResp.DatFileSize, volumeFileName, ".dat", false, true); err != nil {
+ if err := vs.doCopyFile(client, false, req.Collection, req.VolumeId, volFileInfoResp.CompactionRevision, volFileInfoResp.IdxFileSize, volumeFileName, ".idx", false, false); err != nil {
return err
}
@@ -74,6 +76,8 @@ func (vs *VolumeServer) VolumeCopy(ctx context.Context, req *volume_server_pb.Vo
return err
}
+ os.Remove(volumeFileName + ".note")
+
return nil
})
diff --git a/weed/server/volume_server_handlers.go b/weed/server/volume_server_handlers.go
index ad13cdf3b..7852c950a 100644
--- a/weed/server/volume_server_handlers.go
+++ b/weed/server/volume_server_handlers.go
@@ -1,10 +1,11 @@
package weed_server
import (
- "github.com/chrislusf/seaweedfs/weed/util"
"net/http"
"strings"
+ "github.com/chrislusf/seaweedfs/weed/util"
+
"github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/security"
"github.com/chrislusf/seaweedfs/weed/stats"
@@ -27,6 +28,10 @@ security settings:
func (vs *VolumeServer) privateStoreHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Server", "SeaweedFS Volume "+util.VERSION)
+ if r.Header.Get("Origin") != "" {
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Access-Control-Allow-Credentials", "true")
+ }
switch r.Method {
case "GET", "HEAD":
stats.ReadRequest()
@@ -37,11 +42,19 @@ func (vs *VolumeServer) privateStoreHandler(w http.ResponseWriter, r *http.Reque
case "PUT", "POST":
stats.WriteRequest()
vs.guard.WhiteList(vs.PostHandler)(w, r)
+ case "OPTIONS":
+ stats.ReadRequest()
+ w.Header().Add("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS")
+ w.Header().Add("Access-Control-Allow-Headers", "*")
}
}
func (vs *VolumeServer) publicReadOnlyHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Server", "SeaweedFS Volume "+util.VERSION)
+ if r.Header.Get("Origin") != "" {
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Access-Control-Allow-Credentials", "true")
+ }
switch r.Method {
case "GET":
stats.ReadRequest()
@@ -49,6 +62,10 @@ func (vs *VolumeServer) publicReadOnlyHandler(w http.ResponseWriter, r *http.Req
case "HEAD":
stats.ReadRequest()
vs.GetOrHeadHandler(w, r)
+ case "OPTIONS":
+ stats.ReadRequest()
+ w.Header().Add("Access-Control-Allow-Methods", "GET, OPTIONS")
+ w.Header().Add("Access-Control-Allow-Headers", "*")
}
}