Browse Source

Issue 27: feature request - Last-Modified header

pull/2/head
Chris Lu 12 years ago
parent
commit
cbd9d14cc4
  1. 18
      go/storage/needle.go
  2. 28
      go/storage/needle_read_write.go
  3. 15
      go/weed/volume.go
  4. 11
      go/weed/volume_test.go

18
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)

28
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
}

15
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") {

11
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))
}
Loading…
Cancel
Save