diff options
| -rw-r--r-- | weed/s3api/filer_multipart.go | 6 | ||||
| -rw-r--r-- | weed/s3api/s3api_object_multipart_handlers.go | 4 | ||||
| -rw-r--r-- | weed/server/common.go | 10 | ||||
| -rw-r--r-- | weed/server/filer_server_handlers_read.go | 2 | ||||
| -rw-r--r-- | weed/server/filer_server_handlers_write_autochunk.go | 2 | ||||
| -rw-r--r-- | weed/storage/volume_backup.go | 61 | ||||
| -rw-r--r-- | weed/storage/volume_write_test.go | 23 |
7 files changed, 89 insertions, 19 deletions
diff --git a/weed/s3api/filer_multipart.go b/weed/s3api/filer_multipart.go index 9a485ec66..fca1a0aa4 100644 --- a/weed/s3api/filer_multipart.go +++ b/weed/s3api/filer_multipart.go @@ -38,6 +38,9 @@ func (s3a *S3ApiServer) createMultipartUpload(input *s3.CreateMultipartUploadInp for k, v := range input.Metadata { entry.Extended[k] = []byte(*v) } + if input.ContentType != nil { + entry.Attributes.Mime = *input.ContentType + } }); err != nil { glog.Errorf("NewMultipartUpload error: %v", err) return nil, s3err.ErrInternalError @@ -121,6 +124,9 @@ func (s3a *S3ApiServer) completeMultipartUpload(input *s3.CompleteMultipartUploa entry.Extended[k] = v } } + if pentry.Attributes.Mime != "" { + entry.Attributes.Mime = pentry.Attributes.Mime + } }) if err != nil { diff --git a/weed/s3api/s3api_object_multipart_handlers.go b/weed/s3api/s3api_object_multipart_handlers.go index c9ad222b1..ab72b8437 100644 --- a/weed/s3api/s3api_object_multipart_handlers.go +++ b/weed/s3api/s3api_object_multipart_handlers.go @@ -36,6 +36,10 @@ func (s3a *S3ApiServer) NewMultipartUploadHandler(w http.ResponseWriter, r *http createMultipartUploadInput.Metadata[k] = aws.String(string(v)) } + contentType := r.Header.Get("Content-Type") + if contentType != "" { + createMultipartUploadInput.ContentType = &contentType + } response, errCode := s3a.createMultipartUpload(createMultipartUploadInput) glog.V(2).Info("NewMultipartUploadHandler", string(s3err.EncodeXMLResponse(response)), errCode) diff --git a/weed/server/common.go b/weed/server/common.go index 2054e1a84..16213689d 100644 --- a/weed/server/common.go +++ b/weed/server/common.go @@ -9,6 +9,7 @@ import ( "io/fs" "mime/multipart" "net/http" + "net/url" "path/filepath" "strconv" "strings" @@ -250,7 +251,16 @@ func handleStaticResources2(r *mux.Router) { } func adjustHeaderContentDisposition(w http.ResponseWriter, r *http.Request, filename string) { + responseContentDisposition := r.FormValue("response-content-disposition") + if responseContentDisposition != "" { + w.Header().Set("Content-Disposition", responseContentDisposition) + return + } + if w.Header().Get("Content-Disposition") != "" { + return + } if filename != "" { + filename = url.QueryEscape(filename) contentDisposition := "inline" if r.FormValue("dl") != "" { if dl, _ := strconv.ParseBool(r.FormValue("dl")); dl { diff --git a/weed/server/filer_server_handlers_read.go b/weed/server/filer_server_handlers_read.go index 9fc9da60f..c24e8780c 100644 --- a/weed/server/filer_server_handlers_read.go +++ b/weed/server/filer_server_handlers_read.go @@ -7,7 +7,6 @@ import ( "io" "mime" "net/http" - "net/url" "path/filepath" "strconv" "strings" @@ -133,7 +132,6 @@ func (fs *FilerServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request) setEtag(w, etag) filename := entry.Name() - filename = url.QueryEscape(filename) adjustHeaderContentDisposition(w, r, filename) totalSize := int64(entry.Size()) diff --git a/weed/server/filer_server_handlers_write_autochunk.go b/weed/server/filer_server_handlers_write_autochunk.go index 872d83fca..1c230bad3 100644 --- a/weed/server/filer_server_handlers_write_autochunk.go +++ b/weed/server/filer_server_handlers_write_autochunk.go @@ -218,7 +218,7 @@ func (fs *FilerServer) saveMetaData(ctx context.Context, r *http.Request, fileNa entry.Extended = SaveAmzMetaData(r, entry.Extended, false) for k, v := range r.Header { - if len(v) > 0 && (strings.HasPrefix(k, needle.PairNamePrefix) || k == "Cache-Control" || k == "Expires") { + if len(v) > 0 && (strings.HasPrefix(k, needle.PairNamePrefix) || k == "Cache-Control" || k == "Expires" || k == "Content-Disposition") { entry.Extended[k] = []byte(v[0]) } } diff --git a/weed/storage/volume_backup.go b/weed/storage/volume_backup.go index 500f48b23..a8ec50cad 100644 --- a/weed/storage/volume_backup.go +++ b/weed/storage/volume_backup.go @@ -194,6 +194,35 @@ func (v *Volume) BinarySearchByAppendAtNs(sinceNs uint64) (offset Offset, isLast err = fmt.Errorf("read entry %d: %v", m, err) return } + if offset.IsZero() { + leftIndex, _, leftNs, leftErr := v.readLeftNs(m) + if leftErr != nil { + err = leftErr + return + } + rightIndex, rightOffset, rightNs, rightErr := v.readRightNs(m) + if rightErr != nil { + err = rightErr + return + } + if rightNs <= sinceNs { + l = rightIndex + if l == entryCount { + return Offset{}, true, nil + } else { + continue + } + } + if sinceNs < leftNs { + h = leftIndex + 1 + continue + } + return rightOffset, false, nil + + } + if offset.IsZero() { + return Offset{}, true, nil + } mNs, nsReadErr := v.readAppendAtNs(offset) if nsReadErr != nil { @@ -220,6 +249,38 @@ func (v *Volume) BinarySearchByAppendAtNs(sinceNs uint64) (offset Offset, isLast } +func (v *Volume) readRightNs(m int64) (index int64, offset Offset, ts uint64, err error) { + index = m + for offset.IsZero() { + index++ + offset, err = v.readOffsetFromIndex(index) + if err != nil { + err = fmt.Errorf("read entry %d: %v", index, err) + return + } + } + if !offset.IsZero() { + ts, err = v.readAppendAtNs(offset) + } + return +} + +func (v *Volume) readLeftNs(m int64) (index int64, offset Offset, ts uint64, err error) { + index = m + for offset.IsZero() { + index-- + offset, err = v.readOffsetFromIndex(index) + if err != nil { + err = fmt.Errorf("read entry %d: %v", index, err) + return + } + } + if !offset.IsZero() { + ts, err = v.readAppendAtNs(offset) + } + return +} + // bytes is of size NeedleMapEntrySize func (v *Volume) readOffsetFromIndex(m int64) (Offset, error) { v.dataFileAccessLock.RLock() diff --git a/weed/storage/volume_write_test.go b/weed/storage/volume_write_test.go index e0ee3dac7..309f29657 100644 --- a/weed/storage/volume_write_test.go +++ b/weed/storage/volume_write_test.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/chrislusf/seaweedfs/weed/storage/needle" "github.com/chrislusf/seaweedfs/weed/storage/super_block" + "github.com/chrislusf/seaweedfs/weed/storage/types" "io/ioutil" "os" "testing" @@ -22,9 +23,9 @@ func TestSearchVolumesWithDeletedNeedles(t *testing.T) { t.Fatalf("volume creation: %v", err) } - count := 10 + count := 20 - for i:=1;i<count;i++{ + for i := 1; i < count; i++ { n := newRandomNeedle(uint64(i)) _, _, _, err := v.writeNeedle2(n, true, false) if err != nil { @@ -32,9 +33,9 @@ func TestSearchVolumesWithDeletedNeedles(t *testing.T) { } } - for i:=1;i<5;i++{ + for i := 1; i < 15; i++ { n := newEmptyNeedle(uint64(i)) - _, err := v.doDeleteRequest(n) + err := v.nm.Put(n.Id, types.Offset{}, types.TombstoneFileSize) if err != nil { t.Fatalf("delete needle %d: %v", i, err) } @@ -42,15 +43,12 @@ func TestSearchVolumesWithDeletedNeedles(t *testing.T) { ts1 := time.Now().UnixNano() - var ts2 uint64 - - for i:=5;i<count;i++{ + for i := 15; i < count; i++ { n := newEmptyNeedle(uint64(i)) _, err := v.doDeleteRequest(n) if err != nil { t.Fatalf("delete needle %d: %v", i, err) } - ts2 = n.AppendAtNs } offset, isLast, err := v.BinarySearchByAppendAtNs(uint64(ts1)) @@ -59,11 +57,4 @@ func TestSearchVolumesWithDeletedNeedles(t *testing.T) { } fmt.Printf("offset: %v, isLast: %v\n", offset.ToActualOffset(), isLast) - offset, isLast, err = v.BinarySearchByAppendAtNs(uint64(ts2)) - if err != nil { - t.Fatalf("lookup by ts: %v", err) - } - fmt.Printf("offset: %v, isLast: %v\n", offset.ToActualOffset(), isLast) - - -}
\ No newline at end of file +} |
