apache / apisix-java-plugin-runner

APISIX Plugin Runner in Java
https://apisix.apache.org/
Apache License 2.0
128 stars 95 forks source link

request help: how can i get custom request headers in the ext-plugin-post-resp? #217

Closed dev-Wang closed 1 year ago

dev-Wang commented 1 year ago

Issue description

In order to refresh user's jwt token, i tried to call keycloak to get a new token, then i set it into the ext-plugin-post-req's HttpResponse, but it will stop the request. so I try to use pre-req plugin and post-resp plugin to deliver the token by request headers, firstly i set the token into the pre-req plugin and expect to get it in the PostRequest.getUpstreamHeaders() so i can set it into the PostResponse. however i can't get the new token by this function. could you help me? thanks.

tzssangglass commented 1 year ago

PostRequest.getUpstreamHeaders()

Get the headers returned from the upstream

  1. we can get request headers in filter function by ext-plugin-pre-req
  2. keep request headers as internal variables
  3. use internal variables in postFilter by ext-plugin-post-resp
dev-Wang commented 1 year ago

PostRequest.getUpstreamHeaders()

Get the headers returned from the upstream

  1. we can get request headers in filter function by ext-plugin-pre-req
  2. keep request headers as internal variables
  3. use internal variables in postFilter by ext-plugin-post-resp

Although i can get the token in the ext-plugin-post-resp by this way, but i can't ensure the token delivered to the ext-plugin-post-resp meet my expectation. Users can send request at the same time. in this situation, how can i ensure a pair of request-response in a filter chain? eg: i've enabled ext-plugin-pre-req and ext-plugin-post-resp, user A and user B call a interface at the same time, postFilter function will be called twice. now i take two tokens, how to distinguish the token whether belongs to user A or B? i've tried to get requestId but the requestId in request is different from response.

tzssangglass commented 1 year ago

for customrequest headers, we can register vars in requiredVars, the header is start with http_, for example:

java code

package com.example.demo;

import java.util.ArrayList;
import java.util.List;
import org.apache.apisix.plugin.runner.PostRequest;
import org.apache.apisix.plugin.runner.PostResponse;
import org.apache.apisix.plugin.runner.filter.PluginFilter;
import org.apache.apisix.plugin.runner.filter.PluginFilterChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class DemoFilter implements PluginFilter {
    private final Logger logger = LoggerFactory.getLogger(DemoFilter.class);

    @Override
    public String name() {
        return "DemoFilter";
    }

    @Override
    public void postFilter(PostRequest request, PostResponse response, PluginFilterChain chain) {
        logger.warn("DemoFilter is running");
        String http_x_test = request.getVars("http_x_test");
        logger.warn("http_x_test: {}", http_x_test);
        chain.postFilter(request, response);
    }

    /**
     * If you need to fetch some Nginx variables in the current plugin, you will need to declare them in this function.
     * @return a list of Nginx variables that need to be called in this plugin
     */
    @Override
    public List<String> requiredVars() {
        List<String> vars = new ArrayList<>();
        vars.add("http_x_test");
        return vars;
    }
}

add route

curl -i http://127.0.0.1:9180/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "uri": "/get",
    "plugins": {
        "ext-plugin-post-resp": {
            "conf" : [
                {"name": "DemoFilter", "value": "{\"enable\":\"feature\"}"}
            ]
        }
    },
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "httpbin.org:80": 1
        }
    }
}'

hit route

curl http://127.0.0.1:9080/get -H "X-TEST: hello"

in java runner, we can get

2022-12-05 12:48:20.154  WARN 89108 --- [ntLoopGroup-2-2] c.e.d.DemoFilter                         : http_x_test: hello
dev-Wang commented 1 year ago

thanks, i've tried your solution. but when i called a service endpoint, an exception was thrown. 94dade3ad1556f901ac8cb846d2949b failed to receive RPC HTTP RESP CALL: unexpected type 3,client: 172.22.0.1 what do this mean?

tzssangglass commented 1 year ago

try with v.0.4.0

dev-Wang commented 1 year ago

it works! thank you so much!