[Rewrite rules] Hi all, can someone help me to und...
# box-products
a
[Rewrite rules] Hi all, can someone help me to understand how to configure a rewrite rule for my site? I used to have IIS, I'm giving Tuckey some tries but something is wrong... This is what I need: https://site/api/v1/xxx must be rewritten to https://site/core/framework/api/v1/index.cfm?endpoint=xxx My IIS urlrewrite rule, if it can help, is
Copy code
<rule name="api" stopProcessing="true">
  <match url="api/(v[1-9]+)/(.+.*)$" ignoreCase="true" />
  <conditions>
    <add input="{PATH_INFO}" pattern="^.*/index.cfm.*$" negate="true" />
  </conditions>
  <action type="Rewrite" url="core/framework/api/{R:1}/index.cfm?endpoint=/{R:2}" />
</rule>
I tried with this customRewrites.xml:
Copy code
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" "<http://tuckey.org/res/dtds/urlrewrite4.0.dtd>">
<urlrewrite use-query-string="true">
  <rule>
    <name>Api redirect</name>
    <from>^api/(v[1-9]+)/(.+.*)$</from>
    <condition type="request-url" operator="notequal">/index\.cfm.*$</condition>
    <to>core/framework/api/$1/index.cfm?endpoint=/$2</to>
  </rule>
