Git Product home page Git Product logo

Comments (13)

julienschmidt avatar julienschmidt commented on May 12, 2024 16

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 RedirectTrailingSlashand RedirectFixedPath off in that case.

from httprouter.

tehsphinx avatar tehsphinx commented on May 12, 2024 12

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.

amrnt avatar amrnt commented on May 12, 2024 4

http.Handle("/", http.FileServer(http.Dir("public/"))) doesnt serve anything and throws me 404 on /!

from httprouter.

amrnt avatar amrnt commented on May 12, 2024 1

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.

julienschmidt avatar julienschmidt commented on May 12, 2024

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.

julienschmidt avatar julienschmidt commented on May 12, 2024

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.

daveroberts avatar daveroberts commented on May 12, 2024

[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.

deboerr avatar deboerr commented on May 12, 2024

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.

koodimetsa avatar koodimetsa commented on May 12, 2024

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.

daveroberts avatar daveroberts commented on May 12, 2024

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.

cooervo avatar cooervo commented on May 12, 2024

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.

tehsphinx avatar tehsphinx commented on May 12, 2024

@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.

DylanVerstraete avatar DylanVerstraete commented on May 12, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.