aboutsummaryrefslogtreecommitdiff
path: root/go
diff options
context:
space:
mode:
Diffstat (limited to 'go')
-rw-r--r--go/storage/needle.go18
-rw-r--r--go/storage/needle_read_write.go28
-rw-r--r--go/weed/volume.go15
-rw-r--r--go/weed/volume_test.go11
4 files changed, 58 insertions, 14 deletions
diff --git a/go/storage/needle.go b/go/storage/needle.go
index 256a7c26a..9c0acc6b9 100644
--- a/go/storage/needle.go
+++ b/go/storage/needle.go
@@ -11,6 +11,7 @@ import (
"path"
"strconv"
"strings"
+ "time"
)
const (
@@ -24,13 +25,14 @@ type Needle struct {
Id uint64 `comment:"needle id"`
Size uint32 `comment:"sum of DataSize,Data,NameSize,Name,MimeSize,Mime"`
- DataSize uint32 `comment:"Data size"` //version2
- Data []byte `comment:"The actual file data"`
- Flags byte `comment:"boolean flags"` //version2
- NameSize uint8 //version2
- Name []byte `comment:"maximum 256 characters"` //version2
- MimeSize uint8 //version2
- Mime []byte `comment:"maximum 256 characters"` //version2
+ DataSize uint32 `comment:"Data size"` //version2
+ Data []byte `comment:"The actual file data"`
+ Flags byte `comment:"boolean flags"` //version2
+ NameSize uint8 //version2
+ Name []byte `comment:"maximum 256 characters"` //version2
+ MimeSize uint8 //version2
+ Mime []byte `comment:"maximum 256 characters"` //version2
+ LastModified uint64 //only store LastModifiedBytesLength bytes, which is 5 bytes to disk
Checksum CRC `comment:"CRC32 to check integrity"`
Padding []byte `comment:"Aligned to 8 bytes"`
@@ -88,6 +90,8 @@ func NewNeedle(r *http.Request) (n *Needle, e error) {
}
n.SetHasName()
}
+ n.LastModified = uint64(time.Now().Unix())
+ n.SetHasLastModifiedDate()
n.Data = data
n.Checksum = NewCRC(data)
diff --git a/go/storage/needle_read_write.go b/go/storage/needle_read_write.go
index c5f27ea21..bcb93f57b 100644
--- a/go/storage/needle_read_write.go
+++ b/go/storage/needle_read_write.go
@@ -9,9 +9,11 @@ import (
)
const (
- FlagGzip = 0x01
- FlagHasName = 0x02
- FlagHasMime = 0x04
+ FlagGzip = 0x01
+ FlagHasName = 0x02
+ FlagHasMime = 0x04
+ FlagHasLastModifiedDate = 0x08
+ LastModifiedBytesLength = 5
)
func (n *Needle) DiskSize() uint32 {
@@ -64,6 +66,9 @@ func (n *Needle) Append(w io.Writer, version Version) (size uint32, err error) {
if n.HasMime() {
n.Size = n.Size + 1 + uint32(n.MimeSize)
}
+ if n.HasLastModifiedDate() {
+ n.Size = n.Size + LastModifiedBytesLength
+ }
}
size = n.DataSize
util.Uint32toBytes(header[12:16], n.Size)
@@ -101,6 +106,12 @@ func (n *Needle) Append(w io.Writer, version Version) (size uint32, err error) {
return
}
}
+ if n.HasLastModifiedDate() {
+ util.Uint64toBytes(header[0:8], n.LastModified)
+ if _, err = w.Write(header[8-LastModifiedBytesLength : 8]); err != nil {
+ return
+ }
+ }
padding := NeedlePaddingSize - ((NeedleHeaderSize + n.Size + NeedleChecksumSize) % NeedlePaddingSize)
util.Uint32toBytes(header[0:NeedleChecksumSize], n.Checksum.Value())
_, err = w.Write(header[0 : NeedleChecksumSize+padding])
@@ -172,6 +183,11 @@ func (n *Needle) readNeedleDataVersion2(bytes []byte) {
n.MimeSize = uint8(bytes[index])
index = index + 1
n.Mime = bytes[index : index+int(n.MimeSize)]
+ index = index + int(n.MimeSize)
+ }
+ if index < lenBytes && n.HasLastModifiedDate() {
+ n.LastModified = util.BytesToUint64(bytes[index : index+LastModifiedBytesLength])
+ index = index + LastModifiedBytesLength
}
}
@@ -236,3 +252,9 @@ func (n *Needle) HasMime() bool {
func (n *Needle) SetHasMime() {
n.Flags = n.Flags | FlagHasMime
}
+func (n *Needle) HasLastModifiedDate() bool {
+ return n.Flags&FlagHasLastModifiedDate > 0
+}
+func (n *Needle) SetHasLastModifiedDate() {
+ n.Flags = n.Flags | FlagHasLastModifiedDate
+}
diff --git a/go/weed/volume.go b/go/weed/volume.go
index 6282b0bc8..039212793 100644
--- a/go/weed/volume.go
+++ b/go/weed/volume.go
@@ -145,6 +145,17 @@ func GetOrHeadHandler(w http.ResponseWriter, r *http.Request, isGetMethod bool)
w.WriteHeader(http.StatusNotFound)
return
}
+ if n.LastModified != 0 {
+ w.Header().Set("Last-Modified", time.Unix(int64(n.LastModified), 0).UTC().Format(http.TimeFormat))
+ if r.Header.Get("If-Modified-Since") != "" {
+ if t, parseError := time.Parse(http.TimeFormat, r.Header.Get("If-Modified-Since")); parseError == nil {
+ if t.Unix() <= int64(n.LastModified) {
+ w.WriteHeader(http.StatusNotModified)
+ return
+ }
+ }
+ }
+ }
if n.NameSize > 0 {
fname := string(n.Name)
dotIndex := strings.LastIndex(fname, ".")
@@ -165,10 +176,6 @@ func GetOrHeadHandler(w http.ResponseWriter, r *http.Request, isGetMethod bool)
if n.NameSize > 0 {
w.Header().Set("Content-Disposition", "filename="+fileNameEscaper.Replace(string(n.Name)))
}
- if n.LastModified != 0 {
- println("file time is", n.LastModified)
- w.Header().Set("Last-Modified", time.Unix(int64(n.LastModified), 0).Format(http.TimeFormat))
- }
if ext != ".gz" {
if n.IsGzipped() {
if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
diff --git a/go/weed/volume_test.go b/go/weed/volume_test.go
new file mode 100644
index 000000000..09340910b
--- /dev/null
+++ b/go/weed/volume_test.go
@@ -0,0 +1,11 @@
+package main
+
+import (
+ "net/http"
+ "testing"
+ "time"
+)
+
+func TestXYZ(t *testing.T) {
+ println("Last-Modified", time.Unix(int64(1373273596), 0).UTC().Format(http.TimeFormat))
+}