mirror of
https://github.com/minio/minio.git
synced 2025-01-25 21:53:16 -05:00
Handled possible short writes to httpResponseWriter (#1804)
* XL: Handled possible short writes to httpResponseWriter * Added tests for Range Header combinations
This commit is contained in:
parent
b466f27705
commit
967c2b2940
@ -19,7 +19,7 @@ package main
|
|||||||
import "errors"
|
import "errors"
|
||||||
|
|
||||||
// ReadFile - decoded erasure coded file.
|
// ReadFile - decoded erasure coded file.
|
||||||
func (e erasure) ReadFile(volume, path string, bufferOffset int64, startOffset int64, buffer []byte) (int64, error) {
|
func (e erasure) ReadFile(volume, path string, startOffset int64, buffer []byte) (int64, error) {
|
||||||
// Calculate the current encoded block size.
|
// Calculate the current encoded block size.
|
||||||
curEncBlockSize := getEncodedBlockLen(int64(len(buffer)), e.DataBlocks)
|
curEncBlockSize := getEncodedBlockLen(int64(len(buffer)), e.DataBlocks)
|
||||||
offsetEncOffset := getEncodedBlockLen(startOffset, e.DataBlocks)
|
offsetEncOffset := getEncodedBlockLen(startOffset, e.DataBlocks)
|
||||||
@ -89,7 +89,7 @@ func (e erasure) ReadFile(volume, path string, bufferOffset int64, startOffset i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy data blocks.
|
// Copy data blocks.
|
||||||
copy(buffer, dataBlocks[bufferOffset:])
|
copy(buffer, dataBlocks)
|
||||||
|
|
||||||
// Relenquish memory.
|
// Relenquish memory.
|
||||||
dataBlocks = nil
|
dataBlocks = nil
|
||||||
|
@ -920,9 +920,18 @@ func (s *MyAPIXLSuite) TestPartialContent(c *C) {
|
|||||||
c.Assert(response.StatusCode, Equals, http.StatusOK)
|
c.Assert(response.StatusCode, Equals, http.StatusOK)
|
||||||
|
|
||||||
// Prepare request
|
// Prepare request
|
||||||
|
var table = []struct {
|
||||||
|
byteRange string
|
||||||
|
expectedString string
|
||||||
|
}{
|
||||||
|
{"6-7", "Wo"},
|
||||||
|
{"6-", "World"},
|
||||||
|
{"-7", "o World"},
|
||||||
|
}
|
||||||
|
for _, t := range table {
|
||||||
request, err = s.newRequest("GET", testAPIXLServer.URL+"/partial-content/bar", 0, nil)
|
request, err = s.newRequest("GET", testAPIXLServer.URL+"/partial-content/bar", 0, nil)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
request.Header.Add("Range", "bytes=6-7")
|
request.Header.Add("Range", "bytes="+t.byteRange)
|
||||||
|
|
||||||
client = http.Client{}
|
client = http.Client{}
|
||||||
response, err = client.Do(request)
|
response, err = client.Do(request)
|
||||||
@ -930,8 +939,8 @@ func (s *MyAPIXLSuite) TestPartialContent(c *C) {
|
|||||||
c.Assert(response.StatusCode, Equals, http.StatusPartialContent)
|
c.Assert(response.StatusCode, Equals, http.StatusPartialContent)
|
||||||
partialObject, err := ioutil.ReadAll(response.Body)
|
partialObject, err := ioutil.ReadAll(response.Body)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
|
c.Assert(string(partialObject), Equals, t.expectedString)
|
||||||
c.Assert(string(partialObject), Equals, "Wo")
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MyAPIXLSuite) TestListObjectsHandlerErrors(c *C) {
|
func (s *MyAPIXLSuite) TestListObjectsHandlerErrors(c *C) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"io"
|
"io"
|
||||||
@ -63,27 +64,27 @@ func (xl xlObjects) GetObject(bucket, object string, startOffset int64, length i
|
|||||||
}
|
}
|
||||||
var buffer = make([]byte, curBlockSize)
|
var buffer = make([]byte, curBlockSize)
|
||||||
var n int64
|
var n int64
|
||||||
n, err = erasure.ReadFile(bucket, pathJoin(object, part.Name), partOffset, beginOffset, buffer)
|
n, err = erasure.ReadFile(bucket, pathJoin(object, part.Name), beginOffset, buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if length > int64(len(buffer)) {
|
if length > int64(len(buffer)) {
|
||||||
var m int
|
var m int64
|
||||||
m, err = writer.Write(buffer)
|
m, err = io.Copy(writer, bytes.NewReader(buffer[partOffset:]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
length -= int64(m)
|
length -= m
|
||||||
} else {
|
} else {
|
||||||
_, err = writer.Write(buffer[:length])
|
_, err = io.CopyN(writer, bytes.NewReader(buffer[partOffset:]), length)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
totalLeft -= partOffset + n
|
totalLeft -= n
|
||||||
beginOffset += n
|
beginOffset += n
|
||||||
// Reset part offset to 0 to read rest of the parts from the beginning.
|
// Reset part offset to 0 to read rest of the part from the beginning.
|
||||||
partOffset = 0
|
partOffset = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user