</urlrewrite>
I also tried removing the
^
inside
from
tag, but doesn't work (I'm gettin' 404) Also, in my server.json I do this
Copy code
"web":{
        ...
        "rewrites":{
            "enable":true,
            "config":"customRewrites.xml",
            "logEnable":true,
            "statusPath":"/rewriteStatus",
            "configReloadSeconds":"30"
        },
But if I navigate https://site/rewriteStatus I always get a 404. Any help really appreciated!
b
@Alessandro Lia Pro tip: use three backticks for multi-line code blocks. Also, putting them in a thread will keep the main channel clean.
Copy code
example
here
a
backtick done, thanks. I did't know about thread sorry
b
@Alessandro Lia I would highly recommend moving away from the Tuckey-based rewrites. They will be deprecated in the next release and are based on a now-stagnant Java library. CommandBox has supported a new way to do rewrites for a while now, called "server rules" https://commandbox.ortusbooks.com/embedded-server/configuring-your-server/server-rules
So to clarify how you need them to work, you said
This is what I need: https://site/api/v1/xxx must be rewritten to https://site/core/framework/api/v1/xxx
but your actual rewrite looks different
Copy code
<action type="Rewrite" url="core/framework/api/{R:1}/index.cfm?endpoint=/{R:2}" />
It seems you are adding an
index.cfm
in there?
a
wow, I wasn't aware of this...
anyway, you're right, I'm gonna edit this example
b
It also seems you're converting to a query string?
Your rule doesn't seem to match your example
a
sorry, now fixed
b
Also, I see you have this condition in place
Copy code
<add input="{PATH_INFO}" pattern="^.*/index.cfm.*$" negate="true" />
But are there existing valid URLs which start with
Copy code
/api/vN/
which should not be rewritten?
Seems unlikely
a
yes if you don't use that pattern, it will be an infinite replace
b
Also, what's going on here?
Copy code
(.+.*)
That's a capture group containing 1 or more character, followed by 0 or more characters, but that's redundant. You should just be able to move the
.*
entirely.
a
right, it's not that good, I think someone has changed my file and I wasn't aware
b
yes if you don't use that pattern, it will be an infinite replace
That's only because your regex is wrong 🙂 Anchor it to the start of the string with
^
and it will work without the condition
a
ok, I'll try inside my IIS!
b
Copy code
api/(v[1-9]+)/(.+.*)$
will match anywhere in the string, but
Copy code
^api/(v[1-9]+)/(.+.*)$
will only match at the start of the string
Copy code
api/(v[1-9]+)/(.+.*)$
is the functional equivalent of
Copy code
.*api/(v[1-9]+)/(.+.*)$
Also, what about this
Copy code
[1-9]+
are you planning on skipping
v10
and going straight from
v9
to
v11
? 🙂
a
oh god
sorry for that, I'll investigate inside git to understand who make this updates
is obviously wrong
b
I am working on the rule you want to use, just testing it real quick
a
great, thank you! But I can test it
b
Ok, here was my test
Copy code
goto sandbox
mkdir rewritetest --cd
server set web.rules[1]="regex-nocase( '^/api/(v[0-9]+)/(.*)$' ) -> rewrite( '/core/framework/api/\\\${1}/index.cfm?endpoint=\\\${2}' )"
touch core/framework/api/v1/index.cfm
start --console --trace
I opened
Copy code
<http://127.0.0.1:51720/api/v1/foobar>
in my browser
And the console trace output showed the following
Copy code
[DEBUG] Runwar: requested: '<http://127.0.0.1:51720/api/v1/foobar>'
[TRACE] Server Rules: Regex pattern [^/api/(v[0-9]+)/(.*)$] MATCHES input [/api/v1/foobar] for HttpServerExchange{ GET /api/v1/foobar}.
[TRACE] Server Rules: Storing regex match group [0] as [/api/v1/foobar] for HttpServerExchange{ GET /api/v1/foobar}.
[TRACE] Server Rules: Storing regex match group [1] as [v1] for HttpServerExchange{ GET /api/v1/foobar}.
[TRACE] Server Rules: Storing regex match group [2] as [foobar] for HttpServerExchange{ GET /api/v1/foobar}.
[TRACE] Server Rules: Predicate [regex( pattern='^/api/(v[0-9]+)/(.*)$', value='%{RELATIVE_PATH}', full-match='false', case-sensitive='true' )] resolved to true. Next handler is [rewrite( 'NDA' )] for HttpServerExchange{ GET /api/v1/foobar}.
[DEBUG] Server Rules: Request rewritten to [/core/framework/api/v1/index.cfm?endpoint=foobar] for HttpServerExchange{ GET /api/v1/foobar}.
a
seems really great, I'll try and get back asap
thanks a lot!!!
b
Just for completeness, here was my
server.json
Copy code
{
  "web": {
    "rules": [
      "regex-nocase( '^/api/(v[0-9]+)/(.*)$' ) -> rewrite( '/core/framework/api/\\${1}/index.cfm?endpoint=\\${2}' )"
    ]
  }
}
a
They will be deprecated in the next release
Is that the next CommandBox release so soon? We're using Tuckey-based rewrites currently.
a
Just for completeness, this is my final json configuration:
Copy code
"rules":[
    "regex-nocase( '^/api/(v[0-9]+)/(.*)$' ) -> rewrite( '/core/framework/api/\\${1}/index.cfm?endpoint=/\\${2}' )"
]
while debugging I see that I need to redirect to
/apiname
and not just
apiname
, or Taffy will fail. Also, talking about IIS, after some tries I remember why we need to set the matcher to
api/(v[1-9]+)/(.+.*)$
without the initial caret: IIS will not match the rule if you add the first caret, so you need to drop it and add the
index.cfm
exception
anyway: THANKS for your support!!!!
b
@Alessandro Lia I presume IIS didn't match because you were missing the leading slash
You wanted
^/api
not
^api
@aliaspooryorik are you using a custom rule xml file?
a
yeah. set in rewrites.config of server.json. Points to an urlrewrite.xml
Not a big deal to switch up handy to know rough timescale
b
@aliaspooryorik Prolly looking at a couple months until CommandBox 6 release. I'm hoping to have some instructions to workaround and still use Tuckey, but I haven't done much testing on it yet. With the new multi-site stuff coming in CommandBox, the static file serving has been moved out in front of the servlet so requests for static files no longer even hit the servlet by default. This, of course, is one of several issues since Tuckey is a servlet filter.