examples.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. // HTTP server that demonstrates Pion WebRTC examples
  4. package main
  5. import (
  6. "encoding/json"
  7. "flag"
  8. "go/build"
  9. "html/template"
  10. "log"
  11. "net/http"
  12. "os"
  13. "path/filepath"
  14. "strings"
  15. )
  16. // Examples represents the examples loaded from examples.json.
  17. type Examples []*Example
  18. // Example represents an example loaded from examples.json.
  19. type Example struct {
  20. Title string `json:"title"`
  21. Link string `json:"link"`
  22. Description string `json:"description"`
  23. Type string `json:"type"`
  24. IsJS bool
  25. IsWASM bool
  26. }
  27. func main() {
  28. addr := flag.String("address", ":80", "Address to host the HTTP server on.")
  29. flag.Parse()
  30. log.Println("Listening on", *addr)
  31. err := serve(*addr)
  32. if err != nil {
  33. log.Fatalf("Failed to serve: %v", err)
  34. }
  35. }
  36. func serve(addr string) error {
  37. // Load the examples
  38. examples := getExamples()
  39. // Load the templates
  40. homeTemplate := template.Must(template.ParseFiles("index.html"))
  41. // Serve the required pages
  42. // DIY 'mux' to avoid additional dependencies
  43. http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  44. url := r.URL.Path
  45. if url == "/wasm_exec.js" {
  46. http.FileServer(http.Dir(filepath.Join(build.Default.GOROOT, "misc/wasm/"))).ServeHTTP(w, r)
  47. return
  48. }
  49. // Split up the URL. Expected parts:
  50. // 1: Base url
  51. // 2: "example"
  52. // 3: Example type: js or wasm
  53. // 4: Example folder, e.g.: data-channels
  54. // 5: Static file as part of the example
  55. parts := strings.Split(url, "/")
  56. if len(parts) > 4 &&
  57. parts[1] == "example" {
  58. exampleType := parts[2]
  59. exampleLink := parts[3]
  60. for _, example := range *examples {
  61. if example.Link != exampleLink {
  62. continue
  63. }
  64. fiddle := filepath.Join(exampleLink, "jsfiddle")
  65. if len(parts[4]) != 0 {
  66. http.StripPrefix("/example/"+exampleType+"/"+exampleLink+"/", http.FileServer(http.Dir(fiddle))).ServeHTTP(w, r)
  67. return
  68. }
  69. temp := template.Must(template.ParseFiles("example.html"))
  70. _, err := temp.ParseFiles(filepath.Join(fiddle, "demo.html"))
  71. if err != nil {
  72. panic(err)
  73. }
  74. data := struct {
  75. *Example
  76. JS bool
  77. }{
  78. example,
  79. exampleType == "js",
  80. }
  81. err = temp.Execute(w, data)
  82. if err != nil {
  83. panic(err)
  84. }
  85. return
  86. }
  87. }
  88. // Serve the main page
  89. err := homeTemplate.Execute(w, examples)
  90. if err != nil {
  91. panic(err)
  92. }
  93. })
  94. // Start the server
  95. // nolint: gosec
  96. return http.ListenAndServe(addr, nil)
  97. }
  98. // getExamples loads the examples from the examples.json file.
  99. func getExamples() *Examples {
  100. file, err := os.Open("./examples.json")
  101. if err != nil {
  102. panic(err)
  103. }
  104. defer func() {
  105. closeErr := file.Close()
  106. if closeErr != nil {
  107. panic(closeErr)
  108. }
  109. }()
  110. var examples Examples
  111. err = json.NewDecoder(file).Decode(&examples)
  112. if err != nil {
  113. panic(err)
  114. }
  115. for _, example := range examples {
  116. fiddle := filepath.Join(example.Link, "jsfiddle")
  117. js := filepath.Join(fiddle, "demo.js")
  118. if _, err := os.Stat(js); !os.IsNotExist(err) {
  119. example.IsJS = true
  120. }
  121. wasm := filepath.Join(fiddle, "demo.wasm")
  122. if _, err := os.Stat(wasm); !os.IsNotExist(err) {
  123. example.IsWASM = true
  124. }
  125. }
  126. return &examples
  127. }