Maison > développement back-end > Golang > le corps du texte

Panique de type de nœud non valide lors de l'implémentation du plugin pour KrakenD

WBOY
Libérer: 2024-02-09 10:21:09
avant
1027 Les gens l'ont consulté

为 KrakenD 实现插件时无效的节点类型恐慌

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.

Contenu de la question

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)
Copier après la connexion

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
}

Copier après la connexion

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
   }]
}
Copier après la connexion

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 ?

Workaround

est bonne, pour résoudre ce problème j'ai essayé de créer un plugin wildcard+no_redirect en utilisant cette https://www.php.cn/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!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!