首页 > 解决方案 > Regsub 没有从 URL 操作字符串

问题描述

使用这个时我收到一个奇怪的 TCL 错误iRule,错误是:

<HTTP_REQUEST> - ERR_ARG(第 2 行)从 "HTTP::uri [regsub "/3dnotification" [HTTP::uri] ""] " 中调用

这是一个 F5 规则代码。

这是我尝试过的:

   when HTTP_REQUEST 
{ 
    if { not ( [string tolower [HTTP::uri]] starts_with "/socket.io" )} then { 
        HTTP::uri [regsub "/3dnotification" [HTTP::uri] ""] 
    
    # need to strip trailing slash on URI otherwise results in 404 for resources...
        HTTP::uri [regsub "\/$" [HTTP::uri] ""]
    } elseif { [string tolower [HTTP::header Upgrade]] contains "websocket" } {
        ONECONNECT::reuse disable
        set oc_reuse_disable 1
    }
    HTTP::header replace "X-Forwarded-ContextPath" "/"
}
when SERVER_CONNECTED {
    if { [info exists oc_reuse_disable] } {
        # Optional; unnecessary if the HTTP profile is disabled (goes into passthrough mode).
        ONECONNECT::detach disable
        unset oc_reuse_disable
    }
}

标签: tclf5

解决方案


由于 URI 要么是完整的 URI,要么是无协议的部分(我不能从你说的内容中完全分辨出哪一个;我假设两者都是可能的),删除前导部分或尾随部分会有点棘手。您需要做的是首先将 URI 拆分为其组成部分,将转换应用于路径部分,然后重新组合。拆分和重组的关键是Tcllib 中的 uri 包

package require uri

# Split the URI and pick out the path from the parts
set uriParts [uri::split [HTTP::uri]]
set path [dict get $uriParts path]

# Do the transforms
set path [regsub "/3dnotification" $path ""]
set path [string trimright $path "/"];  # A different way to remove trailing slashes

# Reassemble and write back
dict set uriParts path $path
HTTP::uri [uri::join {*}$uriParts]

我假设您将package require(或您需要的任何其他内容以获取代码)放在脚本的顶部,并将其余部分放在正确的when子句中。


这样您就可以看到 URI 拆分的实际作用,这是您的示例 URI 拆分(在交互式tclsh会话中):

% set uri "http://www.example.com:8080/main/index.jsp?user=test&login=check"
http://www.example.com:8080/main/index.jsp?user=test&login=check
% uri::split $uri
fragment {} port 8080 path main/index.jsp scheme http host www.example.com query user=test&login=check pbare 0 pwd {} user {}

正如您所看到的,这path部分正是main/index.jsp比整个 URI 更容易使用的部分。


推荐阅读