Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate header key leads to 500 error for a route with Go plugin trying to fetch request headers #8734

Closed
1 task done
orangejohny opened this issue Apr 28, 2022 · 0 comments · Fixed by #8891
Closed
1 task done

Comments

@orangejohny
Copy link

orangejohny commented Apr 28, 2022

Is there an existing issue for this?

  • I have searched the existing issues

Kong version ($ kong version)

2.8.1

Current Behavior

I have a plugin written in Go that calls kong.Request.GetHeaders(-1) during Access phase.

When making a request to route with enabled plugin Kong returns 500 HTTP error:

$ curl -v --location --request GET 'http://localhost:8000/SuiteHeadersKey/get' \
--header 'X-Test-H: 123' \
--header 'X-Test-H: 567'
Note: Unnecessary use of -X or --request, GET is already inferred.
*   Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /SuiteHeadersKey/get HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.79.1
> Accept: */*
> X-Test-H: 123
> X-Test-H: 567
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 500 Internal Server Error
< Date: Thu, 28 Apr 2022 13:46:30 GMT
< Content-Type: application/json; charset=utf-8
< Connection: keep-alive
< Content-Length: 42
< X-Kong-Response-Latency: 0
< Server: kong/2.8.1
< 
* Connection #0 to host localhost left intact
{"message":"An unexpected error occurred"}

Kong logs show following error:

2022/04/28 13:50:38 [error] 1117#0: *375 [kong] init.lua:297 [kong-go-cache] ...cal/share/lua/5.1/kong/runloop/plugin_servers/pb_rpc.lua:259: bad argument #2 to 'encode' (string expected for field 'key', got number), client: 172.18.0.1, server: kong, request: "GET /SuiteHeadersKey/get HTTP/1.1", host: "localhost:8000"

kong.Request.GetHeaders(-1) call receives EOF error from Kong.

Expected Behavior

kong.Request.GetHeaders(-1) returns client's request headers correctly.

Kong returns response from the upstream correctly:

$ curl -v --location --request GET 'http://localhost:8000/SuiteHeadersKey/get' \
--header 'X-Test-H: 123' \
--header 'X-Test-H: 567'
Note: Unnecessary use of -X or --request, GET is already inferred.
*   Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /SuiteHeadersKey/get HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.79.1
> Accept: */*
> X-Test-H: 123
> X-Test-H: 567
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 426
< Connection: keep-alive
< Date: Thu, 28 Apr 2022 14:10:16 GMT
< Server: gunicorn/19.9.0
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< X-Kong-Upstream-Latency: 273
< X-Kong-Proxy-Latency: 2
< Via: kong/2.8.1
< 
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.79.1", 
    "X-Amzn-Trace-Id": "Root=1-626aa048-7ac54e37762209633233c3e2", 
    "X-Forwarded-Host": "localhost", 
    "X-Forwarded-Path": "/SuiteHeadersKey/get", 
    "X-Forwarded-Prefix": "/SuiteHeadersKey", 
    "X-Test-H": "123,567"
  }, 
  "origin": "172.18.0.1, 95.31.162.132", 
  "url": "http://localhost/get"
}
* Connection #0 to host localhost left intact

Steps To Reproduce

There is a plugin example for which the issue reproduces:

package main

import (
	"github.com/Kong/go-pdk/server"

	"github.com/Kong/go-pdk"
)

const Version = "1.0"
const Priority = 1

func main() {
	server.StartServer(New, Version, Priority)
}

type Config struct{}

func New() interface{} {
	return &Config{}
}

func (conf Config) Access(kong *pdk.PDK) {
	_, err := kong.Request.GetHeaders(-1)
	if err != nil {
		kong.Log.Err(err.Error())
	}
}

You need to deploy a Kong instance with this plugin included to reproduce the issue. After that follow the steps bellow.

  1. Create a service:
curl --location --request POST 'http://localhost:8001/services' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "svc",
    "url": "http://httpbin.org"
}'
  1. Create a route:
curl --location --request POST 'http://localhost:8001/services/svc/routes' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "route",
    "paths": ["/httpbin"],
    "protocols": ["http"]
}'
  1. Create a plugin:
curl --location --request POST 'http://localhost:8001/routes/route/plugins' \
--header 'Content-Type: application/json' \
--data-raw '{
    "enabled": true,
    "config": {},
    "name": "test-plugin"
}'
  1. Make a request:
curl --location --request GET 'http://localhost:8000/httpbin/get' \
--header 'X-Test-H: 123' \
--header 'X-Test-H: 567'

Anything else?

It seems that Kong plugin server receives request from the Go plugin correctly but fails to encode a result from https://github.com/Kong/kong/blob/master/kong/pdk/request.lua#L610 method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants