package main import ( "bytes" "crypto/sha256" "embed" "fmt" "net/http" ) const legalPageStyle = ` ` //go:embed legal/*.html var legalDocumentFiles embed.FS type legalDocument struct { body []byte etag string } var legalDocuments = map[string]legalDocument{ "/legal/user-terms": loadLegalDocument("legal/user-terms.html", "笔墨讯使软件服务协议"), "/legal/privacy-policy": loadLegalDocument("legal/privacy-policy.html", "笔墨讯使隐私政策"), } func loadLegalDocument(name, title string) legalDocument { body, err := legalDocumentFiles.ReadFile(name) if err != nil { panic("load legal document: " + err.Error()) } body = bytes.Replace(body, []byte(""), []byte(""), 1) body = bytes.Replace(body, []byte(""), []byte(""+title+""), 1) body = bytes.Replace(body, []byte(""), []byte(legalPageStyle+""), 1) body = bytes.Replace(body, []byte(""), []byte("

"+title+"

"), 1) body = bytes.Replace(body, []byte(""), []byte("
"), 1) digest := sha256.Sum256(body) return legalDocument{body: body, etag: fmt.Sprintf("\"%x\"", digest[:16])} } func serveLegalDocument(wrt http.ResponseWriter, req *http.Request) { if req.Method != http.MethodGet && req.Method != http.MethodHead { wrt.Header().Set("Allow", "GET, HEAD") http.Error(wrt, "method not allowed", http.StatusMethodNotAllowed) return } document, ok := legalDocuments[req.URL.Path] if !ok { http.NotFound(wrt, req) return } wrt.Header().Set("Content-Type", "text/html; charset=utf-8") wrt.Header().Set("Cache-Control", "public, max-age=300, must-revalidate") wrt.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; img-src data:; base-uri 'none'; form-action 'none'") wrt.Header().Set("Referrer-Policy", "no-referrer") wrt.Header().Set("X-Content-Type-Options", "nosniff") wrt.Header().Set("ETag", document.etag) if req.Header.Get("If-None-Match") == document.etag { wrt.WriteHeader(http.StatusNotModified) return } if req.Method == http.MethodHead { wrt.Header().Set("Content-Length", fmt.Sprintf("%d", len(document.body))) return } _, _ = wrt.Write(document.body) }