diff options
Diffstat (limited to 'workhorse/internal/headers')
-rw-r--r-- | workhorse/internal/headers/content_headers.go | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/workhorse/internal/headers/content_headers.go b/workhorse/internal/headers/content_headers.go index 9c33ddb8c8a..8cca3d97e82 100644 --- a/workhorse/internal/headers/content_headers.go +++ b/workhorse/internal/headers/content_headers.go @@ -8,28 +8,37 @@ import ( ) var ( - ImageTypeRegex = regexp.MustCompile(`^image/*`) - SvgMimeTypeRegex = regexp.MustCompile(`^image/svg\+xml$`) + javaScriptTypeRegex = regexp.MustCompile(`^(text|application)\/javascript$`) - TextTypeRegex = regexp.MustCompile(`^text/*`) + imageTypeRegex = regexp.MustCompile(`^image/*`) + svgMimeTypeRegex = regexp.MustCompile(`^image/svg\+xml$`) - VideoTypeRegex = regexp.MustCompile(`^video/*`) + textTypeRegex = regexp.MustCompile(`^text/*`) - PdfTypeRegex = regexp.MustCompile(`application\/pdf`) + videoTypeRegex = regexp.MustCompile(`^video/*`) - AttachmentRegex = regexp.MustCompile(`^attachment`) - InlineRegex = regexp.MustCompile(`^inline`) + pdfTypeRegex = regexp.MustCompile(`application\/pdf`) + + attachmentRegex = regexp.MustCompile(`^attachment`) + inlineRegex = regexp.MustCompile(`^inline`) ) // Mime types that can't be inlined. Usually subtypes of main types -var forbiddenInlineTypes = []*regexp.Regexp{SvgMimeTypeRegex} +var forbiddenInlineTypes = []*regexp.Regexp{svgMimeTypeRegex} // Mime types that can be inlined. We can add global types like "image/" or // specific types like "text/plain". If there is a specific type inside a global // allowed type that can't be inlined we must add it to the forbiddenInlineTypes var. // One example of this is the mime type "image". We allow all images to be // inlined except for SVGs. -var allowedInlineTypes = []*regexp.Regexp{ImageTypeRegex, TextTypeRegex, VideoTypeRegex, PdfTypeRegex} +var allowedInlineTypes = []*regexp.Regexp{imageTypeRegex, textTypeRegex, videoTypeRegex, pdfTypeRegex} + +const ( + svgContentType = "image/svg+xml" + textPlainContentType = "text/plain; charset=utf-8" + attachmentDispositionText = "attachment" + inlineDispositionText = "inline" +) func SafeContentHeaders(data []byte, contentDisposition string) (string, string) { contentType := safeContentType(data) @@ -40,16 +49,24 @@ func SafeContentHeaders(data []byte, contentDisposition string) (string, string) func safeContentType(data []byte) string { // Special case for svg because DetectContentType detects it as text if svg.Is(data) { - return "image/svg+xml" + return svgContentType } // Override any existing Content-Type header from other ResponseWriters contentType := http.DetectContentType(data) + // http.DetectContentType does not support JavaScript and would only + // return text/plain. But for cautionary measures, just in case they start supporting + // it down the road and start returning application/javascript, we want to handle it now + // to avoid regressions. + if isType(contentType, javaScriptTypeRegex) { + return textPlainContentType + } + // If the content is text type, we set to plain, because we don't // want to render it inline if they're html or javascript - if isType(contentType, TextTypeRegex) { - return "text/plain; charset=utf-8" + if isType(contentType, textTypeRegex) { + return textPlainContentType } return contentType @@ -58,7 +75,7 @@ func safeContentType(data []byte) string { func safeContentDisposition(contentType string, contentDisposition string) string { // If the existing disposition is attachment we return that. This allow us // to force a download from GitLab (ie: RawController) - if AttachmentRegex.MatchString(contentDisposition) { + if attachmentRegex.MatchString(contentDisposition) { return contentDisposition } @@ -82,11 +99,11 @@ func safeContentDisposition(contentType string, contentDisposition string) strin func attachmentDisposition(contentDisposition string) string { if contentDisposition == "" { - return "attachment" + return attachmentDispositionText } - if InlineRegex.MatchString(contentDisposition) { - return InlineRegex.ReplaceAllString(contentDisposition, "attachment") + if inlineRegex.MatchString(contentDisposition) { + return inlineRegex.ReplaceAllString(contentDisposition, attachmentDispositionText) } return contentDisposition @@ -94,11 +111,11 @@ func attachmentDisposition(contentDisposition string) string { func inlineDisposition(contentDisposition string) string { if contentDisposition == "" { - return "inline" + return inlineDispositionText } - if AttachmentRegex.MatchString(contentDisposition) { - return AttachmentRegex.ReplaceAllString(contentDisposition, "inline") + if attachmentRegex.MatchString(contentDisposition) { + return attachmentRegex.ReplaceAllString(contentDisposition, inlineDispositionText) } return contentDisposition |