Rumah >pembangunan bahagian belakang >Golang >Panik jenis nod tidak sah apabila melaksanakan pemalam untuk KrakenD

Panik jenis nod tidak sah apabila melaksanakan pemalam untuk KrakenD

WBOY
WBOYke hadapan
2024-02-09 10:21:091094semak imbas

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

editor php Baicao hari ini memperkenalkan kepada anda masalah biasa dalam pembangunan pemalam KrakenD: "Panik jenis nod tidak sah apabila melaksanakan pemalam untuk KrakenD". KrakenD ialah gerbang API yang pantas dan berprestasi tinggi yang menyediakan fungsi yang kaya dan sistem pemalam yang fleksibel. Walau bagaimanapun, apabila membangunkan pemalam KrakenD, anda kadangkala menghadapi masalah jenis nod tidak sah, yang mungkin menyebabkan pemalam gagal berfungsi dengan betul. Dalam artikel ini, kami akan meneroka punca masalah ini serta penyelesaian untuk membantu pembangun mengatasi panik ini.

Kandungan soalan

Saya sedang membangunkan pemalam tanpa ubah hala. Saya menggunakan krakend-ce 2.2.1 (menggunakan golang 1.19) dan saya 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)

Kelihatan serupa dengannya https://github.com/gin-gonic/gin/issues/2959, tetapi versi gin telah dinaik taraf pada versi krakend sebelumnya. Ia akan menjadi pelik jika ia benar-benar huruf besar, ia berfungsi dengan sempurna tanpa pemalam. Saya juga memangkas yang terakhir / (ia telah ditambah pada satu ketika atas sebab tertentu)

BTW, saya menggunakan versi krakend yang sama untuk menyusun pemalam.

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
}

Titik akhir saya ditakrifkan seperti berikut:

{
     "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: Penyemak imbas saya masih menunjukkan /abc/ bukannya /abc, yang boleh mewujudkan kemungkinan perlanggaran antara laluan (seperti yang dilihat di sini: https://github.com/krakendio/krakend-ce/issues/386 ) Bagaimanapun, saya tidak tahu di mana untuk menambah garis miring (saya fikir saya memangkasnya secara kekal...nampaknya saya tidak melakukannya)

edit2: Saya menjumpai ini https://www.krakend.io/docs/service-settings/router-options/ dan menggunakan "disable_redirect_fixed_path": benar dan "disable_redirect_trailing_slash": benar, ia tidak panik lagi... Sekarang saya mempunyai masalah lain: ubah hala tidak terhingga (hanya 10 bergurau sahaja) apabila batu saya cuba mengubah hala ke /a/ atau apa-apa sahaja dengan laluan slash mengekor, ini dalam pemalam kerana krakend pernah mengendalikan ubah hala dengan cara tersendiri...

Saya rasa masalah utama di sini ialah konflik penghalaan, apabila /{level1} dan /{level1}/{level2} sepadan dengan /abc/ pada masa yang sama

Idea?

Penyelesaian

bagus, untuk menyelesaikan masalah ini, saya cuba mencipta pemalam wildcard+no_redirect menggunakan ini https://www.php.cn/link/ba530cdf0a884348613f2aaa3a5ba5e8, tetapi saya gagal konfigurasi, tetapi saya gagal untuk mencapai ini. Jadi saya menyelesaikan masalah dengan cara lain: Saya meletakkan gerbang di hadapan batu besar saya dan setiap kali permintaan gagal saya menambah laluan... kerana kami tidak mempunyai laluan log (* menangis). Ia berfungsi dengan baik untuk fail yang memerlukan pemalam tanpa ubah hala. Penyelesaian yang hebat tetapi ia telah berjaya setakat ini dan tidak seperti yang saya fikirkan

Atas ialah kandungan terperinci Panik jenis nod tidak sah apabila melaksanakan pemalam untuk KrakenD. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam