Skip to content

Commit

Permalink
Inspect wrapped handlers in Mount (#86)
Browse files Browse the repository at this point in the history
  • Loading branch information
vearutop authored Jul 22, 2022
1 parent c1989ca commit 0f5ebfc
Show file tree
Hide file tree
Showing 9 changed files with 247 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
test:
strategy:
matrix:
go-version: [ 1.17.x, 1.18.x ]
go-version: [1.18.x ]
runs-on: ubuntu-latest
steps:
- name: Install Go stable
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/test-unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,10 @@ jobs:
id: annotate
if: matrix.go-version == env.COV_GO_VERSION && github.event.pull_request.base.sha != ''
run: |
curl -sLO https://github.com/vearutop/gocovdiff/releases/download/v1.3.6/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz
gocovdiff_hash=$(git hash-object ./gocovdiff)
[ "$gocovdiff_hash" == "8e507e0d671d4d6dfb3612309b72b163492f28eb" ] || (echo "::error::unexpected hash for gocovdiff, possible tampering: $gocovdiff_hash" && exit 1)
git fetch origin master ${{ github.event.pull_request.base.sha }}
curl -sLO https://github.com/vearutop/gocovdiff/releases/download/v1.3.4/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz && shasum -a 256 gocovdiff && echo "b351c67526eefeb0671c82e9271ae984875865eed19e911f40f78348cb98347c gocovdiff" | shasum -c
REP=$(./gocovdiff -cov unit.coverprofile -gha-annotations gha-unit.txt -delta-cov-file delta-cov-unit.txt -target-delta-cov ${TARGET_DELTA_COV})
echo "${REP}"
REP="${REP//$'\n'/%0A}"
Expand Down
10 changes: 4 additions & 6 deletions _examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ replace github.com/swaggest/rest => ../

require (
github.com/bool64/ctxd v1.1.2
github.com/bool64/dev v0.2.16
github.com/bool64/httpmock v0.1.1
github.com/bool64/dev v0.2.18
github.com/bool64/httpmock v0.1.6
github.com/bool64/httptestbench v0.1.3
github.com/go-chi/chi/v5 v5.0.7
github.com/kelseyhightower/envconfig v1.4.0
github.com/rs/cors v1.8.2
github.com/stretchr/testify v1.7.2
github.com/stretchr/testify v1.8.0
github.com/swaggest/assertjson v1.7.0
github.com/swaggest/jsonschema-go v0.3.35
github.com/swaggest/openapi-go v0.2.18
Expand All @@ -25,7 +25,7 @@ require github.com/swaggest/rest v0.0.0-00010101000000-000000000000

require (
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/bool64/shared v0.1.4 // indirect
github.com/bool64/shared v0.1.5 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
Expand All @@ -41,8 +41,6 @@ require (
github.com/yosuke-furukawa/json5 v0.1.2-0.20201207051438-cf7bb3f354ff // indirect
github.com/yudai/gojsondiff v1.0.0 // indirect
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
25 changes: 13 additions & 12 deletions _examples/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ github.com/bool64/ctxd v1.1.2 h1:6J05q1vTG0op2O0kP+LosCd9wJ0qJybcvdE+bPjUJZE=
github.com/bool64/ctxd v1.1.2/go.mod h1:5rwLykeZBJHK27q5sSfhfKig6076270V+3iiXbP+HFY=
github.com/bool64/dev v0.1.35/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU=
github.com/bool64/dev v0.1.41/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU=
github.com/bool64/dev v0.2.5/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU=
github.com/bool64/dev v0.2.16 h1:ZlybgWWXmHGMojqIjDrtl5QF6jmE4hNeojE00nioVk0=
github.com/bool64/dev v0.2.16/go.mod h1:/csLrm+4oDSsKJRIVS0mrywAonLnYKFG8RvGT7Jh9b8=
github.com/bool64/httpmock v0.1.1 h1:jpqM0S8efvJfN7Uy5fBUJKu2C640/ZS0yboxpeyVwm0=
github.com/bool64/httpmock v0.1.1/go.mod h1:Ju7xrs8gVyxANbgIxoxX4Pkj1uHygzPEpGEnfqct+gA=
github.com/bool64/dev v0.2.18 h1:FPXZxR4+bgNgBKtORwCr7W/s46bY/LkKFwVy8f63cqI=
github.com/bool64/dev v0.2.18/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg=
github.com/bool64/httpmock v0.1.6 h1:v9+AmoSabaHuR7abjnhGwGxsaNljtFAYtluF0p4Q3ng=
github.com/bool64/httpmock v0.1.6/go.mod h1:pQukYUfoG9gW4fRAv+xHuvA2BlRoauEXK/XG5mKD04I=
github.com/bool64/httptestbench v0.1.3 h1:bPDM3YPtE3o2sqIwjhdTC55wiqwfHsqps2RGcWBesuo=
github.com/bool64/httptestbench v0.1.3/go.mod h1:3SoL5hfGcPylcOVSEF2+jJC8VG0oKMHlZYRoliBKbzE=
github.com/bool64/shared v0.1.4 h1:zwtb1dl2QzDa9TJOq2jzDTdb5IPf9XlxTGKN8cySWT0=
github.com/bool64/shared v0.1.4/go.mod h1:ryGjsnQFh6BnEXClfVlEJrzjwzat7CmA8PNS5E+jPp0=
github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E=
github.com/bool64/shared v0.1.5/go.mod h1:081yz68YC9jeFB3+Bbmno2RFWvGKv1lPKkMP6MHJlPs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -49,9 +48,11 @@ github.com/santhosh-tekuri/jsonschema/v3 v3.1.0/go.mod h1:8kzK2TC0k0YjOForaAHdNE
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/swaggest/assertjson v1.7.0 h1:SKw5Rn0LQs6UvmGrIdaKQbMR1R3ncXm5KNon+QJ7jtw=
github.com/swaggest/assertjson v1.7.0/go.mod h1:vxMJMehbSVJd+dDWFCKv3QRZKNTpy/ktZKTz9LOEDng=
github.com/swaggest/form/v5 v5.0.1 h1:YQH0REX7iMKhtoVPWXREZgbt50VYXNCKK61psnD8Fgo=
Expand Down Expand Up @@ -82,15 +83,15 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDf
github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220630215102-69896b714898 h1:K7wO6V1IrczY9QOQ2WkVpw4JQSwCd52UsxVEirZUfiw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220702020025-31831981b65f h1:xdsejrW/0Wf2diT5CPp3XmKUNbr7Xvw8kYilQ+6qjRY=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand All @@ -101,10 +102,10 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
64 changes: 64 additions & 0 deletions _examples/mount/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package main

import (
"context"
"fmt"
"log"
"net/http"

"github.com/go-chi/chi/v5/middleware"
"github.com/swaggest/rest/nethttp"
"github.com/swaggest/rest/web"
swgui "github.com/swaggest/swgui/v4emb"
"github.com/swaggest/usecase"
)

func mul() usecase.Interactor {
return usecase.NewInteractor(func(ctx context.Context, input []int, output *int) error {
*output = 1

for _, v := range input {
*output *= v
}

return nil
})
}

func sum() usecase.Interactor {
return usecase.NewInteractor(func(ctx context.Context, input []int, output *int) error {
for _, v := range input {
*output += v
}

return nil
})
}

func main() {
service := web.DefaultService()
service.OpenAPI.Info.Title = "Security and Mount Example"

apiV1 := web.DefaultService()

apiV1.Wrap(
middleware.BasicAuth("Admin Access", map[string]string{"admin": "admin"}),
nethttp.HTTPBasicSecurityMiddleware(service.OpenAPICollector, "Admin", "Admin access"),
)

apiV1.Post("/sum", sum())
apiV1.Post("/mul", mul())

service.Mount("/api/v1", apiV1)
service.Docs("/api/v1/docs", swgui.New)

// Blanket handler, for example to serve static content.
service.Mount("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("blanket handler got a request: " + r.URL.String()))
}))

fmt.Println("Swagger UI at http://localhost:8010/api/v1/docs.")
if err := http.ListenAndServe("localhost:8010", service); err != nil {
log.Fatal(err)
}
}
39 changes: 34 additions & 5 deletions chirouter/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"

"github.com/go-chi/chi/v5"
"github.com/swaggest/rest"
"github.com/swaggest/rest/nethttp"
)

Expand All @@ -25,6 +26,7 @@ type Wrapper struct {

middlewares []func(http.Handler) http.Handler
wraps []func(http.Handler) http.Handler
handlers []http.Handler
}

var _ chi.Router = &Wrapper{}
Expand Down Expand Up @@ -89,8 +91,27 @@ func (r *Wrapper) Route(pattern string, fn func(r chi.Router)) chi.Router {

// Mount attaches another http.Handler along "./basePattern/*".
func (r *Wrapper) Mount(pattern string, h http.Handler) {
h = r.prepareHandler("", pattern, h)
r.captureHandler(h)
if hr, ok := h.(interface {
handlersWithRoute() []http.Handler
handlerWraps() []func(http.Handler) http.Handler
}); ok {
pattern = strings.TrimSuffix(pattern, "/")

for _, h := range hr.handlersWithRoute() {
var rh rest.HandlerWithRoute
if nethttp.HandlerAs(h, &rh) {
m := rh.RouteMethod()
p := r.resolvePattern(pattern + rh.RoutePattern())
h := nethttp.WrapHandler(h, nethttp.HandlerWithRouteMiddleware(m, p))
h = nethttp.WrapHandler(h, hr.handlerWraps()...)
_ = nethttp.WrapHandler(h, r.wraps...)
}
}
} else {
h = r.prepareHandler("", pattern, h)
r.captureHandler(h)
}

r.Router.Mount(pattern, h)
}

Expand Down Expand Up @@ -167,9 +188,17 @@ func (r *Wrapper) captureHandler(h http.Handler) {
}

func (r *Wrapper) prepareHandler(method, pattern string, h http.Handler) http.Handler {
mw := r.wraps
mw = append(mw, nethttp.HandlerWithRouteMiddleware(method, r.resolvePattern(pattern)))
h = nethttp.WrapHandler(h, mw...)
h = nethttp.WrapHandler(h, nethttp.HandlerWithRouteMiddleware(method, r.resolvePattern(pattern)))
r.handlers = append(r.handlers, h)
h = nethttp.WrapHandler(h, r.wraps...)

return h
}

func (r *Wrapper) handlersWithRoute() []http.Handler {
return r.handlers
}

func (r *Wrapper) handlerWraps() []func(http.Handler) http.Handler {
return r.wraps
}
102 changes: 102 additions & 0 deletions chirouter/wrapper_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package chirouter_test

import (
"bytes"
"context"
"errors"
"net/http"
"net/http/httptest"
"net/url"
Expand All @@ -10,9 +13,12 @@ import (
"github.com/go-chi/chi/v5/middleware"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/swaggest/assertjson"
"github.com/swaggest/rest"
"github.com/swaggest/rest/chirouter"
"github.com/swaggest/rest/nethttp"
"github.com/swaggest/rest/web"
"github.com/swaggest/usecase"
)

type HandlerWithFoo struct {
Expand Down Expand Up @@ -254,3 +260,99 @@ func TestWrapper_Use_StripSlashes(t *testing.T) {
"h", "h",
}, log)
}

func TestWrapper_Mount(t *testing.T) {
service := web.DefaultService()
service.OpenAPI.Info.Title = "Security and Mount Example"

apiV1 := web.DefaultService()

apiV1.Wrap(
middleware.BasicAuth("Admin Access", map[string]string{"admin": "admin"}),
nethttp.HTTPBasicSecurityMiddleware(service.OpenAPICollector, "Admin", "Admin access"),
)

apiV1.Post("/sum", usecase.NewIOI(new([]int), new(int), func(ctx context.Context, input, output interface{}) error {
return errors.New("oops")
}))

service.Mount("/api/v1", apiV1)

// Blanket handler, for example to serve static content.
service.Mount("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("blanket handler got a request: " + r.URL.String()))
assert.NoError(t, err)
}))

req, err := http.NewRequest(http.MethodGet, "/foo", nil)
require.NoError(t, err)

rw := httptest.NewRecorder()
service.ServeHTTP(rw, req)

assert.Equal(t, "blanket handler got a request: /foo", rw.Body.String())

req, err = http.NewRequest(http.MethodPost, "/api/v1/sum", bytes.NewBufferString(`[1,2,3]`))
require.NoError(t, err)

rw = httptest.NewRecorder()

service.ServeHTTP(rw, req)
assert.Equal(t, http.StatusUnauthorized, rw.Code)

req.Header.Set("Authorization", "Basic YWRtaW46YWRtaW4=")

rw = httptest.NewRecorder()

service.ServeHTTP(rw, req)
assert.Equal(t, `{"error":"oops"}`+"\n", rw.Body.String())

assertjson.EqualMarshal(t, []byte(`{
"openapi":"3.0.3","info":{"title":"Security and Mount Example","version":""},
"paths":{
"/api/v1/sum":{
"post":{
"summary":"Test Wrapper _ Mount",
"operationId":"rest/chirouter_test.TestWrapper_Mount",
"requestBody":{
"content":{
"application/json":{
"schema":{"type":"array","items":{"type":"integer"},"nullable":true}
}
}
},
"responses":{
"200":{
"description":"OK",
"content":{"application/json":{"schema":{"type":"integer"}}}
},
"401":{
"description":"Unauthorized",
"content":{
"application/json":{"schema":{"$ref":"#/components/schemas/RestErrResponse"}}
}
}
},
"security":[{"Admin":[]}]
}
}
},
"components":{
"schemas":{
"RestErrResponse":{
"type":"object",
"properties":{
"code":{"type":"integer","description":"Application-specific error code."},
"context":{
"type":"object","additionalProperties":{},
"description":"Application context."
},
"error":{"type":"string","description":"Error message."},
"status":{"type":"string","description":"Status text."}
}
}
},
"securitySchemes":{"Admin":{"type":"http","scheme":"basic","description":"Admin access"}}
}
}`), service.OpenAPI)
}
Loading

0 comments on commit 0f5ebfc

Please sign in to comment.