diff --git a/assets/templates/html/pasteMeta.html.tmpl b/assets/templates/html/pasteMeta.html.tmpl
index 15c113d..5c50084 100644
--- a/assets/templates/html/pasteMeta.html.tmpl
+++ b/assets/templates/html/pasteMeta.html.tmpl
@@ -6,8 +6,8 @@
 <pre>
 <a href="{{.Host}}/{{.Paste.Key}}{{.FileExt}}">{{.Host}}/{{.Paste.Key}}{{.FileExt}}</a>
 ---
-{{if and (ne .Paste.State.String "deleted") .CanDelete.Bool}}
-with delete token: <a href="{{.Host}}/{{.Paste.Key}}{{.FileExt}}?deleteToken={{.Request.URL.Query.Get "deleteToken"}}">{{.Host}}/{{.Paste.Key}}{{.FileExt}}?deleteToken={{.Request.URL.Query.Get "deleteToken"}}</a>
+{{if and (ne .Paste.State.String "deleted") .CanDeleteBool}}
+with delete token: <a href="{{.Host}}/{{.Paste.Key}}{{.FileExt}}?deleteToken={{.Paste.DeleteToken}}">{{.Host}}/{{.Paste.Key}}{{.FileExt}}?deleteToken={{.Paste.DeleteToken}}</a>
 {{else -}}
 with delete token: &lt;unknown&gt;
 {{end -}}
@@ -18,18 +18,11 @@ created: unknown
 {{else -}}
 created: {{.Paste.TimeCreated}}
 {{end -}}
-delete token: {{.CanDelete.String}}
+delete token: {{.CanDelete}}
 
-{{if and (ne .Paste.State.String "deleted") .CanDelete.Bool}}
+{{if and (ne .Paste.State.String "deleted") .CanDeleteBool}}
 ```
-# To delete this {{.Paste.Type}}, execute:
-{{- /*
-    We have the option here to take the deleteToken from the user request or
-    from .Paste.  Both are equivalent as long as .CanDelete is correct.  We
-    use the .Request value, because leaking the deleteToken would be a more
-    dramatic vulnerability.
-*/}}
-curl --request "DELETE" "<a href="{{.Host}}/{{.Paste.Key}}{{.FileExt}}?deleteToken={{.Request.URL.Query.Get "deleteToken"}}">{{.Host}}/{{.Paste.Key}}{{.FileExt}}?deleteToken={{.Request.URL.Query.Get "deleteToken"}}"</a>
+curl --request "DELETE" "<a href="{{.Host}}/{{.Paste.Key}}{{.FileExt}}?deleteToken={{.Paste.DeleteToken}}">{{.Host}}/{{.Paste.Key}}{{.FileExt}}?deleteToken={{.Paste.DeleteToken}}"</a>
 ```
 </pre>
 {{end}}
diff --git a/assets/templates/txt/pasteMeta.txt.tmpl b/assets/templates/txt/pasteMeta.txt.tmpl
index 04cb8dc..c2c5ee5 100644
--- a/assets/templates/txt/pasteMeta.txt.tmpl
+++ b/assets/templates/txt/pasteMeta.txt.tmpl
@@ -1,6 +1,6 @@
 {{.Host}}/{{.Paste.Key}}{{.FileExt}}
 ---
-{{if and (ne .Paste.State.String "deleted") .CanDelete.Bool}}
+{{if and (ne .Paste.State.String "deleted") .CanDeleteBool}}
 with delete token: {{.Host}}/{{.Paste.Key}}{{.FileExt}}?deleteToken={{.Request.URL.Query.Get "deleteToken"}}
 {{else -}}
 with delete token: <unknown>
@@ -11,17 +11,11 @@ created: unknown
 {{else -}}
 created: {{.Paste.TimeCreated}}
 {{end -}}
-delete token: {{.CanDelete.String}}
+delete token: {{.CanDelete}}
 
-{{if and (ne .Paste.State.String "deleted") .CanDelete.Bool}}
+{{if and (ne .Paste.State.String "deleted") .CanDeleteBool}}
 ```
 # To delete this {{.Paste.Type}}, execute:
-{{- /*
-    We have the option here to take the deleteToken from the user request or
-    from .Paste.  Both are equivalent as long as .CanDelete is correct.  We
-    use the .Request value, because leaking the deleteToken would be a more
-    dramatic vulnerability.
-*/ -}}
-curl --request "DELETE" "{{.Host}}/{{.Paste.Key}}{{.FileExt}}?deleteToken={{.Request.URL.Query.Get "deleteToken"}}"
+curl --request "DELETE" "{{.Host}}/{{.Paste.Key}}{{.FileExt}}?deleteToken={{.Paste.DeleteToken}}"
 ```
 {{end}}
