Merge pull request #537 from harshavardhana/pr_out_add_proper_content_length_for_error_and_success_responses

master
Harshavardhana 10 years ago
commit 251c99176a
  1. 23
      pkg/api/api_bucket_handlers.go
  2. 12
      pkg/api/api_definitions.go
  3. 14
      pkg/api/api_generic_handlers.go
  4. 21
      pkg/api/api_object_handlers.go
  5. 22
      pkg/api/api_response.go
  6. 87
      pkg/api/api_test.go
  7. 2
      pkg/api/headers.go

@ -18,6 +18,7 @@ package api
import ( import (
"net/http" "net/http"
"strconv"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/minio-io/minio/pkg/iodine" "github.com/minio-io/minio/pkg/iodine"
@ -88,12 +89,15 @@ func (server *minioAPI) listObjectsHandler(w http.ResponseWriter, req *http.Requ
switch err := iodine.ToError(err).(type) { switch err := iodine.ToError(err).(type) {
case nil: // success case nil: // success
{ {
// generate response
response := generateListObjectsResponse(bucket, objects, resources)
encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType)
// write headers // write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType)) setCommonHeaders(w, getContentTypeString(acceptsContentType))
// set content-length to the size of the body
w.Header().Set("Content-Length", strconv.Itoa(len(encodedSuccessResponse)))
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
// write body // write body
response := generateObjectsListResult(bucket, objects, resources)
encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType)
w.Write(encodedSuccessResponse) w.Write(encodedSuccessResponse)
} }
case drivers.ObjectNotFound: case drivers.ObjectNotFound:
@ -128,12 +132,15 @@ func (server *minioAPI) listBucketsHandler(w http.ResponseWriter, req *http.Requ
switch err := iodine.ToError(err).(type) { switch err := iodine.ToError(err).(type) {
case nil: case nil:
{ {
response := generateBucketsListResult(buckets) // generate response
response := generateListBucketsResponse(buckets)
encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType)
// write headers // write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType)) setCommonHeaders(w, getContentTypeString(acceptsContentType))
// set content-length to the size of the body
w.Header().Set("Content-Length", strconv.Itoa(len(encodedSuccessResponse)))
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
// write response // write response
encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType)
w.Write(encodedSuccessResponse) w.Write(encodedSuccessResponse)
} }
default: default:
@ -172,7 +179,9 @@ func (server *minioAPI) putBucketHandler(w http.ResponseWriter, req *http.Reques
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
{ {
writeSuccessResponse(w) // Make sure to add Location information here only for bucket
w.Header().Set("Location", "/"+bucket)
writeSuccessResponse(w, acceptsContentType)
} }
case drivers.TooManyBuckets: case drivers.TooManyBuckets:
{ {
@ -217,7 +226,7 @@ func (server *minioAPI) putBucketACLHandler(w http.ResponseWriter, req *http.Req
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
{ {
writeSuccessResponse(w) writeSuccessResponse(w, acceptsContentType)
} }
case drivers.BucketNameInvalid: case drivers.BucketNameInvalid:
{ {
@ -254,5 +263,5 @@ func (server *minioAPI) headBucketHandler(w http.ResponseWriter, req *http.Reque
} }
// Always a success if isValidOp succeeds // Always a success if isValidOp succeeds
writeSuccessResponse(w) writeSuccessResponse(w, acceptsContentType)
} }

@ -25,8 +25,8 @@ const (
maxObjectList = 1000 maxObjectList = 1000
) )
// ObjectListResponse format // ListObjectsResponse - format for list objects response
type ObjectListResponse struct { type ListObjectsResponse struct {
XMLName xml.Name `xml:"ListBucketResult" json:"-"` XMLName xml.Name `xml:"ListBucketResult" json:"-"`
Name string Name string
Prefix string Prefix string
@ -38,8 +38,8 @@ type ObjectListResponse struct {
CommonPrefixes []*Prefix CommonPrefixes []*Prefix
} }
// BucketListResponse - bucket list response format // ListBucketsResponse - format for list buckets response
type BucketListResponse struct { type ListBucketsResponse struct {
XMLName xml.Name `xml:"ListAllMyBucketsResult" json:"-"` XMLName xml.Name `xml:"ListAllMyBucketsResult" json:"-"`
Owner Owner Owner Owner
Buckets struct { Buckets struct {
@ -75,7 +75,7 @@ type Owner struct {
} }
// List of not implemented bucket queries // List of not implemented bucket queries
var unimplementedBucketResourceNames = map[string]bool{ var notimplementedBucketResourceNames = map[string]bool{
"policy": true, "policy": true,
"cors": true, "cors": true,
"lifecycle": true, "lifecycle": true,
@ -91,7 +91,7 @@ var unimplementedBucketResourceNames = map[string]bool{
} }
// List of not implemented object queries // List of not implemented object queries
var unimplementedObjectResourceNames = map[string]bool{ var notimplementedObjectResourceNames = map[string]bool{
"uploadId": true, "uploadId": true,
"torrent": true, "torrent": true,
"uploads": true, "uploads": true,

@ -162,7 +162,7 @@ func (h resourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
writeErrorResponse(w, r, NotAcceptable, acceptsContentType, r.URL.Path) writeErrorResponse(w, r, NotAcceptable, acceptsContentType, r.URL.Path)
return return
} }
if ignoreUnImplementedObjectResources(r) || ignoreUnImplementedBucketResources(r) { if ignoreNotImplementedObjectResources(r) || ignoreNotImplementedBucketResources(r) {
error := getErrorCode(NotImplemented) error := getErrorCode(NotImplemented)
errorResponse := getErrorResponse(error, "") errorResponse := getErrorResponse(error, "")
setCommonHeaders(w, getContentTypeString(acceptsContentType)) setCommonHeaders(w, getContentTypeString(acceptsContentType))
@ -175,22 +175,22 @@ func (h resourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//// helpers //// helpers
// Checks requests for unimplemented Bucket resources // Checks requests for not implemented Bucket resources
func ignoreUnImplementedBucketResources(req *http.Request) bool { func ignoreNotImplementedBucketResources(req *http.Request) bool {
q := req.URL.Query() q := req.URL.Query()
for name := range q { for name := range q {
if unimplementedBucketResourceNames[name] { if notimplementedBucketResourceNames[name] {
return true return true
} }
} }
return false return false
} }
// Checks requests for unimplemented Object resources // Checks requests for not implemented Object resources
func ignoreUnImplementedObjectResources(req *http.Request) bool { func ignoreNotImplementedObjectResources(req *http.Request) bool {
q := req.URL.Query() q := req.URL.Query()
for name := range q { for name := range q {
if unimplementedObjectResourceNames[name] { if notimplementedObjectResourceNames[name] {
return true return true
} }
} }

@ -175,7 +175,26 @@ func (server *minioAPI) putObjectHandler(w http.ResponseWriter, req *http.Reques
switch err := iodine.ToError(err).(type) { switch err := iodine.ToError(err).(type) {
case nil: case nil:
{ {
writeSuccessResponse(w) metadata, err := server.driver.GetObjectMetadata(bucket, object, "")
switch err := iodine.ToError(err).(type) {
case nil:
w.Header().Set("ETag", metadata.Md5)
writeSuccessResponse(w, acceptsContentType)
case drivers.ObjectNotFound:
{
writeErrorResponse(w, req, NoSuchKey, acceptsContentType, req.URL.Path)
}
case drivers.ObjectNameInvalid:
{
writeErrorResponse(w, req, NoSuchKey, acceptsContentType, req.URL.Path)
}
default:
{
log.Error.Println(iodine.New(err, nil))
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
}
}
} }
case drivers.ObjectExists: case drivers.ObjectExists:
{ {

@ -19,6 +19,7 @@ package api
import ( import (
"net/http" "net/http"
"sort" "sort"
"strconv"
"github.com/minio-io/minio/pkg/storage/drivers" "github.com/minio-io/minio/pkg/storage/drivers"
) )
@ -34,9 +35,9 @@ const (
// //
// output: // output:
// populated struct that can be serialized to match xml and json api spec output // populated struct that can be serialized to match xml and json api spec output
func generateBucketsListResult(buckets []drivers.BucketMetadata) BucketListResponse { func generateListBucketsResponse(buckets []drivers.BucketMetadata) ListBucketsResponse {
var listbuckets []*Bucket var listbuckets []*Bucket
var data = BucketListResponse{} var data = ListBucketsResponse{}
var owner = Owner{} var owner = Owner{}
owner.ID = "minio" owner.ID = "minio"
@ -70,11 +71,11 @@ func (b itemKey) Less(i, j int) bool { return b[i].Key < b[j].Key }
// //
// output: // output:
// populated struct that can be serialized to match xml and json api spec output // populated struct that can be serialized to match xml and json api spec output
func generateObjectsListResult(bucket string, objects []drivers.ObjectMetadata, bucketResources drivers.BucketResourcesMetadata) ObjectListResponse { func generateListObjectsResponse(bucket string, objects []drivers.ObjectMetadata, bucketResources drivers.BucketResourcesMetadata) ListObjectsResponse {
var contents []*Item var contents []*Item
var prefixes []*Prefix var prefixes []*Prefix
var owner = Owner{} var owner = Owner{}
var data = ObjectListResponse{} var data = ListObjectsResponse{}
owner.ID = "minio" owner.ID = "minio"
owner.DisplayName = "minio" owner.DisplayName = "minio"
@ -110,20 +111,23 @@ func generateObjectsListResult(bucket string, objects []drivers.ObjectMetadata,
} }
// writeSuccessResponse - write success headers // writeSuccessResponse - write success headers
func writeSuccessResponse(w http.ResponseWriter) { func writeSuccessResponse(w http.ResponseWriter, acceptsContentType contentType) {
w.Header().Set("Server", "Minio") setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.Header().Set("Connection", "close")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
} }
// writeErrorRespone - write error headers // writeErrorRespone - write error headers
func writeErrorResponse(w http.ResponseWriter, req *http.Request, errorType int, acceptsContentType contentType, resource string) { func writeErrorResponse(w http.ResponseWriter, req *http.Request, errorType int, acceptsContentType contentType, resource string) {
error := getErrorCode(errorType) error := getErrorCode(errorType)
// generate error response
errorResponse := getErrorResponse(error, resource) errorResponse := getErrorResponse(error, resource)
// set headers encodedErrorResponse := encodeErrorResponse(errorResponse, acceptsContentType)
// set common headers
setCommonHeaders(w, getContentTypeString(acceptsContentType)) setCommonHeaders(w, getContentTypeString(acceptsContentType))
// set content-length to size of error response
w.Header().Set("Content-Length", strconv.Itoa(len(encodedErrorResponse)))
// set headers
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
// write body // write body
encodedErrorResponse := encodeErrorResponse(errorResponse, acceptsContentType)
w.Write(encodedErrorResponse) w.Write(encodedErrorResponse)
} }

@ -168,6 +168,7 @@ func (s *MySuite) TestEmptyObject(c *C) {
} }
typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once() typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once()
typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything).Return(nil).Once() typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything).Return(nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(metadata, nil).Once()
typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Twice() typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Twice()
typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(metadata, nil).Once() typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(metadata, nil).Once()
typedDriver.On("GetObject", mock.Anything, "bucket", "object").Return(int64(0), nil).Once() typedDriver.On("GetObject", mock.Anything, "bucket", "object").Return(int64(0), nil).Once()
@ -179,6 +180,7 @@ func (s *MySuite) TestEmptyObject(c *C) {
buffer := bytes.NewBufferString("") buffer := bytes.NewBufferString("")
driver.CreateBucket("bucket", "private") driver.CreateBucket("bucket", "private")
driver.CreateObject("bucket", "object", "", "", buffer) driver.CreateObject("bucket", "object", "", "", buffer)
driver.GetObjectMetadata("bucket", "object", "")
request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil) request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -250,6 +252,7 @@ func (s *MySuite) TestObject(c *C) {
} }
typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once() typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once()
typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything).Return(nil).Once() typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything).Return(nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(metadata, nil).Twice()
typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Twice() typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Twice()
typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(metadata, nil).Twice() typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(metadata, nil).Twice()
typedDriver.SetGetObjectWriter("bucket", "object", []byte("hello world")) typedDriver.SetGetObjectWriter("bucket", "object", []byte("hello world"))
@ -262,6 +265,7 @@ func (s *MySuite) TestObject(c *C) {
buffer := bytes.NewBufferString("hello world") buffer := bytes.NewBufferString("hello world")
driver.CreateBucket("bucket", "private") driver.CreateBucket("bucket", "private")
driver.CreateObject("bucket", "object", "", "", buffer) driver.CreateObject("bucket", "object", "", "", buffer)
driver.GetObjectMetadata("bucket", "object", "")
request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil) request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -325,11 +329,17 @@ func (s *MySuite) TestMultipleObjects(c *C) {
typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once() typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once()
driver.CreateBucket("bucket", "private") driver.CreateBucket("bucket", "private")
typedDriver.On("CreateObject", "bucket", "object1", "", "", mock.Anything).Return(nil).Once() typedDriver.On("CreateObject", "bucket", "object1", "", "", mock.Anything).Return(nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "object1", "").Return(metadata1, nil).Once()
driver.CreateObject("bucket", "object1", "", "", buffer1) driver.CreateObject("bucket", "object1", "", "", buffer1)
driver.GetObjectMetadata("bucket", "object1", "")
typedDriver.On("CreateObject", "bucket", "object2", "", "", mock.Anything).Return(nil).Once() typedDriver.On("CreateObject", "bucket", "object2", "", "", mock.Anything).Return(nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "object2", "").Return(metadata2, nil).Once()
driver.CreateObject("bucket", "object2", "", "", buffer2) driver.CreateObject("bucket", "object2", "", "", buffer2)
driver.GetObjectMetadata("bucket", "object2", "")
typedDriver.On("CreateObject", "bucket", "object3", "", "", mock.Anything).Return(nil).Once() typedDriver.On("CreateObject", "bucket", "object3", "", "", mock.Anything).Return(nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "object3", "").Return(metadata3, nil).Once()
driver.CreateObject("bucket", "object3", "", "", buffer3) driver.CreateObject("bucket", "object3", "", "", buffer3)
driver.GetObjectMetadata("bucket", "object3", "")
// test non-existant object // test non-existant object
typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Once() typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Once()
@ -494,11 +504,6 @@ func (s *MySuite) TestHeader(c *C) {
verifyError(c, response, "NoSuchKey", "The specified key does not exist.", http.StatusNotFound) verifyError(c, response, "NoSuchKey", "The specified key does not exist.", http.StatusNotFound)
buffer := bytes.NewBufferString("hello world")
typedDriver.On("GetBucketMetadata", "foo").Return(bucketMetadata, nil).Once()
typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything).Return(nil).Once()
driver.CreateObject("bucket", "object", "", "", buffer)
objectMetadata := drivers.ObjectMetadata{ objectMetadata := drivers.ObjectMetadata{
Bucket: "bucket", Bucket: "bucket",
Key: "object", Key: "object",
@ -508,6 +513,13 @@ func (s *MySuite) TestHeader(c *C) {
Size: 11, Size: 11,
} }
buffer := bytes.NewBufferString("hello world")
typedDriver.On("GetBucketMetadata", "foo").Return(bucketMetadata, nil).Once()
typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything).Return(nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(objectMetadata, nil).Once()
driver.CreateObject("bucket", "object", "", "", buffer)
driver.GetObjectMetadata("bucket", "object", "")
typedDriver.On("GetBucketMetadata", "bucket").Return(bucketMetadata, nil).Once() typedDriver.On("GetBucketMetadata", "bucket").Return(bucketMetadata, nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(objectMetadata, nil).Once() typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(objectMetadata, nil).Once()
typedDriver.SetGetObjectWriter("", "", []byte("hello world")) typedDriver.SetGetObjectWriter("", "", []byte("hello world"))
@ -608,15 +620,6 @@ func (s *MySuite) TestPutObject(c *C) {
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
typedDriver.On("CreateObject", "bucket", "two", "", "", mock.Anything).Return(nil).Once()
request, err = http.NewRequest("PUT", testServer.URL+"/bucket/two", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil)
setAuthHeader(request)
response, err = client.Do(request)
c.Assert(err, IsNil)
c.Assert(response.StatusCode, Equals, http.StatusOK)
twoMetadata := drivers.ObjectMetadata{ twoMetadata := drivers.ObjectMetadata{
Bucket: "bucket", Bucket: "bucket",
Key: "two", Key: "two",
@ -626,6 +629,16 @@ func (s *MySuite) TestPutObject(c *C) {
Size: 11, Size: 11,
} }
typedDriver.On("CreateObject", "bucket", "two", "", "", mock.Anything).Return(nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "two", "").Return(twoMetadata, nil).Once()
request, err = http.NewRequest("PUT", testServer.URL+"/bucket/two", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil)
setAuthHeader(request)
response, err = client.Do(request)
c.Assert(err, IsNil)
c.Assert(response.StatusCode, Equals, http.StatusOK)
date2 := time.Now() date2 := time.Now()
resources.Maxkeys = 1000 resources.Maxkeys = 1000
@ -731,8 +744,8 @@ func (s *MySuite) TestListBuckets(c *C) {
c.Assert(listResponse.Buckets.Bucket[1].Name, Equals, "foo") c.Assert(listResponse.Buckets.Bucket[1].Name, Equals, "foo")
} }
func readListBucket(reader io.Reader) (BucketListResponse, error) { func readListBucket(reader io.Reader) (ListBucketsResponse, error) {
var results BucketListResponse var results ListBucketsResponse
decoder := xml.NewDecoder(reader) decoder := xml.NewDecoder(reader)
err := decoder.Decode(&results) err := decoder.Decode(&results)
return results, err return results, err
@ -893,8 +906,19 @@ func (s *MySuite) TestContentTypePersists(c *C) {
Created: time.Now(), Created: time.Now(),
ACL: drivers.BucketACL("private"), ACL: drivers.BucketACL("private"),
} }
// test head
oneMetadata := drivers.ObjectMetadata{
Bucket: "bucket",
Key: "one",
ContentType: "application/octet-stream",
Created: time.Now(),
Md5: "d41d8cd98f00b204e9800998ecf8427e",
Size: 0,
}
typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once() typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once()
typedDriver.On("CreateObject", "bucket", "one", "", "", mock.Anything).Return(nil).Once() typedDriver.On("CreateObject", "bucket", "one", "", "", mock.Anything).Return(nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "one", "").Return(oneMetadata, nil).Once()
request, err := http.NewRequest("PUT", testServer.URL+"/bucket/one", bytes.NewBufferString("hello world")) request, err := http.NewRequest("PUT", testServer.URL+"/bucket/one", bytes.NewBufferString("hello world"))
delete(request.Header, "Content-Type") delete(request.Header, "Content-Type")
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -905,15 +929,6 @@ func (s *MySuite) TestContentTypePersists(c *C) {
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
// test head
oneMetadata := drivers.ObjectMetadata{
Bucket: "bucket",
Key: "one",
ContentType: "application/octet-stream",
Created: time.Now(),
Md5: "d41d8cd98f00b204e9800998ecf8427e",
Size: 0,
}
typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Once() typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "one", "").Return(oneMetadata, nil).Once() typedDriver.On("GetObjectMetadata", "bucket", "one", "").Return(oneMetadata, nil).Once()
request, err = http.NewRequest("HEAD", testServer.URL+"/bucket/one", nil) request, err = http.NewRequest("HEAD", testServer.URL+"/bucket/one", nil)
@ -939,8 +954,19 @@ func (s *MySuite) TestContentTypePersists(c *C) {
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
c.Assert(response.Header.Get("Content-Type"), Equals, "application/octet-stream") c.Assert(response.Header.Get("Content-Type"), Equals, "application/octet-stream")
twoMetadata := drivers.ObjectMetadata{
Bucket: "bucket",
Key: "one",
ContentType: "application/octet-stream",
Created: time.Now(),
// Fix MD5
Md5: "d41d8cd98f00b204e9800998ecf8427e",
Size: 0,
}
typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once() typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once()
typedDriver.On("CreateObject", "bucket", "two", "", "", mock.Anything).Return(nil).Once() typedDriver.On("CreateObject", "bucket", "two", "", "", mock.Anything).Return(nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "two", "").Return(twoMetadata, nil).Once()
request, err = http.NewRequest("PUT", testServer.URL+"/bucket/two", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testServer.URL+"/bucket/two", bytes.NewBufferString("hello world"))
delete(request.Header, "Content-Type") delete(request.Header, "Content-Type")
request.Header.Add("Content-Type", "application/json") request.Header.Add("Content-Type", "application/json")
@ -951,15 +977,6 @@ func (s *MySuite) TestContentTypePersists(c *C) {
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
twoMetadata := drivers.ObjectMetadata{
Bucket: "bucket",
Key: "one",
ContentType: "application/octet-stream",
Created: time.Now(),
// Fix MD5
Md5: "d41d8cd98f00b204e9800998ecf8427e",
Size: 0,
}
typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once() typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "two", "").Return(twoMetadata, nil).Once() typedDriver.On("GetObjectMetadata", "bucket", "two", "").Return(twoMetadata, nil).Once()
request, err = http.NewRequest("HEAD", testServer.URL+"/bucket/two", nil) request, err = http.NewRequest("HEAD", testServer.URL+"/bucket/two", nil)
@ -1008,10 +1025,12 @@ func (s *MySuite) TestPartialContent(c *C) {
typedDriver.On("CreateBucket", "foo", "private").Return(nil).Once() typedDriver.On("CreateBucket", "foo", "private").Return(nil).Once()
typedDriver.On("CreateObject", "foo", "bar", "", "", mock.Anything).Return(nil).Once() typedDriver.On("CreateObject", "foo", "bar", "", "", mock.Anything).Return(nil).Once()
typedDriver.On("GetObjectMetadata", "foo", "bar", "").Return(metadata, nil).Once()
err := driver.CreateBucket("foo", "private") err := driver.CreateBucket("foo", "private")
c.Assert(err, IsNil) c.Assert(err, IsNil)
driver.CreateObject("foo", "bar", "", "", bytes.NewBufferString("hello world")) driver.CreateObject("foo", "bar", "", "", bytes.NewBufferString("hello world"))
driver.GetObjectMetadata("foo", "bar", "")
// prepare for GET on range request // prepare for GET on range request
typedDriver.SetGetObjectWriter("foo", "bar", []byte("hello world")) typedDriver.SetGetObjectWriter("foo", "bar", []byte("hello world"))

@ -40,6 +40,8 @@ func setCommonHeaders(w http.ResponseWriter, acceptsType string) {
w.Header().Set("Accept-Ranges", "bytes") w.Header().Set("Accept-Ranges", "bytes")
w.Header().Set("Content-Type", acceptsType) w.Header().Set("Content-Type", acceptsType)
w.Header().Set("Connection", "close") w.Header().Set("Connection", "close")
// should be set to '0' by default
w.Header().Set("Content-Length", "0")
} }
// Write error response headers // Write error response headers

Loading…
Cancel
Save