@@ -36,10 +36,13 @@ import (
3636 "log"
3737 "net/http"
3838 _ "net/http/pprof"
39+ "net/url"
3940 "os"
4041 "path"
42+ "path/filepath"
4143 goruntime "runtime"
4244 "strconv"
45+ "strings"
4346 "syscall"
4447 "time"
4548)
@@ -75,6 +78,20 @@ func roomHandler(w http.ResponseWriter, r *http.Request) {
7578
7679}
7780
81+ func sandboxHandler (w http.ResponseWriter , r * http.Request ) {
82+
83+ vars := mux .Vars (r )
84+ // NOTE(longsleep): origin_scheme is window.location.protocol (eg. https:, http:).
85+ originURL , err := url .Parse (fmt .Sprintf ("%s//%s" , vars ["origin_scheme" ], vars ["origin_host" ]))
86+ if err != nil || originURL .Scheme == "" || originURL .Host == "" {
87+ http .Error (w , "Invalid origin path" , http .StatusBadRequest )
88+ return
89+ }
90+ origin := fmt .Sprintf ("%s://%s" , originURL .Scheme , originURL .Host )
91+ handleSandboxView (vars ["sandbox" ], origin , w , r )
92+
93+ }
94+
7895func makeImageHandler (buddyImages ImageCache , expires time.Duration ) http.HandlerFunc {
7996
8097 return func (w http.ResponseWriter , r * http.Request ) {
@@ -158,6 +175,42 @@ func handleRoomView(room string, w http.ResponseWriter, r *http.Request) {
158175
159176}
160177
178+ func handleSandboxView (sandbox string , origin string , w http.ResponseWriter , r * http.Request ) {
179+
180+ w .Header ().Set ("Content-Type" , "text/html; charset=UTF-8" )
181+ w .Header ().Set ("Expires" , "-1" )
182+ w .Header ().Set ("Cache-Control" , "private, max-age=0" )
183+
184+ sandboxTemplateName := fmt .Sprintf ("%s_sandbox.html" , sandbox )
185+
186+ // Prepare context to deliver to HTML..
187+ if t := templates .Lookup (sandboxTemplateName ); t != nil {
188+
189+ // CSP support for sandboxes.
190+ var csp string
191+ switch sandbox {
192+ case "odfcanvas" :
193+ csp = fmt .Sprintf ("default-src 'none'; script-src %s; img-src data: blob:; style-src 'unsafe-inline'" , origin )
194+ case "pdfcanvas" :
195+ csp = fmt .Sprintf ("default-src 'none'; script-src %s 'unsafe-eval'; img-src 'self' data: blob:; style-src 'unsafe-inline'" , origin )
196+ default :
197+ csp = "default-src 'none'"
198+ }
199+ w .Header ().Set ("Content-Security-Policy" , csp )
200+
201+ // Prepare context to deliver to HTML..
202+ context := & Context {Cfg : config , Origin : origin , Csp : true }
203+ err := t .Execute (w , & context )
204+ if err != nil {
205+ http .Error (w , err .Error (), http .StatusInternalServerError )
206+ }
207+
208+ } else {
209+ http .Error (w , "404 Unknown Sandbox" , http .StatusNotFound )
210+ }
211+
212+ }
213+
161214func runner (runtime phoenix.Runtime ) error {
162215
163216 log .SetFlags (log .LstdFlags | log .Lmicroseconds )
@@ -257,10 +310,21 @@ func runner(runtime phoenix.Runtime) error {
257310 config = NewConfig (runtime , tokenProvider != nil )
258311
259312 // Load templates.
260- tt := template .New ("" )
261- tt .Delims ("<%" , "%>" )
262-
263- templates , err = tt .ParseGlob (path .Join (rootFolder , "html" , "*.html" ))
313+ templates = template .New ("" )
314+ templates .Delims ("<%" , "%>" )
315+
316+ // Load html templates folder
317+ err = filepath .Walk (path .Join (rootFolder , "html" ), func (path string , info os.FileInfo , err error ) error {
318+ if err == nil {
319+ if strings .HasSuffix (path , ".html" ) {
320+ _ , err = templates .ParseFiles (path )
321+ if err != nil {
322+ return err
323+ }
324+ }
325+ }
326+ return nil
327+ })
264328 if err != nil {
265329 return fmt .Errorf ("Failed to load templates: %s" , err )
266330 }
@@ -335,7 +399,7 @@ func runner(runtime phoenix.Runtime) error {
335399 runtime .DefaultHTTPSHandler (r )
336400 }
337401
338- // Add handlers .
402+ // Prepare services .
339403 buddyImages := NewImageCache ()
340404 codec := NewCodec (incomingCodecLimit )
341405 roomManager := NewRoomManager (config , codec )
@@ -344,6 +408,8 @@ func runner(runtime phoenix.Runtime) error {
344408 sessionManager := NewSessionManager (config , tickets , hub , roomManager , roomManager , buddyImages , sessionSecret )
345409 statsManager := NewStatsManager (hub , roomManager , sessionManager )
346410 channellingAPI := NewChannellingAPI (config , roomManager , tickets , sessionManager , statsManager , hub , hub , hub )
411+
412+ // Add handlers.
347413 r .HandleFunc ("/" , httputils .MakeGzipHandler (mainHandler ))
348414 r .Handle ("/static/img/buddy/{flags}/{imageid}/{idx:.*}" , http .StripPrefix (config .B , makeImageHandler (buddyImages , time .Duration (24 )* time .Hour )))
349415 r .Handle ("/static/{path:.*}" , http .StripPrefix (config .B , httputils .FileStaticServer (http .Dir (rootFolder ))))
@@ -354,6 +420,9 @@ func runner(runtime phoenix.Runtime) error {
354420 // Simple room handler.
355421 r .HandleFunc ("/{room}" , httputils .MakeGzipHandler (roomHandler ))
356422
423+ // Sandbox handler.
424+ r .HandleFunc ("/sandbox/{origin_scheme}/{origin_host}/{sandbox}.html" , httputils .MakeGzipHandler (sandboxHandler ))
425+
357426 // Add API end points.
358427 api := sloth .NewAPI ()
359428 api .SetMux (r .PathPrefix ("/api/v1/" ).Subrouter ())
0 commit comments