2. added custom 404 handler 3. added video page with template video.htmlmaster
| @@ -0,0 +1,10 @@ | |||
| #/bin/bash | |||
| rm -rf /tmp/goweb | |||
| mkdir -p /tmp/goweb | |||
| cp -a . /tmp/goweb/ | |||
| rm -rf /tmp/goweb/html/* | |||
| rsync -avh /mnt/hgfs/workspace/2021-07-31-BiukopWeb/ /tmp/goweb/html/ | |||
| cd /tmp/goweb | |||
| gcloud app deploy | |||
| @@ -0,0 +1 @@ | |||
| custom 404 | |||
| @@ -65,6 +65,10 @@ | |||
| </script> | |||
| </ol> | |||
| <p id="socketOutPut"></p> | |||
| <p> </p><a href="video.html"> Vimeo Video re branding </a> </p> | |||
| <p> </p><a href="404.html"> 404 test </a> </p> | |||
| </div> | |||
| <!--<script type="text/javascript">--> | |||
| @@ -0,0 +1,12 @@ | |||
| <html> | |||
| <title> Video For you </title> | |||
| <body style="margin:0px"> | |||
| <style> iframe {width: 100vw; height: 100vh; overflow:hidden;} </style> | |||
| <iframe src="https://player.vimeo.com/video/583797556?autoplay=1&loop=1&autopause=0&background=1&muted=1" | |||
| scrolling="no" frameborder="0" | |||
| style="width: 100vw; height: 100vh; overflow:hidden;" | |||
| allow="autoplay; fullscreen" | |||
| webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe> | |||
| </body> | |||
| </html> | |||
| @@ -3,6 +3,9 @@ package main | |||
| import ( | |||
| "log" | |||
| "net/http" | |||
| "os" | |||
| "path" | |||
| "strings" | |||
| ) | |||
| type httpEntry func(http.ResponseWriter, *http.Request) | |||
| @@ -10,6 +13,7 @@ type httpEntry func(http.ResponseWriter, *http.Request) | |||
| var httpEntryMap = map[string]httpEntry{ | |||
| apiV1Prefix: apiV1Main, | |||
| apiV1WebSocket: apiV1WebSocketHandler, | |||
| videoPrefix: videoMain, | |||
| } | |||
| func setupHTTPHandler() { | |||
| @@ -22,3 +26,64 @@ func setupHTTPHandler() { | |||
| log.Fatal(http.ListenAndServe(config.Host+":"+config.Port, nil)) | |||
| //log.Fatal(http.ListenAndServeTLS(config.Host+":"+config.Port, config.TlsCert, config.TlsKey, nil)) | |||
| } | |||
| // FSHandler404 provides the function signature for passing to the FileServerWith404 | |||
| type FSHandler404 = func(w http.ResponseWriter, r *http.Request) (doDefaultFileServe bool) | |||
| /* | |||
| FileServerWith404 wraps the http.FileServer checking to see if the url path exists first. | |||
| If the file fails to exist it calls the supplied FSHandle404 function | |||
| The implementation can choose to either modify the request, e.g. change the URL path and return true to have the | |||
| default FileServer handling to still take place, or return false to stop further processing, for example if you wanted | |||
| to write a custom response | |||
| e.g. redirects to root and continues the file serving handler chain | |||
| func fileSystem404(w http.ResponseWriter, r *http.Request) (doDefaultFileServe bool) { | |||
| //if not found redirect to / | |||
| r.URL.Path = "/" | |||
| return true | |||
| } | |||
| Use the same as you would with a http.FileServer e.g. | |||
| r.Handle("/", http.StripPrefix("/", mw.FileServerWith404(http.Dir("./staticDir"), fileSystem404))) | |||
| */ | |||
| func FileServerWith404(root http.FileSystem, handler404 FSHandler404) http.Handler { | |||
| fs := http.FileServer(root) | |||
| return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |||
| //make sure the url path starts with / | |||
| upath := r.URL.Path | |||
| if !strings.HasPrefix(upath, "/") { | |||
| upath = "/" + upath | |||
| r.URL.Path = upath | |||
| } | |||
| upath = path.Clean(upath) | |||
| // attempt to open the file via the http.FileSystem | |||
| f, err := root.Open(upath) | |||
| if err != nil { | |||
| if os.IsNotExist(err) { | |||
| // call handler | |||
| if handler404 != nil { | |||
| doDefault := handler404(w, r) | |||
| if !doDefault { | |||
| return | |||
| } | |||
| } | |||
| } | |||
| } | |||
| // close if successfully opened | |||
| if err == nil { | |||
| f.Close() | |||
| } | |||
| // default serve | |||
| fs.ServeHTTP(w, r) | |||
| }) | |||
| } | |||
| func fileSystem404(w http.ResponseWriter, r *http.Request) (doDefaultFileServe bool) { | |||
| //if not found redirect to / | |||
| r.URL.Path = "/404.html" | |||
| return true | |||
| } | |||
| @@ -0,0 +1,74 @@ | |||
| package main | |||
| import ( | |||
| "fmt" | |||
| "net/http" | |||
| ) | |||
| //display vimeo video in biukop brand | |||
| const videoPrefix = "/v/" | |||
| type vimeoPlayer struct { | |||
| VideoId string | |||
| playsinline int | |||
| autoplay int | |||
| autopause int | |||
| loop int | |||
| background int | |||
| muted int | |||
| Title string | |||
| } | |||
| func videoMain(w http.ResponseWriter, r *http.Request) { | |||
| videoVimeo(w, r) | |||
| } | |||
| func videoVimeo(w http.ResponseWriter, r *http.Request) { | |||
| vimeo := getVimeoParams(r) | |||
| pattern := ` | |||
| <html> | |||
| <title> %s </title> | |||
| <body style="margin:0px"> | |||
| <style> iframe {width: 100vw; height: 100vh; overflow:hidden;} </style> | |||
| <iframe src="%s" | |||
| scrolling="no" frameborder="0" | |||
| style="width: 100vw; height: 100vh; overflow:hidden;" | |||
| allow="autoplay; fullscreen" | |||
| webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe> | |||
| </body> | |||
| </html>` | |||
| output := fmt.Sprintf(pattern, vimeo.Title, vimeo.getUrl()) | |||
| fmt.Fprintf(w, output) | |||
| } | |||
| func getVimeoParams(r *http.Request) (ret vimeoPlayer) { | |||
| prefix := videoPrefix + "v/" | |||
| ret.VideoId = r.URL.Path[len(prefix):] | |||
| ret.Title = "Video" | |||
| ret.autopause = 0 | |||
| ret.autoplay = 1 | |||
| ret.playsinline = 0 | |||
| ret.loop = 1 | |||
| ret.background = 0 | |||
| ret.muted = 0 | |||
| if r.URL.Path[:len(prefix)] == videoPrefix+"b/" { | |||
| ret.playsinline = 1 | |||
| ret.background = 1 | |||
| ret.muted = 1 // autoplay video must be muted. | |||
| } | |||
| return | |||
| } | |||
| func (m *vimeoPlayer) getUrl() (ret string) { | |||
| ret = fmt.Sprintf( | |||
| "https://player.vimeo.com/video/%s?playsinline=%d&autoplay=%d&autopause=%d&loop=%d&background=%d&muted=%d", | |||
| m.VideoId, m.playsinline, m.autoplay, m.autopause, m.loop, m.background, m.muted) | |||
| return | |||
| } | |||
| @@ -38,7 +38,7 @@ func setupRootFileServer() { | |||
| //root of doc | |||
| for idx, node := range config.Static { | |||
| log.Printf("setting up static %d with %+v\n", idx, node) | |||
| fs := http.FileServer(http.Dir(node.Dir)) | |||
| fs := FileServerWith404(http.Dir(node.Dir), fileSystem404) | |||
| http.Handle(node.StaticUrl, http.StripPrefix(node.StripPrefix, fs)) | |||
| } | |||
| } | |||