code.gitea.io/gitea@v1.19.3/modules/sitemap/sitemap.go (about) 1 // Copyright 2022 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package sitemap 5 6 import ( 7 "bytes" 8 "encoding/xml" 9 "fmt" 10 "io" 11 "time" 12 ) 13 14 const ( 15 sitemapFileLimit = 50 * 1024 * 1024 // the maximum size of a sitemap file 16 urlsLimit = 50000 17 18 schemaURL = "http://www.sitemaps.org/schemas/sitemap/0.9" 19 urlsetName = "urlset" 20 sitemapindexName = "sitemapindex" 21 ) 22 23 // URL represents a single sitemap entry 24 type URL struct { 25 URL string `xml:"loc"` 26 LastMod *time.Time `xml:"lastmod,omitempty"` 27 } 28 29 // Sitemap represents a sitemap 30 type Sitemap struct { 31 XMLName xml.Name 32 Namespace string `xml:"xmlns,attr"` 33 34 URLs []URL `xml:"url"` 35 Sitemaps []URL `xml:"sitemap"` 36 } 37 38 // NewSitemap creates a sitemap 39 func NewSitemap() *Sitemap { 40 return &Sitemap{ 41 XMLName: xml.Name{Local: urlsetName}, 42 Namespace: schemaURL, 43 } 44 } 45 46 // NewSitemapIndex creates a sitemap index. 47 func NewSitemapIndex() *Sitemap { 48 return &Sitemap{ 49 XMLName: xml.Name{Local: sitemapindexName}, 50 Namespace: schemaURL, 51 } 52 } 53 54 // Add adds a URL to the sitemap 55 func (s *Sitemap) Add(u URL) { 56 if s.XMLName.Local == sitemapindexName { 57 s.Sitemaps = append(s.Sitemaps, u) 58 } else { 59 s.URLs = append(s.URLs, u) 60 } 61 } 62 63 // WriteTo writes the sitemap to a response 64 func (s *Sitemap) WriteTo(w io.Writer) (int64, error) { 65 if l := len(s.URLs); l > urlsLimit { 66 return 0, fmt.Errorf("The sitemap contains %d URLs, but only %d are allowed", l, urlsLimit) 67 } 68 if l := len(s.Sitemaps); l > urlsLimit { 69 return 0, fmt.Errorf("The sitemap contains %d sub-sitemaps, but only %d are allowed", l, urlsLimit) 70 } 71 buf := bytes.NewBufferString(xml.Header) 72 if err := xml.NewEncoder(buf).Encode(s); err != nil { 73 return 0, err 74 } 75 if err := buf.WriteByte('\n'); err != nil { 76 return 0, err 77 } 78 if buf.Len() > sitemapFileLimit { 79 return 0, fmt.Errorf("The sitemap has %d bytes, but only %d are allowed", buf.Len(), sitemapFileLimit) 80 } 81 return buf.WriteTo(w) 82 }