12 635ade7f 2024-04-10 o type cache struct {
13 635ade7f 2024-04-10 o post map[int]entry
14 635ade7f 2024-04-10 o community map[string]entry
18 635ade7f 2024-04-10 o type entry struct {
20 635ade7f 2024-04-10 o community Community
21 635ade7f 2024-04-10 o expiry time.Time
24 635ade7f 2024-04-10 o func (c *cache) store(p Post, com Community, dur time.Duration) {
26 635ade7f 2024-04-10 o defer c.mu.Unlock()
27 635ade7f 2024-04-10 o t := time.Now().Add(dur)
28 635ade7f 2024-04-10 o entry := entry{expiry: t}
29 635ade7f 2024-04-10 o if p.Name() != "" {
31 635ade7f 2024-04-10 o c.post[p.ID] = entry
33 635ade7f 2024-04-10 o if com.Name() != "" {
34 635ade7f 2024-04-10 o entry.community = com
35 635ade7f 2024-04-10 o c.community[com.Name()] = entry
39 635ade7f 2024-04-10 o func (c *cache) delete(p Post, com Community) {
41 635ade7f 2024-04-10 o defer c.mu.Unlock()
42 635ade7f 2024-04-10 o delete(c.post, p.ID)
43 635ade7f 2024-04-10 o delete(c.community, com.Name())
47 635ade7f 2024-04-10 o func parseMaxAge(s string) (time.Duration, error) {
48 635ade7f 2024-04-10 o var want string
49 635ade7f 2024-04-10 o elems := strings.Split(s, ",")
50 635ade7f 2024-04-10 o for i := range elems {
51 635ade7f 2024-04-10 o elems[i] = strings.TrimSpace(elems[i])
52 635ade7f 2024-04-10 o if strings.HasPrefix(elems[i], "max-age") {
53 635ade7f 2024-04-10 o want = elems[i]
56 635ade7f 2024-04-10 o _, num, found := strings.Cut(want, "=")
58 635ade7f 2024-04-10 o return 0, fmt.Errorf("missing = separator")
60 635ade7f 2024-04-10 o n, err := strconv.Atoi(num)
61 635ade7f 2024-04-10 o if err != nil {
62 635ade7f 2024-04-10 o return 0, fmt.Errorf("parse seconds: %w", err)
64 635ade7f 2024-04-10 o return time.Duration(n) * time.Second, nil
67 635ade7f 2024-04-10 o // Cache-Control: public, max-age=50
68 635ade7f 2024-04-10 o func extractMaxAge(header http.Header) string {
69 635ade7f 2024-04-10 o cc := header.Get("Cache-Control")
70 635ade7f 2024-04-10 o if !strings.Contains(cc, "max-age=") {