@@ -660,6 +660,56 @@ func (s *statusCodeLogger) WriteHeader(code int) {
660660 s .ResponseWriter .WriteHeader (code )
661661}
662662
663+ func (s * SouinBaseHandler ) backfillStorers (idx int , cachedKey string , rq * http.Request , response * http.Response ) {
664+ if idx == 0 {
665+ return
666+ }
667+
668+ storedDuration , err := time .ParseDuration (response .Header .Get (rfc .StoredTTLHeader ))
669+ if err != nil {
670+ return
671+ }
672+
673+ dateHeader , err := http .ParseTime (response .Header .Get ("Date" ))
674+ if err != nil {
675+ return
676+ }
677+
678+ now := time .Now ()
679+
680+ ma := storedDuration - now .Sub (dateHeader )
681+
682+ variedHeaders , _ := rfc .VariedHeaderAllCommaSepValues (response .Header )
683+ variedKey := cachedKey + rfc .GetVariedCacheKey (rq , variedHeaders )
684+
685+ if rq .Context ().Value (context .Hashed ).(bool ) {
686+ cachedKey = fmt .Sprint (xxhash .Sum64String (cachedKey ))
687+ variedKey = fmt .Sprint (xxhash .Sum64String (variedKey ))
688+ }
689+
690+ vhs := http.Header {}
691+ for _ , hname := range variedHeaders {
692+ hn := strings .Split (hname , ":" )
693+ vhs .Set (hn [0 ], rq .Header .Get (hn [0 ]))
694+ }
695+
696+ res , _ := httputil .DumpResponse (response , true )
697+
698+ for _ , currentStorer := range s .Storers [:idx ] {
699+ err = currentStorer .SetMultiLevel (
700+ cachedKey ,
701+ variedKey ,
702+ res ,
703+ vhs ,
704+ response .Header .Get ("Etag" ), ma ,
705+ variedKey ,
706+ )
707+ if err != nil {
708+ s .Configuration .GetLogger ().Errorf ("Error while backfilling the storer %s: %v" , currentStorer .Name (), err )
709+ }
710+ }
711+ }
712+
663713func (s * SouinBaseHandler ) ServeHTTP (rw http.ResponseWriter , rq * http.Request , next handlerFunc ) error {
664714 start := time .Now ()
665715 defer func (s time.Time ) {
@@ -749,6 +799,9 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n
749799 crw .headersSent = true
750800 crw .mutex .Unlock ()
751801 }(req , customWriter )
802+
803+ backfillIds := 0
804+
752805 s .Configuration .GetLogger ().Debugf ("Request cache-control %+v" , requestCc )
753806 if modeContext .Bypass_request || ! requestCc .NoCache {
754807 validator := rfc .ParseRequest (req )
@@ -766,11 +819,18 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n
766819 s .Configuration .GetLogger ().Debugf ("Found at least one valid response in the %s storage" , storerName )
767820 break
768821 }
822+
823+ backfillIds ++
769824 }
770825
771826 headerName , _ := s .SurrogateKeyStorer .GetSurrogateControl (customWriter .Header ())
772827 if fresh != nil && (! modeContext .Strict || rfc .ValidateCacheControl (fresh , requestCc )) {
828+ go func () {
829+ s .backfillStorers (backfillIds , cachedKey , req , fresh )
830+ }()
831+
773832 response := fresh
833+
774834 if validator .ResponseETag != "" && validator .Matched {
775835 rfc .SetCacheStatusHeader (response , storerName )
776836 for h , v := range response .Header {
0 commit comments