Skip to content

Commit

Permalink
0.1.0 && optimize test
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidCai1111 committed Nov 26, 2016
1 parent 572e35c commit 8947f61
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 9 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
# favicon
[![Build Status](https://travis-ci.org/go-http-utils/favicon.svg?branch=master)](https://travis-ci.org/go-http-utils/favicon)
[![Coverage Status](https://coveralls.io/repos/github/go-http-utils/favicon/badge.svg?branch=master)](https://coveralls.io/github/go-http-utils/favicon?branch=master)

Go http middleware for serving the favicon.

## Installation

go get -u github.com/go-http-utils/favicon

## Documentation

API documentation can be found here: https://godoc.org/github.com/go-http-utils/favicon

## Usage

```go
import (
"github.com/go-http-utils/favicon"
)
```

```go
mux := http.NewServeMux()
mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
res.Write([]byte("Hello World"))
})

http.ListenAndServe(":8080", favicon.Handler(mux, "./public/favicon.ico"))
```
16 changes: 16 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package favicon_test

import (
"net/http"

"github.com/go-http-utils/favicon"
)

func Example() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
res.Write([]byte("Hello World"))
})

http.ListenAndServe(":8080", favicon.Handler(mux, "./public/favicon.ico"))
}
20 changes: 11 additions & 9 deletions favicon.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,24 @@ import (
)

// Version is this package's version.
const Version = "0.0.1"
const Version = "0.1.0"

// Handler wraps the http.Handler h with favicon support. `path`
// is the path to find the favicon.
func Handler(h http.Handler, path string) http.Handler {
if !os.IsPathSeparator(path[0]) {
if wd, err := os.Getwd(); err == nil {
path = filepath.Join(wd, path)
} else {
wd, err := os.Getwd()

if err != nil {
panic(err)
}

path = filepath.Join(wd, path)
}

stat, err := os.Stat(path)

if err != nil || stat == nil || stat.IsDir() {
if err != nil || stat.IsDir() {
panic("favicon: Invalid favicon path: " + path)
}

Expand All @@ -36,7 +38,7 @@ func Handler(h http.Handler, path string) http.Handler {
panic(err)
}

reader := bytes.NewReader(file)
readSeeker := bytes.NewReader(file)

return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.RequestURI != "/favicon.ico" {
Expand All @@ -46,19 +48,19 @@ func Handler(h http.Handler, path string) http.Handler {
}

if req.Method != http.MethodGet && req.Method != http.MethodHead {
res.Header().Set(headers.Allow, "GET, HEAD, OPTIONS")

if req.Method == http.MethodOptions {
res.WriteHeader(http.StatusOK)
} else {
res.WriteHeader(http.StatusMethodNotAllowed)
}

res.Header().Set(headers.Allow, "GET, HEAD, OPTIONS")

return
}

res.Header().Set(headers.ContentType, "image/x-icon")

http.ServeContent(res, req, "favicon.ico", stat.ModTime(), reader)
http.ServeContent(res, req, "favicon.ico", stat.ModTime(), readSeeker)
})
}
129 changes: 129 additions & 0 deletions favicon_test.go
Original file line number Diff line number Diff line change
@@ -1 +1,130 @@
package favicon

import (
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"

"github.com/go-http-utils/headers"
"github.com/stretchr/testify/suite"
)

func init() {
bytes, err := ioutil.ReadFile("./test_fixtures/favicon.ico")

if err != nil {
panic(err)
}

faviconBytes = bytes
}

var faviconBytes []byte

type FaviconSuite struct {
suite.Suite

relServer *httptest.Server
absServer *httptest.Server
}

func (s *FaviconSuite) SetupTest() {
relMux := http.NewServeMux()
relMux.Handle("/", http.HandlerFunc(helloHandlerFunc))

s.relServer = httptest.NewServer(Handler(relMux,
"./test_fixtures/favicon.ico"))

absMux := http.NewServeMux()
absMux.Handle("/", http.HandlerFunc(helloHandlerFunc))

wd, err := os.Getwd()
s.Nil(err)

s.absServer = httptest.NewServer(Handler(absMux,
filepath.Join(wd, "./test_fixtures/favicon.ico")))

panicMux := http.NewServeMux()

s.Panics(func() {
httptest.NewServer(Handler(panicMux, "invalid-path"))
})
}

func (s *FaviconSuite) TestNotFaviconRes() {
res, err := http.Get(s.relServer.URL + "/")

s.Nil(err)
s.Equal(http.StatusOK, res.StatusCode)
s.Equal([]byte("Hello World"), getResRawBody(res))
}

func (s *FaviconSuite) TestRelPathFaviconRes() {
res, err := http.Get(s.relServer.URL + "/favicon.ico")

s.Nil(err)
s.Equal(http.StatusOK, res.StatusCode)
s.Equal("image/x-icon", res.Header.Get(headers.ContentType))
s.Equal(faviconBytes, getResRawBody(res))
}

func (s *FaviconSuite) TestAbsPathFaviconRes() {
res, err := http.Get(s.absServer.URL + "/favicon.ico")

s.Nil(err)
s.Equal(http.StatusOK, res.StatusCode)
s.Equal("image/x-icon", res.Header.Get(headers.ContentType))
s.Equal(faviconBytes, getResRawBody(res))
}

func (s *FaviconSuite) TestNotAcceptPostReq() {
req, err := http.NewRequest(http.MethodPost,
s.relServer.URL+"/favicon.ico", nil)

s.Nil(err)

res, err := sendRequest(req)

s.Nil(err)
s.Equal(http.StatusMethodNotAllowed, res.StatusCode)
s.Equal("GET, HEAD, OPTIONS", res.Header.Get(headers.Allow))
}

func (s *FaviconSuite) TestAcceptOptionsReq() {
req, err := http.NewRequest(http.MethodOptions,
s.relServer.URL+"/favicon.ico", nil)

s.Nil(err)

res, err := sendRequest(req)

s.Nil(err)
s.Equal(http.StatusOK, res.StatusCode)
s.Equal("GET, HEAD, OPTIONS", res.Header.Get(headers.Allow))
}

func TestFavicon(t *testing.T) {
suite.Run(t, new(FaviconSuite))
}

func helloHandlerFunc(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusOK)

res.Write([]byte("Hello World"))
}

func getResRawBody(res *http.Response) []byte {
if b, err := ioutil.ReadAll(res.Body); err != nil {
panic(err)
} else {
return b
}
}

func sendRequest(req *http.Request) (*http.Response, error) {
cli := &http.Client{}
return cli.Do(req)
}
Binary file added test_fixtures/favicon.ico
Binary file not shown.

0 comments on commit 8947f61

Please sign in to comment.