You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sitemap.go 1.9KB

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