Skip to content

Commit

Permalink
[TT-6024] Return error when GoPlugin handler is nil (#4922)
Browse files Browse the repository at this point in the history
When GoPlugin load fails during API load, its handler is set as `nil`.
The gateway should stop and return error when the API is called instead
of skipping to other middlewares.

Fixes #4469
  • Loading branch information
furkansenharputlu authored Mar 31, 2023
1 parent bb6b882 commit 96543f2
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
6 changes: 1 addition & 5 deletions gateway/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,8 @@ func (gw *Gateway) createMiddleware(actualMW TykMiddleware) func(http.Handler) h

err, errCode := mw.ProcessRequest(w, r, mwConf)
if err != nil {
// GoPluginMiddleware are expected to send response in case of error
// but we still want to record error
_, isGoPlugin := actualMW.(*GoPluginMiddleware)

handler := ErrorHandler{*mw.Base()}
handler.HandleError(w, r, err.Error(), errCode, !isGoPlugin)
handler.HandleError(w, r, err.Error(), errCode, true)

meta["error"] = err.Error()

Expand Down
6 changes: 6 additions & 0 deletions gateway/mw_go_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gateway

import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"net/http"
Expand Down Expand Up @@ -181,9 +182,14 @@ func (m *GoPluginMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Reque
if pluginMw, found := m.goPluginFromRequest(r); found {
logger = pluginMw.logger
handler = pluginMw.handler
} else {
return nil, http.StatusOK // next middleware
}
}

if handler == nil {
respCode = http.StatusInternalServerError
err = errors.New(http.StatusText(respCode))
return
}

Expand Down
43 changes: 43 additions & 0 deletions goplugin/mw_go_plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,3 +452,46 @@ func TestGoPluginAPIandPerPath(t *testing.T) {
}...)
})
}

func TestGoPluginMiddleware_ProcessRequest_ShouldFailWhenNotLoaded(t *testing.T) {
ts := gateway.StartTest(nil)
defer ts.Close()

api := ts.Gw.BuildAndLoadAPI(func(spec *gateway.APISpec) {
spec.Proxy.ListenPath = "/"
spec.UseKeylessAccess = false
spec.CustomPluginAuthEnabled = true
spec.CustomMiddleware.Driver = apidef.GoPluginDriver
spec.CustomMiddleware.AuthCheck.Name = "my-auth"
spec.CustomMiddleware.AuthCheck.Path = "auth.so"
})[0]

_, _ = ts.Run(t, test.TestCase{
Path: "/get", Code: http.StatusInternalServerError, BodyMatch: http.StatusText(http.StatusInternalServerError),
})

t.Run("path level", func(t *testing.T) {
api.CustomPluginAuthEnabled = false
api.UseKeylessAccess = true

v := api.VersionData.Versions["v1"]
v.UseExtendedPaths = true
v.ExtendedPaths = apidef.ExtendedPathsSet{
GoPlugin: []apidef.GoPluginMeta{
apidef.GoPluginMeta{
Path: "/my-plugin",
Method: http.MethodGet,
PluginPath: "non-existing.so",
SymbolName: "NonExistingPlugin",
},
},
}
api.VersionData.Versions["v1"] = v
ts.Gw.LoadAPI(api)

_, _ = ts.Run(t, []test.TestCase{
{Path: "/get", Code: http.StatusOK},
{Path: "/my-plugin", Code: http.StatusInternalServerError, BodyMatch: http.StatusText(http.StatusInternalServerError)},
}...)
})
}

0 comments on commit 96543f2

Please sign in to comment.