From 3cbab96f51f0687a266ea314eb41408f70f70fb1 Mon Sep 17 00:00:00 2001 From: Rohan Verma Date: Wed, 28 Sep 2022 23:55:50 +0530 Subject: [PATCH] [#661] serve css files with text/css content-type Currently, css files are served as text/plain by the server. It is not trivial to detect css file types similar to the issue with svg files. When the css files are served as text/plain instead of text/css they become unusable as stylesheets in the browser when served via the api. In this commit we generalize the svg detection to also detect css files and serve specific extensions with their respective mimetypes. --- tools/filesystem/filesystem.go | 15 ++++++++++----- tools/filesystem/filesystem_test.go | 20 +++++++++++++++++++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/tools/filesystem/filesystem.go b/tools/filesystem/filesystem.go index 2e7ad542..22c64aa3 100644 --- a/tools/filesystem/filesystem.go +++ b/tools/filesystem/filesystem.go @@ -196,6 +196,12 @@ var inlineServeContentTypes = []string{ "application/pdf", "application/x-pdf", } +// manualExtensionContentTypes is a map of file extensions to content types. +var manualExtensionContentTypes = map[string]string{ + ".svg": "image/svg+xml", // (see https://github.com/whatwg/mimesniff/issues/7) + ".css": "text/css", // (see https://github.com/gabriel-vasile/mimetype/pull/113) +} + // Serve serves the file at fileKey location to an HTTP response. func (s *System) Serve(response http.ResponseWriter, fileKey string, name string) error { r, readErr := s.bucket.NewReader(s.ctx, fileKey, nil) @@ -210,12 +216,11 @@ func (s *System) Serve(response http.ResponseWriter, fileKey string, name string disposition = "inline" } - // make an exception for svg and force a custom content type - // to send in the response so that it can be loaded in an img tag - // (see https://github.com/whatwg/mimesniff/issues/7) + // make an exception for specific content types and force a + // custom content type to send in the response so that it can be loaded directly. extContentType := realContentType - if extContentType != "image/svg+xml" && filepath.Ext(name) == ".svg" { - extContentType = "image/svg+xml" + if ct, found := manualExtensionContentTypes[filepath.Ext(name)]; found && extContentType != ct { + extContentType = ct } response.Header().Set("Content-Disposition", disposition+"; filename="+name) diff --git a/tools/filesystem/filesystem_test.go b/tools/filesystem/filesystem_test.go index e9a6a7d4..89fa78dc 100644 --- a/tools/filesystem/filesystem_test.go +++ b/tools/filesystem/filesystem_test.go @@ -207,6 +207,18 @@ func TestFileSystemServe(t *testing.T) { "Content-Security-Policy": "default-src 'none'; style-src 'unsafe-inline'; sandbox", }, }, + { + // css exception + "style.css", + "test_name.css", + false, + map[string]string{ + "Content-Disposition": "attachment; filename=test_name.css", + "Content-Type": "text/css", + "Content-Length": "0", + "Content-Security-Policy": "default-src 'none'; style-src 'unsafe-inline'; sandbox", + }, + }, } for _, scenario := range scenarios { @@ -216,7 +228,7 @@ func TestFileSystemServe(t *testing.T) { hasErr := err != nil if hasErr != scenario.expectError { - t.Errorf("(%s) Expected hasError %v, got %v", scenario.path, scenario.expectError, hasErr) + t.Errorf("(%s) Expected hasError %v, got %v (%v)", scenario.path, scenario.expectError, hasErr, err) continue } @@ -321,5 +333,11 @@ func createTestDir(t *testing.T) string { } file4.Close() + file5, err := os.OpenFile(filepath.Join(dir, "style.css"), os.O_WRONLY|os.O_CREATE, 0666) + if err != nil { + t.Fatal(err) + } + file5.Close() + return dir }