Heim  >  Artikel  >  Backend-Entwicklung  >  Panik wegen ungültigem Knotentyp bei der Implementierung des Plugins für KrakenD

Panik wegen ungültigem Knotentyp bei der Implementierung des Plugins für KrakenD

WBOY
WBOYnach vorne
2024-02-09 10:21:091057Durchsuche

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

php-Editor Baicao stellt Ihnen heute ein häufiges Problem bei der KrakenD-Plug-in-Entwicklung vor: „Ungültige Knotentyp-Panik bei der Implementierung von Plug-ins für KrakenD“. KrakenD ist ein schnelles, leistungsstarkes API-Gateway, das umfassende Funktionalität und ein flexibles Plug-in-System bietet. Bei der Entwicklung eines KrakenD-Plugins stößt man jedoch manchmal auf das Problem ungültiger Knotentypen, was dazu führen kann, dass das Plug-in nicht ordnungsgemäß funktioniert. In diesem Artikel werden wir die Ursachen dieses Problems sowie Lösungen untersuchen, die Entwicklern helfen, diese Panik zu überwinden.

Frageninhalt

Ich entwickle ein Plugin ohne Weiterleitungen. Ich verwende Krakend-ce 2.2.1 (mit Golang 1.19) und gerate in Panik:

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)

Sieht ähnlich aus wie https://github.com/gin-gonic/gin/issues/2959, aber die Version von Gin wurde gegenüber der vorherigen Version von Krakend aktualisiert. Es wäre komisch, wenn es wirklich Großbuchstaben wären, es funktioniert perfekt ohne das Plugin. Den letzten habe ich auch gekürzt / (er wurde irgendwann aus irgendeinem Grund hinzugefügt)

Übrigens verwende ich dieselbe Version von Krakend, um das Plugin zu kompilieren.

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
}

Mein Endpunkt ist wie folgt definiert:

{
     "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
   }]
}

BEARBEITEN: Mein Browser zeigt immer noch /abc/ anstelle von /abc an, was zu möglichen Kollisionen zwischen Routen führen könnte (wie hier zu sehen: https://github.com/krakendio/krakend-ce/issues/386). Jedenfalls nicht Ich weiß, wo ich den Schrägstrich einfügen muss (ich dachte, ich hätte ihn dauerhaft gekürzt ... anscheinend habe ich es nicht getan)

edit2: Ich habe dies https://www.krakend.io/docs/service-settings/router-options/ gefunden und „disable_redirect_fixed_path“ verwendet: true und „disable_redirect_trailing_slash“: wahr, es gerät nicht mehr in Panik ... jetzt habe ich ein anderes Problem: unendliche Weiterleitungen (nur 10, nur ein Scherz), wenn mein Felsbrocken versucht, nach /a/ oder irgendetwas mit einer abschließenden Schrägstrichroute umzuleiten im Plugin, weil Krakend Weiterleitungen auf seine eigene Art und Weise handhabte...

Ich denke, das Hauptproblem hier ist ein Routing-Konflikt, wenn /{level1} und /{level1}/{level2} gleichzeitig mit /abc/ übereinstimmen

Ideen?

Workaround

ist gut, um dieses Problem zu lösen, habe ich versucht, ein Wildcard+no_redirect-Plugin mit dieser https://www.php.cn/link/ba530cdf0a884348613f2aaa3a5ba5e8 Konfiguration zu erstellen, aber selbst mit copilot&gpt4 bin ich gescheitert, das kann ich Ihnen sagen um das zu erreichen. Also habe ich das Problem auf andere Weise gelöst: Ich habe das Gateway vor meinen Felsbrocken gestellt und jedes Mal, wenn die Anfrage fehlschlug, die Route hinzugefügt ... weil wir keine protokollierte Route hatten (*schluchzt). Es funktioniert einwandfrei für Dateien, die ein umleitungsfreies Plugin erfordern. Eine tolle Lösung, aber sie hat bisher funktioniert und nicht so lange, wie ich dachte

Das obige ist der detaillierte Inhalt vonPanik wegen ungültigem Knotentyp bei der Implementierung des Plugins für KrakenD. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen