Comments (9)
I'd probably use it as an endpoint, not a middleware:
goji.Get("/assets/*", http.FileServer(http.Dir("/path/to/assets")))
from goji.
Thanks
from goji.
How would you do it if files like index.html
or favicon.ico
should be available under /
?
Maybe it makes sense - performance wise - to attach it through goji.NotFound()
, in order to try the routes first and only then access the file system.
from goji.
I did it this way:
https://github.com/elcct/defaultproject/blob/master/server.go#L43-L44
But ideally, I would serve those files directly via nginx
from goji.
Those lines are actually what reminded me to take these "root files" into account :) But I would prefer a way without specifying a separate route each.
What do you think of attaching a FileServer
to goji.NotFound()
if the file requested exists, and otherwise handle the 404?
from goji.
If there are only a few of them and they change infrequently, I'd recommend adding them by hand (or maybe writing yourself a short script that codegens them for you). Don't overengineer a solution to a problem you don't have.
If you can't do that or otherwise don't want to, I'd write a middleware that goes something like this (entirely untested!)
type tryFiles struct {
dir string
inner http.Handler
}
func (t tryFiles) ServeHTTP(w http.ResponseWriter, r *http.Request) {
clean := filepath.Clean(r.URL.Path)
fname := filepath.Join(t.dir, clean)
f, err := os.Open(fname)
if err != nil {
t.inner.ServeHTTP(w, r)
return
}
defer f.Close()
s, err := f.Stat()
if err != nil {
t.inner.ServeHTTP(w, r)
return
}
http.ServeContent(w, r, fname, s.ModTime(), f)
}
func TryFiles(dir string) func(http.Handler) http.Handler {
return func(h http.Handler) http.Handler {
return tryFiles{dir, h}
}
}
which can be used like this: goji.Use(TryFiles("path/to/public"))
Maybe I'll make a real repo out of this :)
from goji.
True, but I prefer a static file serving middleware. Here's what I use:
type static struct {
dir string
h http.Handler
}
func (s static) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fname := filepath.Join(s.dir, r.URL.Path)
_, err := os.Stat(fname)
if err != nil {
s.h.ServeHTTP(w, r)
return
}
server := http.FileServer(http.Dir(s.dir))
server.ServeHTTP(w, r)
}
func Static(dir string) func(http.Handler) http.Handler {
return func(h http.Handler) http.Handler {
return static{dir, h}
}
}
I'm using FileServer()
because it already Clean()
s, Open()
s, serves /index.html
under /
and probably does some more.
It would be great to have an official one added to https://github.com/goji :)
from goji.
👍 +1 to this Issue
The use case I'm interested is:
- goji serve static files in development (using env variables), on
/*
and api on/api/v1/*
- in production static file serving gets handled by nginx/apache/whatever
Would be useful to only register API endpoints, and put on a clever NotFound
handler like @zenazn posted before.
If I succeed in creating a decent middleware I'll post it
from goji.
I don't think I'm able to make a plugin out of it.. yet (my skills in go + goji are like... well.. forget it!).
But in the meantime I've solved implementing a reverse string pattern
It's very simple. Posting it here so if you have ideas, I may also benefit!
// ReverseStringPattern is a simple struct keeping the raw string
// and the prefix to skip in requests
type ReverseStringPattern struct {
raw string
prefix string
}
// prefix returns "" so goji doesn't ever skip the matching function
func (s ReverseStringPattern) Prefix() string {
return ""
}
func (s ReverseStringPattern) Match(r *http.Request, c *web.C) bool {
path := r.URL.Path
return !strings.HasPrefix(path, s.prefix)
}
func (s ReverseStringPattern) Run(r *http.Request, c *web.C) {}
func NewReverseStringPattern(s string) ReverseStringPattern {
var prefix string = s
if strings.HasSuffix(s, "*") {
prefix = s[:len(s)-1]
}
return ReverseStringPattern{raw: s, prefix: prefix}
}
// serveStatic makes sure that if running for development
// purposes, it serves static content from /static
func serveStatic() {
buildMode := os.Getenv("mode")
switch buildMode {
case "development", "":
reverseApiPattern := NewReverseStringPattern("/api/*")
goji.Handle(reverseApiPattern, http.FileServer(http.Dir("static")))
case "production":
return
default:
return
}
}
from goji.
Related Issues (20)
- Use different middleware for different routes with App Engine HOT 2
- Data race when goroutines using context.Context outlive the http request HOT 2
- TLS from http.Request is nil HOT 8
- Post method with multipart/form-data encoding not work HOT 3
- returned 404 error when load js file HOT 1
- Document zenazn/goji vs goji/goji HOT 1
- wrapping HandlerType HOT 4
- Question: how to set timeout on HTTP requests HOT 8
- goji routing with react-router HOT 5
- Headers matching HOT 4
- Update ReadMe HOT 1
- Question: per-endpoint middleware HOT 5
- Does Goji 2 have Einhorn support? HOT 1
- How to use goji.ServeTLS() HOT 1
- How do I can change a variable with go command line? HOT 1
- SubRouter unexpected 404 HOT 4
- tag "v1.0" is a invalid module version HOT 5
- func Serve() have no options to disable log rquest HOT 1
- TLS context is not added to request HOT 2
- zenazn/goji or goji/goji ? HOT 1
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 goji.