@@ -91,7 +91,36 @@ func main() {
9191 }
9292
9393 fmt .Printf ("Server started at http://localhost:%s\n " , port )
94- log .Fatal (http .ListenAndServe (":" + port , nil ))
94+
95+ mux := http .DefaultServeMux
96+
97+ // forceHTTPS redirects HTTP -> HTTPS for non-local requests using a 301.
98+ // We intentionally allow localhost/127.0.0.1 to remain on HTTP for local dev.
99+ forceHTTPS := func (next http.Handler ) http.Handler {
100+ return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
101+ if ! isHTTPS (r ) && ! strings .HasPrefix (r .Host , "localhost" ) && ! strings .HasPrefix (r .Host , "127.0.0.1" ) {
102+ url := "https://" + r .Host + r .URL .RequestURI ()
103+ http .Redirect (w , r , url , http .StatusMovedPermanently )
104+ return
105+ }
106+ next .ServeHTTP (w , r )
107+ })
108+ }
109+
110+ handler := forceHTTPS (mux )
111+
112+ log .Fatal (http .ListenAndServe (":" + port , handler ))
113+ }
114+
115+ func isHTTPS (r * http.Request ) bool {
116+ if r .TLS != nil {
117+ return true
118+ }
119+ proto := r .Header .Get ("X-Forwarded-Proto" )
120+ if strings .EqualFold (proto , "https" ) {
121+ return true
122+ }
123+ return false
95124}
96125
97126func loadData () {
@@ -263,10 +292,12 @@ func createDrawHandler(w http.ResponseWriter, r *http.Request) {
263292 t := loadTranslations (lang )
264293
265294 if r .Method == http .MethodGet {
295+ canonical := fmt .Sprintf ("https://%s%s" , r .Host , r .URL .Path )
266296 templates .ExecuteTemplate (w , "create_event.html" , struct {
267297 T Translations
268298 CurrentLang string
269- }{t , lang })
299+ Canonical string
300+ }{t , lang , canonical })
270301 return
271302 }
272303 r .ParseForm ()
@@ -380,12 +411,14 @@ func drawHandler(w http.ResponseWriter, r *http.Request) {
380411 return
381412 }
382413 if ! draw .DrawDone {
414+ canonical := fmt .Sprintf ("https://%s%s" , r .Host , r .URL .Path )
383415 templates .ExecuteTemplate (w , "participant.html" , struct {
384416 Name string
385417 Ready bool
386418 T Translations
387419 CurrentLang string
388- }{p .Name , false , t , lang })
420+ Canonical string
421+ }{p .Name , false , t , lang , canonical })
389422 } else {
390423 // Find the wish of the person they're giving a gift to
391424 recipientWish := ""
@@ -395,26 +428,30 @@ func drawHandler(w http.ResponseWriter, r *http.Request) {
395428 break
396429 }
397430 }
431+ canonical := fmt .Sprintf ("https://%s%s" , r .Host , r .URL .Path )
398432 templates .ExecuteTemplate (w , "participant.html" , struct {
399433 Name string
400434 Ready bool
401435 GiftFor string
402436 Wish string
403437 T Translations
404438 CurrentLang string
405- }{p .Name , true , p .GiftFor , recipientWish , t , lang })
439+ Canonical string
440+ }{p .Name , true , p .GiftFor , recipientWish , t , lang , canonical })
406441 }
407442 return
408443 }
409444
410445 switch action {
411446 case "join" :
412447 if r .Method == http .MethodGet {
448+ canonical := fmt .Sprintf ("https://%s%s" , r .Host , r .URL .Path )
413449 templates .ExecuteTemplate (w , "join.html" , struct {
414450 EventID string
415451 T Translations
416452 CurrentLang string
417- }{id , t , lang })
453+ Canonical string
454+ }{id , t , lang , canonical })
418455 return
419456 }
420457 r .ParseForm ()
@@ -473,14 +510,17 @@ func drawHandler(w http.ResponseWriter, r *http.Request) {
473510 }
474511 dataMutex .RUnlock ()
475512
476- joinLink := fmt .Sprintf ("http://%s/draw/%s/join" , r .Host , id )
513+ // Build canonical links using HTTPS
514+ scheme := "https"
515+ joinLink := fmt .Sprintf (scheme + "://%s/draw/%s/join" , r .Host , id )
477516 organizerToken := r .URL .Query ().Get ("organizer" )
478517 organizerLink := ""
479518 // Only show organizer link after draw is done
480519 if organizerToken != "" && draw .DrawDone {
481- organizerLink = fmt .Sprintf ("http ://%s/draw/%s/participant/%s" , r .Host , id , organizerToken )
520+ organizerLink = fmt .Sprintf (scheme + " ://%s/draw/%s/participant/%s" , r .Host , id , organizerToken )
482521 }
483522 canDraw := allSubmitted && ! draw .DrawDone && expectedReached
523+ canonical := fmt .Sprintf ("https://%s%s" , r .Host , r .URL .Path )
484524 templates .ExecuteTemplate (w , "manage.html" , struct {
485525 EventID string
486526 EventName string
@@ -492,7 +532,8 @@ func drawHandler(w http.ResponseWriter, r *http.Request) {
492532 DrawDone bool
493533 T Translations
494534 CurrentLang string
495- }{id , draw .Name , joinLink , organizerLink , organizerToken , draw .Participants , canDraw , draw .DrawDone , t , lang })
535+ Canonical string
536+ }{id , draw .Name , joinLink , organizerLink , organizerToken , draw .Participants , canDraw , draw .DrawDone , t , lang , canonical })
496537
497538 case "draw" :
498539 if r .Method != http .MethodPost {
0 commit comments