S3 bucket list, response with uploaded storageclass.

This commit is contained in:
ruitao.liu 2020-10-29 14:57:19 +08:00
parent 2dcc178d0a
commit b917be7955
4 changed files with 157 additions and 14 deletions

View file

@ -4,7 +4,6 @@ import (
"context" "context"
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
@ -13,6 +12,10 @@ import (
"strings" "strings"
"time" "time"
"github.com/chrislusf/seaweedfs/weed/util"
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
"github.com/chrislusf/seaweedfs/weed/filer" "github.com/chrislusf/seaweedfs/weed/filer"
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb" "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
) )
@ -137,6 +140,10 @@ func (s3a *S3ApiServer) listFilerEntries(bucket string, originalPrefix string, m
}) })
} }
} else { } else {
storageClass := "STANDARD"
if v, ok := entry.Extended[util.AmzStorageClass]; ok {
storageClass = string(v)
}
contents = append(contents, ListEntry{ contents = append(contents, ListEntry{
Key: fmt.Sprintf("%s/%s", dir, entry.Name)[len(bucketPrefix):], Key: fmt.Sprintf("%s/%s", dir, entry.Name)[len(bucketPrefix):],
LastModified: time.Unix(entry.Attributes.Mtime, 0).UTC(), LastModified: time.Unix(entry.Attributes.Mtime, 0).UTC(),
@ -146,7 +153,7 @@ func (s3a *S3ApiServer) listFilerEntries(bucket string, originalPrefix string, m
ID: fmt.Sprintf("%x", entry.Attributes.Uid), ID: fmt.Sprintf("%x", entry.Attributes.Uid),
DisplayName: entry.Attributes.UserName, DisplayName: entry.Attributes.UserName,
}, },
StorageClass: "STANDARD", StorageClass: StorageClass(storageClass),
}) })
} }
}) })

View file

@ -97,12 +97,12 @@ func (fs *FilerServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request,
if r.Method == "GET" { if r.Method == "GET" {
tagCount := 0 tagCount := 0
for k, _ := range entry.Extended { for k, _ := range entry.Extended {
if strings.HasPrefix(k, "X-Amz-Tagging-") { if strings.HasPrefix(k, util.AmzObjectTagging+"-") {
tagCount++ tagCount++
} }
} }
if tagCount > 0 { if tagCount > 0 {
w.Header().Set("x-amz-tag-count", strconv.Itoa(tagCount)) w.Header().Set(util.AmzTagCount, strconv.Itoa(tagCount))
} }
} }

View file

@ -312,31 +312,26 @@ func (fs *FilerServer) mkdir(ctx context.Context, w http.ResponseWriter, r *http
} }
func (fs *FilerServer) saveAmzMetaData(r *http.Request, entry *filer.Entry) { func (fs *FilerServer) saveAmzMetaData(r *http.Request, entry *filer.Entry) {
var (
storageClass = "X-Amz-Storage-Class"
objectTagging = "X-Amz-Tagging"
userMetaPrefix = "X-Amz-Meta-"
)
if entry.Extended == nil { if entry.Extended == nil {
entry.Extended = make(map[string][]byte) entry.Extended = make(map[string][]byte)
} }
if sc := r.Header.Get(storageClass); sc != "" { if sc := r.Header.Get(util.AmzStorageClass); sc != "" {
entry.Extended[storageClass] = []byte(sc) entry.Extended[util.AmzStorageClass] = []byte(sc)
} }
if tags := r.Header.Get(objectTagging); tags != "" { if tags := r.Header.Get(util.AmzObjectTagging); tags != "" {
for _, v := range strings.Split(tags, "&") { for _, v := range strings.Split(tags, "&") {
tag := strings.Split(v, "=") tag := strings.Split(v, "=")
if len(tag) == 2 { if len(tag) == 2 {
entry.Extended[objectTagging+"-"+tag[0]] = []byte(tag[1]) entry.Extended[util.AmzObjectTagging+"-"+tag[0]] = []byte(tag[1])
} }
} }
} }
for header, values := range r.Header { for header, values := range r.Header {
if strings.HasPrefix(header, userMetaPrefix) { if strings.HasPrefix(header, util.AmzUserMetaPrefix) {
for _, value := range values { for _, value := range values {
entry.Extended[header] = []byte(value) entry.Extended[header] = []byte(value)
} }

141
weed/util/http_header.go Normal file
View file

@ -0,0 +1,141 @@
/*
* MinIO Cloud Storage, (C) 2019 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package util
// Standard S3 HTTP response constants
const (
LastModified = "Last-Modified"
Date = "Date"
ETag = "ETag"
ContentType = "Content-Type"
ContentMD5 = "Content-Md5"
ContentEncoding = "Content-Encoding"
Expires = "Expires"
ContentLength = "Content-Length"
ContentLanguage = "Content-Language"
ContentRange = "Content-Range"
Connection = "Connection"
AcceptRanges = "Accept-Ranges"
AmzBucketRegion = "X-Amz-Bucket-Region"
ServerInfo = "Server"
RetryAfter = "Retry-After"
Location = "Location"
CacheControl = "Cache-Control"
ContentDisposition = "Content-Disposition"
Authorization = "Authorization"
Action = "Action"
Range = "Range"
)
// Non standard S3 HTTP response constants
const (
XCache = "X-Cache"
XCacheLookup = "X-Cache-Lookup"
)
// Standard S3 HTTP request constants
const (
IfModifiedSince = "If-Modified-Since"
IfUnmodifiedSince = "If-Unmodified-Since"
IfMatch = "If-Match"
IfNoneMatch = "If-None-Match"
// S3 storage class
AmzStorageClass = "x-amz-storage-class"
// S3 user-defined metadata
AmzUserMetaPrefix = "X-Amz-Meta-"
// S3 object version ID
AmzVersionID = "x-amz-version-id"
AmzDeleteMarker = "x-amz-delete-marker"
// S3 object tagging
AmzObjectTagging = "X-Amz-Tagging"
AmzTagCount = "x-amz-tagging-count"
AmzTagDirective = "X-Amz-Tagging-Directive"
// S3 extensions
AmzCopySourceIfModifiedSince = "x-amz-copy-source-if-modified-since"
AmzCopySourceIfUnmodifiedSince = "x-amz-copy-source-if-unmodified-since"
AmzCopySourceIfNoneMatch = "x-amz-copy-source-if-none-match"
AmzCopySourceIfMatch = "x-amz-copy-source-if-match"
AmzCopySource = "X-Amz-Copy-Source"
AmzCopySourceVersionID = "X-Amz-Copy-Source-Version-Id"
AmzCopySourceRange = "X-Amz-Copy-Source-Range"
AmzMetadataDirective = "X-Amz-Metadata-Directive"
AmzObjectLockMode = "X-Amz-Object-Lock-Mode"
AmzObjectLockRetainUntilDate = "X-Amz-Object-Lock-Retain-Until-Date"
AmzObjectLockLegalHold = "X-Amz-Object-Lock-Legal-Hold"
AmzObjectLockBypassGovernance = "X-Amz-Bypass-Governance-Retention"
AmzBucketReplicationStatus = "X-Amz-Replication-Status"
// Multipart parts count
AmzMpPartsCount = "x-amz-mp-parts-count"
// Object date/time of expiration
AmzExpiration = "x-amz-expiration"
// Dummy putBucketACL
AmzACL = "x-amz-acl"
// Signature V4 related contants.
AmzContentSha256 = "X-Amz-Content-Sha256"
AmzDate = "X-Amz-Date"
AmzAlgorithm = "X-Amz-Algorithm"
AmzExpires = "X-Amz-Expires"
AmzSignedHeaders = "X-Amz-SignedHeaders"
AmzSignature = "X-Amz-Signature"
AmzCredential = "X-Amz-Credential"
AmzSecurityToken = "X-Amz-Security-Token"
AmzDecodedContentLength = "X-Amz-Decoded-Content-Length"
AmzMetaUnencryptedContentLength = "X-Amz-Meta-X-Amz-Unencrypted-Content-Length"
AmzMetaUnencryptedContentMD5 = "X-Amz-Meta-X-Amz-Unencrypted-Content-Md5"
// Signature v2 related constants
AmzSignatureV2 = "Signature"
AmzAccessKeyID = "AWSAccessKeyId"
// Response request id.
AmzRequestID = "x-amz-request-id"
// Deployment id.
MinioDeploymentID = "x-minio-deployment-id"
// Server-Status
MinIOServerStatus = "x-minio-server-status"
// Delete special flag to force delete a bucket
MinIOForceDelete = "x-minio-force-delete"
// Header indicates if the mtime should be preserved by client
MinIOSourceMTime = "x-minio-source-mtime"
// Header indicates if the etag should be preserved by client
MinIOSourceETag = "x-minio-source-etag"
)
// Common http query params S3 API
const (
VersionID = "versionId"
PartNumber = "partNumber"
UploadID = "uploadId"
)