0

我试图在 Ktor 中添加自定义功能。它基本上是一个 url 交换器(我们有一个场景,域可能随时更改,并且无法每次都更新客户端)。

我们获得了可用的交换器列表,并且需要 Ktor 中的 CustomFeature 来根据列表交换 url。但是, context.request 或 request.url - 一切都是 val 并且我无法为请求分配新的 url。

在改造中,它曾经像这样工作


            if (currentUrl.contains(urlSwapper.oldUrl)) {

                val newUrl = currentUrl.replace(urlSwapper.oldUrl, urlSwapper.newUrl)
                val newHttpUrl = request.url.newBuilder(newUrl)!!.build()

                // build a new request with the new url. replace it

                request = request.newBuilder().url(newHttpUrl).build()
                break
            }
        }

在 Ktor 功能中,我正在尝试这样的事情

            scope.requestPipeline.intercept(HttpRequestPipeline.Transform) {
                val currentUrl =
                    context.url.protocol.name + "://" + context.url.host + context.url.encodedPath

                for (urlSwapper in feature.urlSwappers) {
                    if (currentUrl.contains(urlSwapper.oldUrl)) {
                        val newUrl = currentUrl.replace(urlSwapper.oldUrl, urlSwapper.newUrl)
                        val newHttpUrl = Url(newUrl)
                        context.url(url = newHttpUrl)
                        break
                    }
                }
                proceedWith(subject)
            }
        }

这是正确的方法吗?

4

1 回答 1

0

通常是的,这是正确的方法。我有几个建议:

  1. 拦截sendPipeline而不是requestPipeline.

一个例子:

client.sendPipeline.intercept(HttpSendPipeline.State) {
    context.url(url = newUrl)
}
  1. 摆脱proceedWith(subject)呼叫,因为它是多余的。
  2. 尝试使用Url对象而不是字符串。UrlBuilder您可以通过克隆和构建来获取当前 URL 而不会影响上下文Urlcontext.url.clone().build()
于 2021-03-10T14:53:19.093 回答