Skip to content

Commit

Permalink
flathttp/middleware: add content length check with test
Browse files Browse the repository at this point in the history
  • Loading branch information
lithdew committed May 24, 2020
1 parent 3c3d816 commit 5e30c01
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 7 deletions.
32 changes: 32 additions & 0 deletions flathttp/middleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package flathttp

import (
"net/http"
"strconv"
)

type Middleware struct {
MinContentLength int64 // inclusive
MaxContentLength int64 // inclusive

Accepts []string // content types that are accepted
}

func (m *Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.ContentLength <= m.MinContentLength || r.ContentLength >= m.MaxContentLength {
tmpl := `{"error": "content length is not acceptable", "given": [[GIVEN]], "min": [[MIN]], "max": [[MAX]]}`

w.Header().Set("Content-Type", "application/json")
w.Header().Set("X-Content-Type-Options", "nosniff")
w.WriteHeader(http.StatusBadRequest)

w.Write(
T(tmpl, F{
"GIVEN": strconv.FormatInt(r.ContentLength, 10),
"MIN": strconv.FormatInt(m.MinContentLength, 10),
"MAX": strconv.FormatInt(m.MaxContentLength, 10),
}),
)
return
}
}
32 changes: 32 additions & 0 deletions flathttp/middleware_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package flathttp

import (
"bytes"
"github.com/stretchr/testify/require"
"net/http"
"net/http/httptest"
"testing"
)

func TestContentLength(t *testing.T) {
cases := []struct {
given, min, max int64
err bool
}{
{given: 10, min: 10, max: 100, err: true},
{given: 100, min: 10, max: 100, err: true},
{given: 11, min: 10, max: 100},
{given: 99, min: 10, max: 100},
}

for _, test := range cases {
m := &Middleware{MinContentLength: test.min, MaxContentLength: test.max}

w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/", bytes.NewReader(make([]byte, test.given)))
m.ServeHTTP(w, r)

check := (test.err && w.Code == http.StatusBadRequest) || (!test.err && w.Code == http.StatusOK)
require.True(t, check)
}
}
13 changes: 6 additions & 7 deletions flathttp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type Server struct {

lns map[string]net.Listener // all listeners
wg sync.WaitGroup // all served goroutines
lm sync.Mutex // lifecycle mutex\
lm sync.Mutex // lifecycle mutex
em sync.Mutex // errors mutex
errs []string // errors
}
Expand Down Expand Up @@ -83,13 +83,12 @@ func (s *Server) start() error {

for _, a := range addrs {
err := s.listen(a)
if err == nil {
continue
}
if errors.Is(err, ErrAlreadyListening) {
continue
if err != nil {
if errors.Is(err, ErrAlreadyListening) {
continue
}
return err
}
return err
}

return nil
Expand Down
23 changes: 23 additions & 0 deletions flathttp/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package flathttp

import (
"github.com/valyala/fasttemplate"
"reflect"
"unsafe"
)

type F map[string]interface{}

func T(tmpl string, fields F) []byte {
return B(fasttemplate.ExecuteString(tmpl, "[[", "]]", fields))
}

func B(s string) []byte {
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
bh := reflect.SliceHeader{
Data: sh.Data,
Len: sh.Len,
Cap: sh.Len,
}
return *(*[]byte)(unsafe.Pointer(&bh))
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ module github.com/lithdew/flatend
go 1.14

require (
github.com/davecgh/go-spew v1.1.0
github.com/stretchr/testify v1.4.0
github.com/tidwall/gjson v1.6.0 // indirect
github.com/tidwall/sjson v1.1.1
github.com/valyala/fasttemplate v1.1.0
go.uber.org/goleak v1.0.0
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8=
github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/sjson v1.1.1 h1:7h1vk049Jnd5EH9NyzNiEuwYW4b5qgreBbqRC19AS3U=
github.com/tidwall/sjson v1.1.1/go.mod h1:yvVuSnpEQv5cYIrO+AT6kw4QVfd5SDZoGIS7/5+fZFs=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo=
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
Expand Down

0 comments on commit 5e30c01

Please sign in to comment.