diff --git a/handlers.go b/handlers.go
index c491f34..77d1ced 100644
--- a/handlers.go
+++ b/handlers.go
@@ -28,6 +28,31 @@ const (
 
 const cookieDeleteToken = "owner_token"
 
+type canDelete uint
+
+const (
+	canDeleteUndef canDelete = iota
+	canDeleteYes
+	canDeleteNo
+)
+
+func (cd *canDelete) Bool() bool {
+	return *cd == canDeleteYes
+}
+
+func (cd *canDelete) String() string {
+	switch *cd {
+	case canDeleteUndef:
+		return "undefined"
+	case canDeleteYes:
+		return "correct"
+	case canDeleteNo:
+		return "invalid"
+	default:
+		panic("unreachable")
+	}
+}
+
 func (rl *rushlink) staticGetHandler(w http.ResponseWriter, r *http.Request) {
 	rl.renderStatic(w, r, mux.Vars(r)["path"])
 }
@@ -79,24 +104,22 @@ func (rl *rushlink) uploadFileGetHandler(w http.ResponseWriter, r *http.Request)
 }
 
 func (rl *rushlink) viewPasteHandler(w http.ResponseWriter, r *http.Request) {
-	rl.viewPasteHandlerInner(w, r, 0)
+	rl.viewPasteHandlerFlags(w, r, 0)
 }
 
 func (rl *rushlink) viewPasteHandlerNoRedirect(w http.ResponseWriter, r *http.Request) {
-	rl.viewPasteHandlerInner(w, r, viewNoRedirect)
+	rl.viewPasteHandlerFlags(w, r, viewNoRedirect)
 }
 
 func (rl *rushlink) viewPasteHandlerMeta(w http.ResponseWriter, r *http.Request) {
-	rl.viewPasteHandlerInner(w, r, viewShowMeta)
+	rl.viewPasteHandlerFlags(w, r, viewShowMeta)
 }
 
