1

I'm building a Go web server that serves static files using TDD.

When I run my server and access /static/index.html in the browser, it works fine and returns the file. However, when I run my test using httptest, I get a 301 response with a Location: ./ header instead of 200. The static files serves on /templates dir.

func newServer() *http.ServeMux {
    mux := http.NewServeMux()

    mux.HandleFunc("/", rootHandler)

    fs := http.FileServer(http.Dir("./templates"))
    mux.Handle("/static/", http.StripPrefix("/static/", fs))

    return mux
}

Here's my test code:

func TestFile(t *testing.T) {
    cwd, err := os.Getwd()
    if err != nil {
        t.Fatalf("error get PATH %v", err)
    }

    server := newServer()
    req, err := http.NewRequest("GET", "/static/index.html", nil)
    if err != nil {
        t.Fatalf("error creating request: %v", err)
    }

    rec := httptest.NewRecorder()
    server.ServeHTTP(rec, req)

    if rec.Code != http.StatusOK {
        t.Errorf("Expected status OK, got %v", rec.Code)
        t.Logf("CWD %s", cwd)
        t.Logf("Response body: %s", rec.Body.String())
        t.Logf("Response headers: %v", rec.Header())
    }

    contentType := rec.Header().Get("Content-Type")
    if contentType != "text/html; charset=utf-8" {
        t.Errorf("Expected content type text/html; charset=utf-8, got %v", contentType)
    }

}

Test Output:

File directory:
 -rw-r--r--  1 user  staff    30 Aug  3 15:00 go.mod
-rw-r--r--@ 1 user  staff  1116 Aug  4 04:19 main_test.go
-rw-r--r--@ 1 user  staff   613 Aug  4 03:48 main.go
drwxr-xr-x@ 4 user  staff   128 Aug  4 04:04 templates
drwxr-xr-x  3 user  staff    96 Aug  3 15:02 test

./templates:
total 112
-rw-r--r--@ 1 user  staff  51007 Aug  4 03:58 htmx.min.js
-rw-r--r--@ 1 user  staff    237 Aug  4 04:04 index.html

./test:
total 8
-rw-r--r--@ 1 user  staff  21 Aug  3 15:02 compression_test.go

Why does http.FileServer return a 301 redirect with Location: ./ for an existing file in my test, but works fine in the browser? How can I make the test pass and return 200 as expected?

I’ve:

  • Ensured the file exists and is not a directory.
  • Used both relative and absolute paths for http.Dir.
  • Checked the current working directory in the test.
  • Filled index.html with simple HTML content.
1
  • 2
    Note that it might do the same thing in a browser, browsers will follow the 301 redirection though. Commented Aug 4 at 7:31

1 Answer 1

3

The http.FileServer documentation says:

As a special case, the returned file server redirects any request ending in "/index.html" to the same path, without the final "index.html".

Based on this, we expect the request in the question to redirect.

The browser follows the redirect to correct URL and the server returns the resource as expected.

The response recorder returns the redirect as is. In other words, the response recorder does not follow the redirect.

Fix one these ways:

  • use the correct URL
  • use http.TestServer and the net/http client (which follows redirects).
  • Write code in your test to follow the redirects.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.