L'éditeur php Baicao vous présente aujourd'hui un problème courant dans le développement du plug-in KrakenD : "Panique de type de nœud invalide lors de l'implémentation des plug-ins pour KrakenD". KrakenD est une passerelle API rapide et hautes performances qui offre des fonctionnalités riches et un système de plug-in flexible. Cependant, lors du développement d'un plug-in KrakenD, vous rencontrez parfois le problème de types de nœuds non valides, ce qui peut empêcher le plug-in de fonctionner correctement. Dans cet article, nous explorerons les causes de ce problème ainsi que des solutions pour aider les développeurs à surmonter cette panique.
Je développe un plugin sans redirections. J'utilise krakend-ce 2.2.1 (en utilisant golang 1.19) et je panique :
gw_krakend_1 | [krakend] 2023/03/15 - 21:09:06.675 ? debug no_redirect_plugin: request received https://127.0.0.1:8443/abc gw_krakend_1 | [krakend] 2023/03/15 - 21:09:06.689 ? debug no_redirect_plugin: redirect detected https://127.0.0.1:8443/abc gw_krakend_1 | [krakend] 2023/03/15 - 21:09:06.689 ? debug status code 302 gw_krakend_1 | 2023/03/15 21:09:06 http: panic serving [::1]:54778: invalid node type gw_krakend_1 | goroutine 84 [running]: gw_krakend_1 | net/http.(*conn).serve.func1() gw_krakend_1 | /usr/local/go/src/net/http/server.go:1854 +0xbf gw_krakend_1 | panic({0x28cbb60, 0x34b5810}) gw_krakend_1 | /usr/local/go/src/runtime/panic.go:890 +0x263 gw_krakend_1 | github.com/gin-gonic/gin.(*node).findcaseinsensitivepathrec(0x0?, {0xc0016ac2ec?, 0x0?}, {0xc0010fe800?, 0xc0016ac2ed?, 0xc000ced928?}, {0x0, 0x0, 0x0, 0x0}, ...) gw_krakend_1 | /go/pkg/mod/github.com/gin-gonic/[email protected]/tree.go:862 +0xa9d gw_krakend_1 | github.com/gin-gonic/gin.(*node).findcaseinsensitivepath(0xc0016ac2ec?, {0xc0016ac2ec, 0x5}, 0x30?) gw_krakend_1 | /go/pkg/mod/github.com/gin-gonic/[email protected]/tree.go:669 +0x9c gw_krakend_1 | github.com/gin-gonic/gin.redirectfixedpath(0xc000664300, 0xc0016ac2ec?, 0x60?) gw_krakend_1 | /go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:684 +0x5b gw_krakend_1 | github.com/gin-gonic/gin.(*engine).handlehttprequest(0xc000602b60, 0xc000664300)
Il y ressemble https://github.com/gin-gonic/gin/issues/2959, mais la version de gin a été mise à niveau par rapport à la version précédente de krakend. Ce serait bizarre s'il s'agissait vraiment de majuscules, cela fonctionne parfaitement sans le plugin. J'ai aussi coupé le dernier / (il a été ajouté à un moment donné pour une raison quelconque)
BTW, j'utilise la même version de Krakend pour compiler le plugin.
package main import ( "context" "errors" "fmt" "io" "net/http" "net/url" "strings" ) func main() {} var clientregisterer = registerer("no_redirect_plugin") type registerer string type logger interface { debug(v ...interface{}) info(v ...interface{}) warning(v ...interface{}) error(v ...interface{}) critical(v ...interface{}) fatal(v ...interface{}) } var logger logger = nil func (registerer) registerlogger(v interface{}) { l, ok := v.(logger) if !ok { return } logger = l logger.info(fmt.sprintf("[plugin: %s] logger loaded", clientregisterer)) } func (r registerer) registerclients(f func( name string, handler func(context.context, map[string]interface{}) (http.handler, error), )) { f(string(r), r.registerclients) } func (r registerer) registerclients(_ context.context, extra map[string]interface{}) (http.handler, error) { name, ok := extra["name"].(string) if !ok { return nil, errors.new("wrong config") } if name != string(r) { return nil, fmt.errorf("unknown register %s", name) } httpclient := &http.client{ checkredirect: func(req *http.request, via []*http.request) error { // trim the last "/" character from the url if it exists urlstr := strings.trimright(req.url.string(), "/") req.url, _ = url.parse(urlstr) logger.debug("no_redirect_plugin: redirect detected", req.url.string()) return http.erruselastresponse }, } return http.handlerfunc(func(w http.responsewriter, req *http.request) { // trim the last "/" character from the url if it exists urlstr := strings.trimright(req.url.string(), "/") req.url, _ = url.parse(urlstr) logger.debug("no_redirect_plugin: request received", req.url.string()) resp, err := httpclient.do(req) if err != nil { logger.debug("error while proxying request", err.error()) http.error(w, err.error(), http.statusinternalservererror) return } defer resp.body.close() for k, hs := range resp.header { for _, h := range hs { w.header().add(k, h) } } w.writeheader(resp.statuscode) logger.debug("status code", resp.statuscode) if resp.body == nil { return } _, err = io.copy(w, resp.body) if err != nil { logger.debug("error while proxying request 2", err.error()) http.error(w, err.error(), http.statusinternalservererror) return } }), nil }
Mon point de terminaison est défini comme suit :
{ "endpoint": "/", "input_headers":[ "*" ], "input_query_strings":[ "*" ], "method": "GET", "output_encoding": "no-op", "extra_config": {}, "backend": [{ "url_pattern": "", "encoding": "no-op", "sd": "static", "method": "GET", "extra_config": { "plugin/http-client": { "name": "no_redirect_plugin" } }, "host": [ "{{ env "HOST" }}" ], "disable_host_sanitize": false }] },{ "endpoint": "/{level1}", "input_headers":[ "*" ], "input_query_strings":[ "*" ], "method": "GET", "output_encoding": "no-op", "extra_config": { }, "backend": [{ "url_pattern": "/{level1}", "encoding": "no-op", "sd": "static", "method": "GET", "extra_config": { "plugin/http-client": { "name": "no_redirect_plugin" } }, "host": [ "{{ env "HOST" }}" ], "disable_host_sanitize": false }] },{ "endpoint": "/{level1}/{level2}", "input_headers":[ "*" ], "input_query_strings":[ "*" ], "method": "GET", "output_encoding": "no-op", "extra_config": { }, "backend": [{ "url_pattern": "/{level1}/{level2}", "encoding": "no-op", "sd": "static", "method": "GET", "extra_config": { "plugin/http-client": { "name": "no_redirect_plugin" } }, "host": [ "{{ env "HOST" }}" ], "disable_host_sanitize": false }] }
EDIT : Mon navigateur affiche toujours /abc/ au lieu de /abc, ce qui pourrait créer d'éventuelles collisions entre les routes (comme vu ici : https://github.com/krakendio/krakend-ce/issues/386 ) Quoi qu'il en soit, je ne le fais pas je sais où ajouter la barre oblique (je pensais l'avoir coupée de façon permanente... on dirait que non)
edit2 : j'ai trouvé ceci https://www.krakend.io/docs/service-settings/router-options/ et utilisé "disable_redirect_fixed_path": true et "disable_redirect_trailing_slash" : vrai, ça ne panique plus... Maintenant j'ai un autre problème : des redirections infinies (juste 10 je plaisante) quand mon rocher essaie de rediriger vers /a/ ou quoi que ce soit avec une route slash finale, c'est dans le plugin car krakend gérait les redirections à sa manière...
Je suppose que le principal problème ici est le conflit de routage, lorsque /{level1} et /{level1}/{level2} correspondent à /abc/ en même temps
Des idées ?
est bonne, pour résoudre ce problème j'ai essayé de créer un plugin wildcard+no_redirect en utilisant cette //m.sbmmt.com/link/ba530cdf0a884348613f2aaa3a5ba5e8 configuration, mais même avec copilot&gpt4 j'ai échoué, je vous défie pour y parvenir. J'ai donc résolu le problème d'une autre manière : j'ai placé la passerelle devant mon rocher et à chaque fois que la requête échouait, j'ajoutais l'itinéraire... parce que nous n'avions pas d'itinéraire enregistré (*sanglots). Cela fonctionne très bien pour les fichiers nécessitant un plugin sans redirection. Une excellente solution mais elle a fonctionné jusqu'à présent et pas aussi longtemps que je le pensais
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!