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