2. added custom 404 handler 3. added video page with template video.htmlmaster
| #/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 |
| custom 404 |
| </script> | </script> | ||||
| </ol> | </ol> | ||||
| <p id="socketOutPut"></p> | <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> | </div> | ||||
| <!--<script type="text/javascript">--> | <!--<script type="text/javascript">--> |
| <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> |
| import ( | import ( | ||||
| "log" | "log" | ||||
| "net/http" | "net/http" | ||||
| "os" | |||||
| "path" | |||||
| "strings" | |||||
| ) | ) | ||||
| type httpEntry func(http.ResponseWriter, *http.Request) | type httpEntry func(http.ResponseWriter, *http.Request) | ||||
| var httpEntryMap = map[string]httpEntry{ | var httpEntryMap = map[string]httpEntry{ | ||||
| apiV1Prefix: apiV1Main, | apiV1Prefix: apiV1Main, | ||||
| apiV1WebSocket: apiV1WebSocketHandler, | apiV1WebSocket: apiV1WebSocketHandler, | ||||
| videoPrefix: videoMain, | |||||
| } | } | ||||
| func setupHTTPHandler() { | func setupHTTPHandler() { | ||||
| log.Fatal(http.ListenAndServe(config.Host+":"+config.Port, nil)) | log.Fatal(http.ListenAndServe(config.Host+":"+config.Port, nil)) | ||||
| //log.Fatal(http.ListenAndServeTLS(config.Host+":"+config.Port, config.TlsCert, config.TlsKey, 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 | |||||
| } |
| 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 | |||||
| } |
| //root of doc | //root of doc | ||||
| for idx, node := range config.Static { | for idx, node := range config.Static { | ||||
| log.Printf("setting up static %d with %+v\n", idx, node) | 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)) | http.Handle(node.StaticUrl, http.StripPrefix(node.StripPrefix, fs)) | ||||
| } | } | ||||
| } | } |