Comments (13)
You can't register a "catch all" at the root dir for serving files while also registering other handlers at sub-pathes.
See also the note at https://github.com/julienschmidt/httprouter#named-parameters
To serve static files with HttpRouter you must use a sub-path which is only used for serving the files, e.g.
router := httprouter.New()
// normal handlers
router.GET("/ws", wsHandler)
// handler for serving files
router.ServeFiles("/static/*filepath", http.Dir("/var/www/public/"))
This way you could serve files at example.com/static/*
An alternative might be serving files via a subdomain.
In #4 the NotFound handler was used, but that is not a good idea in my opinion (and you should definitely turn RedirectTrailingSlash
and RedirectFixedPath
off in that case.
from httprouter.
Solved it with 2 separate routers and the NotFound
handler. That way I can check for specific routes first and if none of them match serve static files.
router := httprouter.New()
router.GET("/", s.index())
router.GET("/api/", s.api())
// if not found look for a static file
static := httprouter.New()
static.ServeFiles("/*filepath", http.Dir(staticPath))
router.NotFound = static
from httprouter.
http.Handle("/", http.FileServer(http.Dir("public/")))
doesnt serve anything and throws me 404 on /
!
from httprouter.
I'm building an API on top of HttpRouter. But Also I want to serve static files thats is my client application (html, css, js, ...).
router := httprouter.New()
router.GET("/ws", wsHandler)
// Other handlers
http.Handle("/", http.FileServer(http.Dir("public/")))
log.Fatal(http.ListenAndServe(":3000", router))
from httprouter.
If you serve it from the root dir, you don't need HttpRouter. You don't need a router at all, since you handle everything with just one handler function.
http.Handle("/", http.FileServer(http.Dir("public/")))
should be the way to solve with net/http.
See also #4 (comment)
from httprouter.
Try using the absolute path in http.Dir maybe.
If you want to serve files only, something like this might also work (doesn't require the involvement of http.ServeMux):
package main
import (
"net/http"
)
func main() {
panic(http.ListenAndServe(":8080", http.FileServer(http.Dir("/var/www/public"))))
}
Or if you want to do some more things like logging:
package main
import (
"fmt"
"net/http"
)
func main() {
panic(http.ListenAndServe(":8080", &logServer{
hdl: http.FileServer(http.Dir("/var/www/public")),
}))
}
type logServer struct {
hdl http.Handler
}
func (l *logServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.RemoteAddr, r.URL, r.URL.Path)
l.hdl.ServeHTTP(w, r)
}
from httprouter.
[using the NotFound handler to serve files] is not a good idea in my opinion
Why not? I need the ability to serve index.html and favicon files from my root, and I'm looking for the best way to accomplish this.
from httprouter.
I agree with daveroberts ... ALL root folders on web sites that I develop for my customers contain 1 file (index.html) and various subfolders (eg /static, /api)
Using Juliens great router component, I can serve a file from any and all subfolders ... however I cannot serve index.html in the root folder with it.
I believe your component requires a tiny tweak, Julien, to accommodate this very common scenario.
.
Advice anyone please ??
from httprouter.
The way I solved index problem was to serve index.html like this:
func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
http.ServeFile(w, r, r.URL.Path[1:])
}
func main() {
router := httprouter.New()
router.GET("/", Index)
router.ServeFiles("/app/*filepath", http.Dir("static"))
....
log.Fatal(http.ListenAndServe(":8080", router))
}
from httprouter.
This forces all of your static files to be accessible under /static. This may work for some projects, but not all. A couple of examples which come to mind:
- The default path for a favicon is in the root directory. If a user requests a non-HTML page, the favicon won't load
- People may already be linking to files on your site and you can't change the links
from httprouter.
This is what finally worked for me:
func main() {
router := httprouter.New()
router.GET("/", LandingPage)
router.GET("/Create", Create)
router.ServeFiles("/static/*filepath",http.Dir("static"))
logger.LogInfo("Server running at http://0.0.0.0:3001")
log.Fatal(http.ListenAndServe(":3001", router))
}
from httprouter.
@julienschmidt
I keep running into this issue again and again when trying to convert an existing php/python/vb6/etc. website to go. I love your router but It is not usable for all these websites because the static files never are to be served in a separate path. I would like them to have a separate path but it just isn't actionable to change that for these large projects.
from httprouter.
Solved it without creating a new router while serving all static files under /
router.NotFound = http.FileServer(http.Dir(staticPath)).ServeHTTP
from httprouter.
Related Issues (20)
- How to use this custom middleware HOT 1
- Matching multiple named parameters HOT 1
- ServeFiles not able to serve static files HOT 2
- How can I receive multiple parameters in GET request? HOT 3
- Is it possible to bind one router to some path in another router? HOT 2
- is it possible to get the registered path? HOT 7
- panic: '/hello/:name' in new path '/hello/:name' conflicts with existing wildcar
- Why make catchAll form so special HOT 2
- httprouter.ParamsWithContext(r.Context()) is returning []
- Question: will re-registering a handler work properly?
- Fails with "embed" package HOT 1
- Dump all registered routes HOT 3
- Improve longestCommonPrefix and add unit tests HOT 1
- Question: How can I embed swagger UI? HOT 2
- Feature Request: Support multi-wildcard names for same tree branch HOT 1
- panic: path must begin with '/' in path 'GET'
- List all registered endpoint httprouter
- what is the empty path node used for? HOT 1
- Unable to load jsx files because "file.jsx was blocked because of a disallowed MIME type text/plain" HOT 2
- Plan to Consolidate with net/http @ 1.22?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from httprouter.