logo.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package controllers
  2. import (
  3. "net/http"
  4. "os"
  5. "path/filepath"
  6. "strconv"
  7. "github.com/owncast/owncast/config"
  8. "github.com/owncast/owncast/core/data"
  9. "github.com/owncast/owncast/static"
  10. "github.com/owncast/owncast/utils"
  11. log "github.com/sirupsen/logrus"
  12. )
  13. var _hasWarnedSVGLogo = false
  14. // GetLogo will return the logo image as a response.
  15. func GetLogo(w http.ResponseWriter, r *http.Request) {
  16. imageFilename := data.GetLogoPath()
  17. if imageFilename == "" {
  18. returnDefault(w)
  19. return
  20. }
  21. imagePath := filepath.Join(config.DataDirectory, imageFilename)
  22. imageBytes, err := getImage(imagePath)
  23. if err != nil {
  24. returnDefault(w)
  25. return
  26. }
  27. contentType := "image/jpeg"
  28. if filepath.Ext(imageFilename) == ".svg" {
  29. contentType = "image/svg+xml"
  30. } else if filepath.Ext(imageFilename) == ".gif" {
  31. contentType = "image/gif"
  32. } else if filepath.Ext(imageFilename) == ".png" {
  33. contentType = "image/png"
  34. }
  35. cacheTime := utils.GetCacheDurationSecondsForPath(imagePath)
  36. writeBytesAsImage(imageBytes, contentType, w, cacheTime)
  37. }
  38. // GetCompatibleLogo will return the logo unless it's a SVG
  39. // and in that case will return a default placeholder.
  40. // Used for sharing to external social networks that generally
  41. // don't support SVG.
  42. func GetCompatibleLogo(w http.ResponseWriter, r *http.Request) {
  43. imageFilename := data.GetLogoPath()
  44. // If the logo image is not a SVG then we can return it
  45. // without any problems.
  46. if imageFilename != "" && filepath.Ext(imageFilename) != ".svg" {
  47. GetLogo(w, r)
  48. return
  49. }
  50. // Otherwise use a fallback logo.png.
  51. imagePath := filepath.Join(config.DataDirectory, "logo.png")
  52. contentType := "image/png"
  53. imageBytes, err := getImage(imagePath)
  54. if err != nil {
  55. returnDefault(w)
  56. return
  57. }
  58. cacheTime := utils.GetCacheDurationSecondsForPath(imagePath)
  59. writeBytesAsImage(imageBytes, contentType, w, cacheTime)
  60. if !_hasWarnedSVGLogo {
  61. log.Warnf("an external site requested your logo. because many social networks do not support SVGs we returned a placeholder instead. change your current logo to a png or jpeg to be most compatible with external social networking sites.")
  62. _hasWarnedSVGLogo = true
  63. }
  64. }
  65. func returnDefault(w http.ResponseWriter) {
  66. imageBytes := static.GetLogo()
  67. cacheTime := utils.GetCacheDurationSecondsForPath("logo.png")
  68. writeBytesAsImage(imageBytes, "image/png", w, cacheTime)
  69. }
  70. func writeBytesAsImage(data []byte, contentType string, w http.ResponseWriter, cacheSeconds int) {
  71. w.Header().Set("Content-Type", contentType)
  72. w.Header().Set("Content-Length", strconv.Itoa(len(data)))
  73. w.Header().Set("Cache-Control", "public, max-age="+strconv.Itoa(cacheSeconds))
  74. if _, err := w.Write(data); err != nil {
  75. log.Println("unable to write image.")
  76. }
  77. }
  78. func getImage(path string) ([]byte, error) {
  79. return os.ReadFile(path) // nolint
  80. }