Skip to content
Snippets Groups Projects
Commit 3d53bc53 authored by Dean's avatar Dean
Browse files

Merge branch 'feat/discord-video-embed' into 'master'

Add HTML response for Discord video embeds

See merge request !11
parents dd504b14 6cc18575
No related branches found
No related tags found
No related merge requests found
...@@ -60,8 +60,9 @@ var redirectHTMLTemplate *template.Template ...@@ -60,8 +60,9 @@ var redirectHTMLTemplate *template.Template
// redirectPreviewHTML is the html/template template for generating redirect preview HTML. // redirectPreviewHTML is the html/template template for generating redirect preview HTML.
const redirectPreviewHTML = `<html><head><meta charset="UTF-8" /><title>Redirect Preview</title></head><body><p>This link goes to <code>{{.}}</code>. If you would like to visit this link, click <a href="{{.}}">here</a> to go to the destination.</p></body></html>` const redirectPreviewHTML = `<html><head><meta charset="UTF-8" /><title>Redirect Preview</title></head><body><p>This link goes to <code>{{.}}</code>. If you would like to visit this link, click <a href="{{.}}">here</a> to go to the destination.</p></body></html>`
// discordHTML is the html/template template for generating Discord-fixing HTML. // discordImageHTML is the html/template template for generating Discord-fixing
const discordHTML = `<html> // HTML for images.
const discordImageHTML = `<html>
<head> <head>
<meta property="twitter:card" content="summary_large_image" /> <meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:image" content="{{.}}" /> <meta property="twitter:image" content="{{.}}" />
...@@ -71,10 +72,22 @@ const discordHTML = `<html> ...@@ -71,10 +72,22 @@ const discordHTML = `<html>
</head> </head>
</html>` </html>`
var discordHTMLTemplate *template.Template // discordVideoHTML is the html/template template for generating Discord-fixing
// HTML for videos.
const discordVideoHTML = `<html>
<head>
<meta property="og:type" content="video.other" />
<meta property="og:video:url" content="{{.}}" />
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
</head>
</html>`
var redirectPreviewHTMLTemplate *template.Template var redirectPreviewHTMLTemplate *template.Template
var discordMediaTypeToTemplate map[string]*template.Template
// printConfiguration iterates through a configuration map[string]interface{} // printConfiguration iterates through a configuration map[string]interface{}
// and prints out all of the values in alphabetical order. Configuration keys // and prints out all of the values in alphabetical order. Configuration keys
// are printed with dot notation. // are printed with dot notation.
...@@ -182,9 +195,30 @@ func init() { ...@@ -182,9 +195,30 @@ func init() {
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("failed to parse redirectPreviewHTML template") log.Fatal().Err(err).Msg("failed to parse redirectPreviewHTML template")
} }
discordHTMLTemplate, err = template.New("discordHTML").Parse(discordHTML)
// Parse Discord-fixing templates
discordImageHTMLTemplate, err := template.New("discordImageHTML").Parse(discordImageHTML)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("failed to parse discordHTML template") log.Fatal().Err(err).Msg("failed to parse discordImageHTML template")
}
discordVideoHTMLTemplate, err := template.New("discordVideoHTML").Parse(discordVideoHTML)
if err != nil {
log.Fatal().Err(err).Msg("failed to parse discordVideoHTML template")
}
discordMediaTypeToTemplate = map[string]*template.Template{
"image/jpeg": discordImageHTMLTemplate,
"image/png": discordImageHTMLTemplate,
"image/gif": discordImageHTMLTemplate,
"image/webp": discordImageHTMLTemplate,
// Official media type, registered in 2022
"image/apng": discordImageHTMLTemplate,
// Official-unofficial media type, still in use, registered in 2015
"image/vnd.mozilla.apng": discordImageHTMLTemplate,
// Currently unsupported by Discord, but no harm keeping it here
"image/avif": discordImageHTMLTemplate,
"video/mp4": discordVideoHTMLTemplate,
"video/webm": discordVideoHTMLTemplate,
"video/ogg": discordVideoHTMLTemplate,
} }
} }
...@@ -434,8 +468,10 @@ func requestHandler(ctx *fasthttp.RequestCtx) { ...@@ -434,8 +468,10 @@ func requestHandler(ctx *fasthttp.RequestCtx) {
return return
} }
// Discord workaround. They're hiding direct image embeds, so we // Discord workaround. Directly returning images results in the
// serve HTML pages with metadata showing the image. // URL being hidden, while directly returning multimedia
// containers reduces the chances of the media embedding at all
// (lower size constraints, fewer whitelisted codecs).
if object.ContentType != nil && discordBotRegex.Match(ctx.Request.Header.UserAgent()) && !ctx.QueryArgs().Has(rawParam) { if object.ContentType != nil && discordBotRegex.Match(ctx.Request.Header.UserAgent()) && !ctx.QueryArgs().Has(rawParam) {
typ, _, err := mime.ParseMediaType(*object.ContentType) typ, _, err := mime.ParseMediaType(*object.ContentType)
if err != nil { if err != nil {
...@@ -444,7 +480,8 @@ func requestHandler(ctx *fasthttp.RequestCtx) { ...@@ -444,7 +480,8 @@ func requestHandler(ctx *fasthttp.RequestCtx) {
return return
} }
if typ == "image/jpeg" || typ == "image/jpg" || typ == "image/png" || typ == "image/gif" { discordTemplate := discordMediaTypeToTemplate[typ]
if discordTemplate != nil {
var ( var (
host = string(ctx.Request.Header.Peek("Host")) host = string(ctx.Request.Header.Peek("Host"))
// Assume anything Discord hits is HTTPS // Assume anything Discord hits is HTTPS
...@@ -463,7 +500,7 @@ func requestHandler(ctx *fasthttp.RequestCtx) { ...@@ -463,7 +500,7 @@ func requestHandler(ctx *fasthttp.RequestCtx) {
ctx.Response.Header.Add("Cache-Control", "no-cache, no-store, must-revalidate") ctx.Response.Header.Add("Cache-Control", "no-cache, no-store, must-revalidate")
ctx.Response.Header.Add("Pragma", "no-cache") ctx.Response.Header.Add("Pragma", "no-cache")
ctx.Response.Header.Add("Expires", "0") ctx.Response.Header.Add("Expires", "0")
err = discordHTMLTemplate.Execute(ctx, url) err = discordTemplate.Execute(ctx, url)
if err != nil { if err != nil {
log.Warn().Err(err).Msg("failed to execute discord html template on discordbot connection") log.Warn().Err(err).Msg("failed to execute discord html template on discordbot connection")
internalServerError(ctx) internalServerError(ctx)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment