I've this ISAPI_Rewrite rule:
RewriteRule /([^/.?]+) /sc.asp?p=$1 [I,L]
This rule should rewrite Urls like:
/some-article
/article2
and shouldn't rewrite Urls like:
/home.asp
/admin (because there's a directory named admin)
/admin/
/sites/gutterman
It works great in ISAPI_Rewrite
Yesterday I bought a Windows 2008 R2 VPS, and I started to transfer my ASP-classic web application to the new server. Now, everything is working great, except for URL Rewriting. I google-ed a little bit and found that the IIS7 URL Rewrite module is completely different from the ISAPI_Rewrite.
I created a Blank Rule. In the pattern I set /([^/.?]+), in Action -> Action Type I set Rewrite and in Action -> Action properties -> Rewrite Url I set sc.asp?p={R:0}. It didn't work.
After some googling I found that I have to remote the / character in the start of my pattern (so my pattern is now ([^/.?]+)). So I did it, and now, it is just rewriting any url, and it should rewrite only urls that aren't directories or files.
Any ideas?
Thank you.
The simplest way to avoid rewriting URLs that actually point to existing files is to add these conditions:
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
Also, your match pattern shows a common misconception. The querystring is not passed to the Match URL pattern, so you don't need to look for ?.
Related
We are removing two sections from our site.
/warehouse/
/clothing/
I'd like to send all the URLS beneath these two to a single (404) landing page saying the item has been removed. I'd like to clean up the query strings too if possible.
Where do I start?
If you're using nginx, you can just add a pair of location sections. They'll match as long as there aren't more specific locations. Check out the documentation for more detail.
location /warehouse/ {
return 410;
}
location /clothing/ {
return 410;
}
If there are too many locations, it could be cumbersome to list them separately, so you can use regex like this:
location ~* ^/(warehouse|clothing|something-else)/ {
return 410;
}
If you want a customized 410 page, add configuration like this in your server block:
error_page 410 /410.html;
location = /410.html {
root /var/www/error/; # Put a file /var/www/error/410.html
internal;
}
Replace 410 with 404 if you want to return that status code. I believe 410 "Gone" is more appropriate answer, but YMMV.
I'd suggest to do this in whatever is closer to the client, so if nginx is in front of Apache - do it with nginx. This way you have less round-trips.
If you want to do this in Apache, you can do it with RedirectMatch:
// I'm not sure `.*$` part is even necessary. Can be probably omitted.
RedirectMatch gone "^/(warehouse|clothing)/.*$" "/410.html"
Or I'd suggest to use mod_rewrite as a somewhat more flexible option:
RewriteEngine on
RewriteRule ^/(warehouse|clothing)/ - [G,L]
ErrorDocument 410 /410.html
Here [G] means "gone" (410 status code). If you want a 404 response, do this instead:
RewriteEngine on
RewriteRule ^/(warehouse|clothing)/ - [R=404,L]
Note, that you need ^/ in your regexes to indicate that path not just contains /warehouse/ or /clothing/ but starts with those. Otherwise you'll see suposedly incorrect responses on addresses like /about/clothing/. I'm not exactly sure if you need trailing .*$, but I believe you don't. Don't have Apache to test this. Add it if rules don't work for you (i.e. ^/(warehouse|clothing)/.*$).
Or you can handle the logic in your application - which can be the only way if your base layout contains something user-dependent and you want consistency. No answer could be written without knowing what language/framework/stack do you use.
First, I'd recommend that you redirect to a 410 (Gone) rather than a 404 to acknowledge that the resource once existed.
In Apache, you'd do something like the following. Refer to this page for more information.
RedirectMatch permanent "^/(warehouse|clothing)/?.*" "http://www.example.com/404"
In IIS, your web config would look something like the following. Note that IIS won't let you use question marks in your regex, since it interprets that as a query string. Refer to this page for more information.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="404 Redirect" stopProcessing="true">
<match url="^/(warehouse|clothing)/" />
<action type="Redirect" url="404" appendQueryString="true" redirectType="Permanent" />
<conditions trackAllCaptures="true"></conditions>
</rule>
</rules>
</rewrite>
<httpProtocol allowKeepAlive="false" />
<caching enabled="false" />
<urlCompression doDynamicCompression="true" />
</system.webServer>
</configuration>
Updated to include ^/ at the beginning of the regex based on drdaeman's comment.
I need to redirect all of the legacy .htm urls for my website to extensionless urls, so:
http://www.website.com/page.htm --> http://www.website.com/page
I created the following rule in config/UrlRewriting.config, which fixed the above issue, but created an issue where all of the backoffice paths are returning 404:
<add name="HtmToExtensionless"
redirect="Domain"
ignoreCase="true"
rewriteUrlParameter="IncludeQueryStringForRewrite"
virtualUrl="http://www.website.com/(.*)(\.htm)"
redirectMode="Permanent"
destinationUrl="http://www.website.com/$1" />
So requests like these are returning 404:
http://www.website.com/umbraco/views/components/application/umb-navigationl?umb__rnd=7.4.2.1536555776
I'm pretty sure my problem is with my regex, but I'm not sure. Anyone care to advise?
Turns out I was being a dufus. Umbraco actually requests resources that have .html extensions, and my regex was grabbing those and stripping the .htm from them. Just had to check for the beginning and end of the string, and now we're golden:
<add name="HtmToExtensionless"
redirect="Domain"
ignoreCase="true"
rewriteUrlParameter="IncludeQueryStringForRewrite"
virtualUrl="^http://www.website.com/(.*)(\.htm)$"
redirectMode="Permanent"
destinationUrl="http://www.website.com/$1" />
I'm trying to setup a 301 redirect for some pages on my site so I setup some rewrite mappings as:
<rewriteMap name="v2 structure">
<add key="/what-we-do/why-us" value="/who-we-are/knowledge/why-us" />
<add key="/what-we-do/why-us/sourcing-models" value="/who-we-are/knowledge/why-us/sourcing-models" />
</rewriteMap>
The site is multi language so the url will include the language:
www.domain.com/en/what-we-do/why-us should redirect to www.domain.com/en/who-we-are/knowledge/why-us
www.domain.com/es/what-we-do/why-us should redirect to www.domain.com/es/who-we-are/knowledge/why-us
The mapping that I have doesn't trigger because of the language on the url. I can make it work by adding the language to the key and value on the mapping but i would had to repeat the mapping for each different language that the site has.
Is there a way to match trigger the rules mapped ignoring the language on the url?
Thank you,
Joao
I have url rewrite rule on my .htaccess file like this.
RewriteEngine on
RewriteRule ^(scripts|css)/(.+)\.(.+)\.(js|css)$ $1/$2.$4 [L]
I need to use the same rule on my IIS .
I have used ^(.*)\.[\d]{10}\.(css|js) for the pattern.
I am not sure what to mention Rewrite URL.
I want to rewrite the url /css/structure.1234.css as /css/structure.css
Anyone knows please help?
I read your other ColdFusion question (regarding using regex to add a numerical value to a filename.)
We use an underscore and a 14 digit datestamp. Here's the IIS Rewrite Rule that we use. You can modify it for your needs.
<rule name="CSSJSDatestamp" stopProcessing="true">
<match url="^(.*)(_[0-9]{14}\.)(css|js)$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{SCRIPT_NAME}" pattern="/_scripts/" />
</conditions>
<action type="Rewrite" url="{R:1}.{R:3}" />
</rule>
BTW, I don't use this method anymore with my ColdFusion-drive websites since installing IISpeed (PageSpeed for IIS). It automatically minifies, concats and caches JS/CSS files when the files are changed (without the need for cach-busting). It can also optimize images based on device support (ie, reduce size, auto-conversion to WebP, etc). I also really like that it can move all CSS & JSS to the HEAD of the HTML file, prioritize CSS and lazy loads all images "below the fold" with having to add any ColdFusion code or use jQuery.
For more info on IISpeed/Pagespeed, check out:
http://www.iispeed.com/
http://www.iispeed.com/pagespeed/insights
https://developers.google.com/speed/pagespeed/
I'm using IIS 7.5 and UrlRewrite Module 2. I've read the official documentation for the module here, as well as many examples on SO and tested my regex on Regexpal. Somehow the translation into the Web.config file is causing me problems. I've tried escaping the parantheses also.
The regex I'm using is:
^partners/(var|distributors|msp|techpartners)/(na|emea|apac)(|/)(.*)
a few example urls:
partners/var/emea
partners/msp/apac/
partners/var/na/abcdabcdabcd
Here is the web.config I have so far:
<rules>
<rule name="partnersListing" enabled="true" stopProcessing="true">
<match url="^partners/(var|distributors|msp|techpartners)/(na|emea|apac)(|/)(.*)" />
<action type="Rewrite" url="partnersList.aspx?type=${R:1}®ion={R:2}" />
</rule>
</rules>
Not sure if I want the action to be Rewrite or Redirect yet, but the pattern isn't working either way. Any help is greatly appreciated
Per your answer to my question in the comments:
Is this rule in the site root web.config or a subdirectory web.config?
#Kev in a subdirectory: "/partners"
From the docs:
http://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-configuration-reference?amp;clcid=0x409
Quote:
Note that the input URL string passed to a distributed rule is always
relative to the location of the Web.config file where the rule is
defined. For example, if a request is made for
http://www.mysite.com/content/default.aspx?tabid=2&subtabid=3, and a
rewrite rule is defined in the /content directory, then the rule gets
this URL string default.aspx as an input.
Based on this you need to change your url match to:
^(var|distributors|msp|techpartners)/(na|emea|apac)(|/)(.*)
Assuming your re-write rule exists in:
http://example.com/partners/web.config
There is just one other thing which is what appears to be an extraneous $ character in your redirect/rewrite url in front of back reference {R:1}, I'm not sure if you intended that to be there or not.