Skip to content

Commit

Permalink
[pocketbase#661] serve css files with text/css content-type
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rhnvrm authored Sep 28, 2022
1 parent 6c005c4 commit 3cbab96
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 6 deletions.
15 changes: 10 additions & 5 deletions tools/filesystem/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
20 changes: 19 additions & 1 deletion tools/filesystem/filesystem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}

Expand Down Expand Up @@ -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
}

0 comments on commit 3cbab96

Please sign in to comment.