2017-10-31 5 views
2

Ich versuche, die Last-Modified -header von http.FileServer gesetzt außer Kraft zu setzen, aber es geht in die Last-Modified -Zeit der Datei zu dienen Ich versuche:Zwingende Last-Modified-Header in http.FileServer

var myTime time.Time 

func main() { 
    myTime = time.Now()   

    fs := http.StripPrefix("/folder/", SetCacheHeader(http.FileServer(http.Dir("/folder/")))) 
    http.Handle("/folder/", fs) 
    http.ListenAndServe(":80", nil) 
} 

Mein SetCacheHeader -Handler:

func SetCacheHeader(h http.Handler) http.Handler { 
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
     w.Header().Set("Last-Modified", myTime.Format(http.TimeFormat)) 
     h.ServeHTTP(w, r) 
    }) 
} 

Antwort

4

der Handler zurück von http.FileServer() bedingungslos setzt die "Last-Modified"-Header in dem http.serveFile() und http.serveContent() unexported func Anweisungen:

func serveFile(w ResponseWriter, r *Request, fs FileSystem, 
    name string, redirect bool) { 

    // ... 
    f, err := fs.Open(name) 
    // ... 
    d, err := f.Stat() 
    // ... 

    // serveContent will check modification time 
    sizeFunc := func() (int64, error) { return d.Size(), nil } 
    serveContent(w, r, d.Name(), d.ModTime(), sizeFunc, f) 
} 

func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time, 
    sizeFunc func() (int64, error), content io.ReadSeeker) { 
    setLastModified(w, modtime) 
    // ... 
} 


func setLastModified(w ResponseWriter, modtime time.Time) { 
    if !isZeroTime(modtime) { 
     w.Header().Set("Last-Modified", modtime.UTC().Format(TimeFormat)) 
    } 
} 

Also was Sie vor dem Aufruf der Dateiserver-Handler gesetzt haben, wird überschrieben. Du kannst nichts dagegen tun.

Wenn Sie den Inhalt einer Datei mit benutzerdefinierten letzten Änderung der Zeit dienen müssen, können Sie http.ServeContent() verwenden:

func ServeContent(w ResponseWriter, req *Request, name string, 
    modtime time.Time, content io.ReadSeeker) 

Wo Sie die zuletzt modifizierten Zeit verwendet werden passieren kann, aber dann natürlich Sie verlieren alle praktischen Funktionen von http.FileServer().

Wenn Sie behalten möchten http.FileServer() verwenden, wäre eine weitere Option, nicht den http.Dir Typ zu verwenden, aber Ihre eigene http.FileSystem Implementierung erstellen, die Sie http.FileServer() passieren, in dem Sie eine der letzten Änderung Zeitstempel berichten könnten Sie es wünschen.

Dies müssten Sie die folgende Schnittstelle implementieren:

type FileSystem interface { 
     Open(name string) (File, error) 
} 

So benötigen Sie eine Methode, die mit seinem Namen eine Datei öffnet, und einen Wert zurückgibt, die http.File implementiert, das ist:

type File interface { 
     io.Closer 
     io.Reader 
     io.Seeker 
     Readdir(count int) ([]os.FileInfo, error) 
     Stat() (os.FileInfo, error) 
} 

Und der Wert, den Sie zurückgeben (der http.File implementiert), könnte eine Methodenimplementierung haben, deren os.FileInfo Rückgabewert die zuletzt geänderte Zeit Ihrer Wahl enthält. Beachten Sie, dass Sie auch die Readdir()-Methode implementieren sollten, um benutzerdefinierte zuletzt geänderte Zeitstempel zurückzugeben, die mit den Zeitstempeln konsistent sind, die von Stat()s Dateiinfo zurückgegeben werden.