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

bug: ext-plugin-post-resp can't get duplicate headers from upstream response, such as Set-Cookie #262

Open
youth-lee opened this issue Aug 20, 2023 · 1 comment

Comments

@youth-lee
Copy link

youth-lee commented Aug 20, 2023

Environment

  • 0.4.0

Steps to reproduce the issue

  1. use ext-plugin-post-resp postFilter(PostRequest request, PostResponse response, PluginFilterChain chain)
  2. use request.getUpstreamHeaders() to get headers
  3. upstream response
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Sat, 19-Aug-2023 05:45:05 GMT
Set-Cookie: JSESSIONID=deleteMe; Path=/; Max-Age=0; Expires=Sat, 19-Aug-2023 05:45:05 GMT
Set-Cookie: JSESSIONID=0bc8714b-e1bf-4077-baaa-b94c8ba10a05; Path=/; HttpOnly
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Sat, 19-Aug-2023 05:45:05 GMT

What's the actual result? (including assertion message & call stack if applicable)

just get the last Set-Cookie item Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Sat, 19-Aug-2023 05:45:05 GMT

What's the expected result?

  1. can get duplicate headers with Multimap data structure
  2. can set duplicate headers

One more thing!

It is recommended that ext-plugin-post-resp inherits all the headers of upstream by default, so you don't need to write them again in the plugin.

eg:

  1. upstream return content-type = text/html
  2. empty code in postFilter(PostRequest request, PostResponse response, PluginFilterChain chain)
  3. the client get content-type = text/pain
@gaoxingliang
Copy link

@youth-lee As a workaround you can refer to the code in: https://github.com/gaoxingliang/apisix-java-plugin-runner/blob/encrypt-response/runner-plugin-sdk/src/main/java/org/apache/apisix/plugin/runner/PostRequest.java#L88

I added one method to return a map of list values.
and then in the filter: https://github.com/gaoxingliang/apisix-java-plugin-runner/blob/encrypt-response/runner-starter/src/main/java/org/apache/apisix/plugin/runner/EncryptResponseFilter.java#L30
it will get the upstream response headers correctly.

If you donot want to change the code, you can do the java reflect in your code and get the req and do the parse.

The below code is an example in python to add two headers:

from http.server import BaseHTTPRequestHandler, HTTPServer

class CustomRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.send_header('Custom-Header', 'Custom Value')
        self.send_header('header1', 'v1')
        self.send_header('header1', 'v2')
        self.end_headers()
        
        response = '{"message": "Hello, world!"}'
        self.wfile.write(response.encode('utf-8'))

def run_server():
    host = '0.0.0.0'
    port = 8100
    
    server = HTTPServer((host, port), CustomRequestHandler)
    server.serve_forever()

if __name__ == '__main__':
    run_server()

and below is the log it printed:

 2023-09-22 06:10:35,919 INFO  epollEventLoopGroup-2-2          - req headers: {Content-type=application/json, header1=v2, Custom-Header=Custom Value, Server=BaseHTTP/0.6 Python/3.6.8, Date=Fri, 22 Sep 2023 06:10:35 GMT}
 2023-09-22 06:10:35,920 INFO  epollEventLoopGroup-2-2          - req headers map:{Content-type=[application/json], header1=[v1, v2], Server=[BaseHTTP/0.6 Python/3.6.8], Custom-Header=[Custom Value], Date=[Fri, 22 Sep 2023 06:10:35 GMT]}

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

No branches or pull requests

2 participants