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