plugin: cache http responses from devices that omit the Date header (#31675)
This commit is contained in:
parent
c136038dfb
commit
df437d536f
2 changed files with 45 additions and 0 deletions
|
|
@ -115,6 +115,11 @@ func NewHTTP(log *util.Logger, method, uri string, insecure bool, cache time.Dur
|
|||
Modifier: func(resp *http.Response) error {
|
||||
dropCacheBusting(resp, "Cache-Control")
|
||||
dropCacheBusting(resp, "Pragma")
|
||||
// httpcache derives freshness from the response Date; stamp one
|
||||
// for devices that omit it, else every read is treated as stale
|
||||
if resp.Header.Get("Date") == "" {
|
||||
resp.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Base: base,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
|
@ -16,11 +17,26 @@ type httpHandler struct {
|
|||
req *http.Request
|
||||
cnt int
|
||||
cacheBusting bool
|
||||
noDate bool
|
||||
}
|
||||
|
||||
func (h *httpHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
h.req = req
|
||||
h.val = lo.RandomString(16, lo.LettersCharset)
|
||||
|
||||
// emulate a device that omits the Date header (e.g. Zendure Solarflow)
|
||||
if h.noDate {
|
||||
conn, buf, err := w.(http.Hijacker).Hijack()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer conn.Close()
|
||||
fmt.Fprintf(buf, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s", len(h.val), h.val)
|
||||
buf.Flush()
|
||||
h.cnt++
|
||||
return
|
||||
}
|
||||
|
||||
if h.cacheBusting {
|
||||
w.Header().Set("Cache-Control", "no-store, no-cache, max-age=0, must-revalidate")
|
||||
w.Header().Set("Pragma", "no-cache")
|
||||
|
|
@ -101,6 +117,30 @@ func (suite *httpTestSuite) TestCacheGetNoStore() {
|
|||
}
|
||||
}
|
||||
|
||||
func (suite *httpTestSuite) TestCacheGetNoDate() {
|
||||
// upstream omits the Date header, cache must still take effect via injected Date
|
||||
suite.h.noDate = true
|
||||
defer func() { suite.h.noDate = false }()
|
||||
|
||||
uri := suite.srv.URL + "/foo/bar?baz=3"
|
||||
p := NewHTTP(util.NewLogger("foo"), http.MethodGet, uri, false, time.Minute)
|
||||
|
||||
g, err := p.StringGetter()
|
||||
suite.Require().NoError(err)
|
||||
|
||||
suite.h.cnt = 0
|
||||
res, err := g()
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().Equal(1, suite.h.cnt)
|
||||
|
||||
for range 3 {
|
||||
val, err := g()
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().Equal(res, val)
|
||||
suite.Require().Equal(1, suite.h.cnt)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *httpTestSuite) TestSetQuery() {
|
||||
uri := suite.srv.URL + "/foo/bar?baz={{.baz}}"
|
||||
p := NewHTTP(util.NewLogger("foo"), http.MethodGet, uri, false, 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue