Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: provide an option to access /index.html directly without 301 redirect #53870

Open
ahuigo opened this issue Jul 14, 2022 · 7 comments
Open
Labels
FeatureRequest NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@ahuigo
Copy link

ahuigo commented Jul 14, 2022

What version of Go are you using (go version)?

$ go version
go1.18, go1.17, ...(may be all versions)

What did you do?

I found that https://github.com/golang/go/blob/master/src/net/http/fs.go#L590 will redirect /index.html to / with 301 status code.

This 301 action may cause some problems for service worker's cache(https://stackoverflow.com/questions/40476938/service-worker-breaking-301-redirects)

In order to stop 301 redirect, I had to hack official GONIC code

What did you expect to see?

PWA(web app) could cache the start_url:"/index.html" (301 redirect)

What did you see instead?

Since Service Worker breaking 301 redirects, my PWA app can't cache the start_url:"/index.html"

I think it's better to have an option an option to access /index.html directly without 301 redirect. (If possible, I could submit a PR)

@mknyszek mknyszek added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. FeatureRequest labels Jul 14, 2022
@mknyszek mknyszek added this to the Backlog milestone Jul 14, 2022
@mknyszek
Copy link
Contributor

CC @neild

@seankhliao seankhliao changed the title net/http/fs: provide an option to access /index.html directly without 301 redirect net/http: provide an option to access /index.html directly without 301 redirect Jul 14, 2022
@seankhliao
Copy link
Member

you could just use start_url: "/" ?

@ahuigo
Copy link
Author

ahuigo commented Jul 15, 2022

you could just use start_url: "/" ?

@seankhliao This is not my own PWA app, I think it is unreasonable and unacceptable to modify someone else's code(e.g., https://github.com/mdn/pwa-examples).

Imagine other scenario, I want /index.html to show index pages and / to list file list. It's too hard too implement this with net/http/fs

@neild
Copy link
Contributor

neild commented Jul 15, 2022

I think it's reasonable to want an http.FileServer that doesn't redirect .../index.html requests, but I'm not sure what the API for it should be.

One thought might be to only redirect an .../index.html request if the index.html file doesn't exist. That is, try opening the file, and only consider redirecting the request if the open fails.

ahuigo added a commit to ahuigo/go that referenced this issue Jul 16, 2022
…out 301 redirect

For: golang#53870
BREAKING CHANGES: http.ServeFile won't redirect /index.html
ahuigo added a commit to ahuigo/go that referenced this issue Jul 16, 2022
…out 301 redirect

For: golang#53870
BREAKING CHANGES: http.ServeFile won't redirect /index.html
ahuigo added a commit to ahuigo/go that referenced this issue Jul 16, 2022
…out 301 redirect

For: golang#53870
BREAKING CHANGES: http.ServeFile won't redirect /index.html
@ahuigo
Copy link
Author

ahuigo commented Jul 16, 2022

I think the easiest way to do this is to provide an optional chained method like this:

	fileServer := http.FileServer(fs)

	////  Is better to let http.FileServer return Struct instead of interface? 
	// fileServer := http.FileServer(fs).SkipPermanentRedirect() 

	// skip 301 redirect
	fileServer.(*http.FileHandler).SkipPermanentRedirect()

8a1fd33#diff-334dd14b9fe9d920086cc14ef1a9f13ac90972a7b289b944d00d4a9be6891a98R23

ahuigo added a commit to ahuigo/go that referenced this issue Jul 16, 2022
…out 301 redirect

For: golang#53870
BREAKING CHANGES: http.ServeFile won't redirect /index.html
@seankhliao
Copy link
Member

In the spirit of http.StripPrefix, this could just be an http middleware layer (untested):

func StripIndex(h http.Handler) http.Handler {
    return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request {
        r.URL.Path = strings.TrimSuffix(r.URL.Path, "index.html")
        h.ServeHTTP(rw, r)
    })
}

@ahuigo
Copy link
Author

ahuigo commented Jul 19, 2022

In the spirit of http.StripPrefix, this could just be an http middleware layer (untested):

func StripIndex(h http.Handler) http.Handler {
    return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request {
        r.URL.Path = strings.TrimSuffix(r.URL.Path, "index.html")
        h.ServeHTTP(rw, r)
    })
}

This is some like what I did in hack GONIC code:

	fileServer := http.FileServer(fs)
	return func(c *gin.Context) {
		.....
		// Replace `/index.html` with `/` to stop 301 redirect
		if strings.HasSuffix(c.Request.URL.Path, "/index.html") {
			c.Request.URL.Path = strings.TrimSuffix(c.Request.URL.Path, "index.html")
		}

		fileServer.ServeHTTP(c.Writer, c.Request)
        }

It works well, but I think injecting logic into every request is not so KISS———
If I can't modify the default redirection action at the begin of initialize http.FileServer(fs),
it may be no so easy to inject this logic to http handler if a project do not expose this http handler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FeatureRequest NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants