Rewriting url with python middleware

I am trying to rewrite the outbound url in APIdefinition using python plugin, but apparantely the ReverseProxy middleware is changing the outbound url to “target_url” in defintion.

Here are my configurations:

middleware:

from tyk.decorators import *
from gateway import TykGateway as tyk

@Hook
def RewriteUpstreamMiddleware(request, session, metadata, spec):
    tyk.log("I'm logged!", "info")
    tyk.log("Request object", "info")
    tyk.log(str(request.object), "info")
    request.object.url = "https://test.example.com/"
    print(request.object.url)
    tyk.log(request.object.url, "debug")
    tyk.log("this is the headers", "info")
    tyk.log(str(request.object.headers), "info")
    return request, session, metadata

manifest.json

{
  "file_list": [
    "rewrite_upstream.py"
  ],
  "custom_middleware": {
    "driver": "python",
    "post": [
      {
        "name": "RewriteUpstreamMiddleware",
        "require_session": false
      }
    ]
  }
}

apiDefintion.yaml

apiVersion: tyk.tyk.io/v1alpha1
kind: ApiDefinition
metadata:
  name: httpbin
  namespace: dst
spec:
  name: httpbin
  use_keyless: true
  protocol: http
  active: true
  proxy:
    target_url: https://httpbin.org
    listen_path: /httpbin
    strip_listen_path: true
  custom_middleware_bundle: Bundle.zip

Logs:


09:34:18.377
time="Nov 06 09:34:18" level=debug msg="Upstream request URL: https://test.example.com/" api_id=ZHN0L2h0dHBiaW4 api_name=httpbin mw=ReverseProxy org_id=
 
09:34:18.377
time="Nov 06 09:34:18" level=debug msg="Outbound request URL: https://httpbin.org" api_id=ZHN0L2h0dHBiaW4 api_name=httpbin mw=ReverseProxy org_id=

The final api is routing to httpbin.org, not the test.example.com as intended. What am I missing?

As you’ve mentioned, it’s because the request still has to go through the Tyk proxy and is overridden there.

image

The actual value needed to do the rewrite is within the spec. However, the spec value only contains 4 properties for the Python plugin. So an overwrite with Python isn’t possible.

I should have explicitly mentioned this is really only possible with a Golang plugin as linked

With the exception of JavaScipt and Virtual Endpoint since they can return a response object.

Perhaps you could try using Go or the advanced URL rewrite. For the advanced URL rewrite, I converted my sample API definition into YAML format via operator. I haven’t tested it but maybe it could assist you in rewriting the URL