Skip to content

Commit

Permalink
fileserver struct rather than DefaultServeMux
Browse files Browse the repository at this point in the history
  • Loading branch information
syntaqx committed Jan 15, 2019
1 parent b172369 commit d41184b
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 51 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,27 @@ to your `$PATH`, can now be used.
serve version
```

## Using `serve` manually

Serve also exposes a reusable `FileServer` convenience struct, letting you
easily create your own static file server:

```go
package main

import (
"log"
"net/http"

"github.com/syntaqx/serve"
)

func main() {
fs := serve.NewFileServer(".")
log.Fatal(http.ListenAndServe(":8080", fs))
}
```

## License

[MIT]: https://opensource.org/licenses/MIT
Expand Down
13 changes: 13 additions & 0 deletions example/simple/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package main

import (
"log"
"net/http"

"github.com/syntaqx/serve"
)

func main() {
fs := serve.NewFileServer(".")
log.Fatal(http.ListenAndServe(":8080", fs))
}
12 changes: 9 additions & 3 deletions internal/commands/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,23 @@ import (
"strconv"
"time"

"github.com/syntaqx/serve"
"github.com/syntaqx/serve/internal/config"
"github.com/syntaqx/serve/internal/router"
"github.com/syntaqx/serve/internal/middleware"
)

// Server implements the static http server command.
func Server(log *log.Logger, opt config.Flags) error {
r := router.NewRouter(log, opt)
fs := serve.NewFileServer(opt.Dir)

fs.Use(middleware.Logger(log))
fs.Use(middleware.Recover())
fs.Use(middleware.CORS())
fs.Use(middleware.NoCache())

server := &http.Server{
Addr: net.JoinHostPort(opt.Host, strconv.Itoa(opt.Port)),
Handler: r,
Handler: fs,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
}
Expand Down
2 changes: 1 addition & 1 deletion internal/middleware/recover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ func TestRecover(t *testing.T) {
Recover()(testHandler).ServeHTTP(res, req)

assert.Equal(http.StatusInternalServerError, res.Code)
assert.Equal(strings.TrimSpace(res.Body.String()), "[PANIC RECOVERED] test")
assert.Equal("[PANIC RECOVERED] test", strings.TrimSpace(res.Body.String()))
}
25 changes: 0 additions & 25 deletions internal/router/router.go

This file was deleted.

22 changes: 0 additions & 22 deletions internal/router/router_test.go

This file was deleted.

26 changes: 26 additions & 0 deletions serve.go
Original file line number Diff line number Diff line change
@@ -1,2 +1,28 @@
// Package serve provides a static http server anywhere you need one.
package serve

import "net/http"

// FileServer implements the http.FileServer.
type FileServer struct {
Handler http.Handler
}

// NewFileServer initializes a FileServer.
func NewFileServer(dir string) *FileServer {
fs := &FileServer{
Handler: http.FileServer(http.Dir(dir)),
}

return fs
}

// Use wraps the handler with another, middleware style.
func (fs *FileServer) Use(h func(http.Handler) http.Handler) {
fs.Handler = h(fs.Handler)
}

// ServeHTTP implements the net/http.Handler interface.
func (fs *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fs.Handler.ServeHTTP(w, r)
}
62 changes: 62 additions & 0 deletions serve_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package serve

import (
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"
)

func TestFileServerUse(t *testing.T) {
t.Parallel()
assert := assert.New(t)

req, err := http.NewRequest(http.MethodGet, "/", nil)
assert.NoError(err)
res := httptest.NewRecorder()

testMiddleware1 := func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("start\n"))
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}

testMiddleware2 := func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("end\n"))
}
return http.HandlerFunc(fn)
}

fs := NewFileServer(".")
fs.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t.Fail()
})

fs.Use(testMiddleware2)
fs.Use(testMiddleware1)

fs.ServeHTTP(res, req)

assert.Equal("start\nend\n", res.Body.String())
}

func TestFileServerServeHTTP(t *testing.T) {
t.Parallel()
assert := assert.New(t)

req, err := http.NewRequest(http.MethodGet, "/", nil)
assert.NoError(err)
res := httptest.NewRecorder()

fs := NewFileServer(".")
fs.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("expected"))
})
fs.ServeHTTP(res, req)

assert.Equal("expected", res.Body.String())
}

0 comments on commit d41184b

Please sign in to comment.