-func (rl *rushlink) viewPasteHandlerInner(w http.ResponseWriter, r *http.Request, flags viewPaste) {
+func (rl *rushlink) viewPasteHandlerFlags(w http.ResponseWriter, r *http.Request, flags viewPaste) {
 	vars := mux.Vars(r)
 	key := vars["key"]
 	var p *db.Paste
-	var fuID *uuid.UUID
 	var fu *db.FileUpload
-	var fileExt string
 	if err := rl.db.Bolt.View(func(tx *bolt.Tx) error {
 		var err error
 		p, err = db.GetPaste(tx, key)
@@ -106,12 +129,10 @@ func (rl *rushlink) viewPasteHandlerInner(w http.ResponseWriter, r *http.Request
 		if p != nil && p.Type == db.PasteTypeFileUpload {
 			var id uuid.UUID
 			copy(id[:], p.Content)
-			fuID = &id
 			fu, err = db.GetFileUpload(tx, id)
 			if err != nil {
 				return err
 			}
-			fileExt = fu.Ext()
 		}
 		return nil
 	}); err != nil {
@@ -123,30 +144,12 @@ func (rl *rushlink) viewPasteHandlerInner(w http.ResponseWriter, r *http.Request
 		return
 	}
 
-	if flags&viewShowMeta != 0 {
-		canDelete := struct {
-			Bool   bool
-			String string
-		}{Bool: false}
-		deleteToken := getDeleteTokenFromRequest(r)
-		if deleteToken == "" {
-			canDelete.String = "undefined"
-		} else {
-			if subtle.ConstantTimeCompare([]byte(deleteToken), []byte(p.DeleteToken)) == 1 {
-				canDelete.Bool = true
-				canDelete.String = "correct"
-			} else {
-				canDelete.String = "invalid"
-			}
-		}
+	rl.viewPasteHandlerInner(w, r, flags, p, fu)
+}
 
-		data := map[string]interface{}{
-			"Paste":     p,
-			"FileExt":   fileExt,
-			"CanDelete": canDelete,
-		}
-		rl.render(w, r, "pasteMeta", data)
-		return
+func (rl *rushlink) viewPasteHandlerInner(w http.ResponseWriter, r *http.Request, flags viewPaste, p *db.Paste, fu *db.FileUpload) {
+	if flags&viewShowMeta != 0 {
+		rl.viewPasteHandlerInnerMeta(w, r, p, fu)
 	}
 
 	switch p.State {
@@ -155,7 +158,7 @@ func (rl *rushlink) viewPasteHandlerInner(w http.ResponseWriter, r *http.Request
 		switch p.Type {
 		case db.PasteTypeFileUpload:
 			if fu == nil {
-				panic(fmt.Sprintf("file for id %v does not exist in database\n", fuID))
+				panic(fmt.Sprintf("file for id %v does not exist in database\n", string(p.Content)))
 			}
 			location = fu.URL().String()
 			break
@@ -176,6 +179,46 @@ func (rl *rushlink) viewPasteHandlerInner(w http.ResponseWriter, r *http.Request
 	}
 }
 
+func (rl *rushlink) viewPasteHandlerInnerMeta(w http.ResponseWriter, r *http.Request, p *db.Paste, fu *db.FileUpload) {
+	var cd canDelete
+	deleteToken := getDeleteTokenFromRequest(r)
+	if deleteToken != "" {
+		if subtle.ConstantTimeCompare([]byte(deleteToken), []byte(p.DeleteToken)) == 1 {
+			cd = canDeleteYes
+		} else {
+			cd = canDeleteNo
+		}
+	}
+
+	var fileExt string
+	if fu != nil {
+		fileExt = fu.Ext()
+	}
+	data := map[string]interface{}{
+		"Paste":         p,
+		"FileExt":       fileExt,
+		"CanDelete":     cd,
+		"CanDeleteBool": cd.Bool(),
+	}
+	rl.render(w, r, "pasteMeta", data)
+	return
+}
+
+func (rl *rushlink) viewCreateSuccess(w http.ResponseWriter, r *http.Request, p *db.Paste, fu *db.FileUpload) {
+	var fileExt string
+	if fu != nil {
+		fileExt = fu.Ext()
+	}
+	data := map[string]interface{}{
+		"Paste":         p,
+		"FileExt":       fileExt,
+		"CanDelete":     canDeleteYes,
+		"CanDeleteBool": true,
+	}
+	rl.render(w, r, "pasteMeta", data)
+	return
+}
+
 func (rl *rushlink) newPasteHandler(w http.ResponseWriter, r *http.Request) {
 	file, fileHeader, err := r.FormFile("file")
 	if err == nil {
@@ -216,7 +259,7 @@ func (rl *rushlink) newFileUploadPasteHandler(w http.ResponseWriter, r *http.Req
 	}); err != nil {
 		panic(err)
 	}
-	rl.renderCreateSuccess(w, r, paste, fu)
+	rl.viewCreateSuccess(w, r, paste, fu)
 }
 
 func (rl *rushlink) newPasteHandlerURLEncoded(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
@@ -256,7 +299,7 @@ func (rl *rushlink) newRedirectPasteHandler(w http.ResponseWriter, r *http.Reque
 	}); err != nil {
 		panic(err)
 	}
-	rl.renderCreateSuccess(w, r, paste, nil)
+	rl.viewCreateSuccess(w, r, paste, nil)
 }
 
 // Delete a URL from the database
@@ -297,7 +340,7 @@ func (rl *rushlink) deletePasteHandler(w http.ResponseWriter, r *http.Request) {
 		rl.renderError(w, r, errorCode, fmt.Sprintf("error: %v\n", err))
 		return
 	}
-	rl.renderCreateSuccess(w, r, paste, nil)
+	rl.viewCreateSuccess(w, r, paste, nil)
 }
 
 // Add a new fileUpload redirect to the database
diff --git a/views.go b/views.go
index 10d5f6a..88cdfee 100644
--- a/views.go
+++ b/views.go
@@ -9,7 +9,6 @@ import (
 	"io"
 	"log"
 	"net/http"
-	"net/url"
 	"path/filepath"
 	"regexp"
 	"runtime/debug"
@@ -19,8 +18,6 @@ import (
 	text "text/template"
 	"time"
 
-	"gitea.hashru.nl/dsprenkels/rushlink/internal/db"
-
 	"github.com/pkg/errors"
 )
 
@@ -168,22 +165,6 @@ func (rl *rushlink) renderInternalServerError(w http.ResponseWriter, r *http.Req
 	rl.renderError(w, r, http.StatusInternalServerError, msg)
 }
 
-func (rl *rushlink) renderCreateSuccess(w http.ResponseWriter, r *http.Request, paste *db.Paste, fu *db.FileUpload) {
-	if paste == nil {
-		panic("paste should not be nil")
-	}
-	var fileExt string
-	if fu != nil {
-		fileExt = fu.Ext()
-	}
-	var redirectURL url.URL
-	redirectURL.Path = fmt.Sprintf("/%s%s/meta", paste.Key, fileExt)
-	queryVals := redirectURL.Query()
-	queryVals.Add("deleteToken", paste.DeleteToken)
-	redirectURL.RawQuery = queryVals.Encode()
-	http.Redirect(w, r, redirectURL.String(), http.StatusFound)
-}
-
 // resolveHost constructs the `scheme://host` part of rushlinks public API.
 //
 // If the `--host` flag is set, it will return that URL.