TykTechnologies / tyk

Tyk Open Source API Gateway written in Go, supporting REST, GraphQL, TCP and gRPC protocols
Other
9.68k stars 1.08k forks source link

Unable to add custom header for error responses from validation #6658

Open sm-agci opened 4 days ago

sm-agci commented 4 days ago

Branch/Environment/Version

Describe the bug We have API configuration imported to Tyk.io using OAS. In this configuration we have middleware section enabled where we specify which plugins are used for given API. We have two plugins - when requests comes in it will assign Unique-Id header with some UUID. When request does not match API swagger definition it will return 400 error. We also have second plugin which should add header when this 400 error is returned. In logs we see that plugins are fired and they add headers but response which is returned to user does not have our custom headers.

We tried to run plugin only on preRlugins or on responsePlugins or on both - it does not matter, custom headers are overriden by defaults:

HTTP/1.1 400 Bad Request Content-Type: application/json X-Generator: tyk.io Date: Tue, 22 Oct 2024 12:23:01 GMT Content-Length: 336 { "status": 400, "code": "INVALID_ARGUMENT" }

Reproduction steps Steps to reproduce the behavior: API configuration:

"middleware": {
      "global": {
        "pluginConfig": {
          "driver": "grpc"
        },
        "prePlugins": [
          {
            "enabled": true,
            "functionName": "RequestCustomHeaderMiddleware",
            "requireSession": false
          },
          {
            "enabled": true,
            "functionName": "ResponseCustomHeaderMiddleware",
            "requireSession": false
          }
        ],
        "contextVariables": {
          "enabled": true
        },
        "responsePlugins": [
          {
            "enabled": true,
            "functionName": "ResponseCustomHeaderMiddleware",
            "requireSession": false
          }
        ],
        "trafficLogs": {
          "enabled": true
        }
      },
      "operations": {
        "test": {
          "validateRequest": {
            "enabled": true,
            "errorResponseCode": 400
          },
          "trackEndpoint": {
            "enabled": true
          },
          "doNotTrackEndpoint": {
            "enabled": false
          }
        }
      }
    }

ResponseCustomHeaderMiddleware: (grpc , java)

public CoprocessObject.Object run(CoprocessObject.Object request) {
 boolean headerExist = request.getResponse().containsHeaders(HEADER_NAME);
        if (!headerExist) {
                 String headerValue = request.getRequest().getHeadersMap().get(HEADER_NAME);

                CoprocessReturnOverrides.ReturnOverrides returnOverrides = CoprocessReturnOverrides.ReturnOverrides.newBuilder()
                        .putHeaders(HEADER_NAME, headerValue)
                        .build();

                request.toBuilder().setRequest(request.getRequest().toBuilder()
                        .setReturnOverrides(returnOverrides)
                        .build()).build();
                return request;
            }
        } else {
            return request;
        }
    }

Actual behavior Custom header when 40x error happen is not returned.

Expected behavior Response which is returned based on swagger file validation should have headers which were added to returnoverrides or there should be an additional hook where this response can be modified before returning it to the user.

andyo-tyk commented 1 day ago

Hi @sm-agci, The custom Response Plugin operates on the response received from your upstream after it is received by Tyk. Are you trying to modify the error response generated by Tyk, or is this a 40x coming from your upstream?

sm-agci commented 1 day ago

I would like to modify response generated by Tyk, 400 in my case comes from request validation made by Tyk based on swagger definition (OAS swagger imported as json file). This request is rejected before it gets to upstream