IIS Rewrite 2.0 Module - 404 errors - url-rewrite-module

I've installed the IIS Rewrite 2.0 module via Web Components on my Windows Server 2012.
I've read several articles but I just can't seem to get my simple rewrite to work.
I would like to rewrite http://www.acme.com/news/13/Jan/20 to http://www.acme.com/news.html#20-Jan-13
This is the rule I'm using:
<rule name="news articles" stopProcessing="true">
<match url="^news\/(.*)\/(.*)\/(.*)$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="news.html#{R:3}-{R:2}-{R:1}" appendQueryString="false" />
</rule>
When I apply http://www.acme.com/news/13/Jan/20 as my test pattern the rewrite works.
However, if I browse to http://www.acme.com/news/13/Jan/20 I get a 404 error:
Requested URL http://www.acme.com/news.html#20-Jan-13
Physical Path C:\Webs\acme.com\www\news.html#20-Jan-13
The physical file news.html exists and I can browse to it directly.
Is it the that are messing things up? Clearly C:\Webs\acme.com\www\news.html#20-Jan-13 isn't a physical file but I don't know how to solve this problem.
I can of course browse directly to http://www.acme.com/news.html#20-Jan-13 without issue.
Can anyone assist please?
Many thanks in advance.
Cheers,
Mark

According to this "How do write a rewrite rule in IIS that allows HTML anchors?" answer, browsers do not send anything after the # in a URL request to the server. They're markers intended solely for the browser to scroll to on the resulting page.
If you look at the logs, do you see a full request for the page including the anchor tag?
An alternative might be to use some DOM loaded JS to scroll the page to the anchor referenced in the URL (jQuery required):
$(function () {
var a_tag = $("a[name='" + window.location.hash.replace("#", "") +']");
$('html,body').animate({scrollTop: a_tag.offset().top}, 'slow');
});
Although, that likely doesn't solve the intended issue of friendlier URLs.

Related

rewrite a url to a soap method in iis

I am trying to rewrite a URL to a soap method but I seem no to able to figure out what's wrong. I have defined a pattern like this --> ./tree/tree/(.) with no conditions and no server variables in the action section I have both used redirect and rewrite to : localhost:2136/sharvand.asmx?op=GetTree but it hasn't worked out. any help will be appreciated
by the way how can I pass query string as a parameter to the web service
You can try this rule:
<rule name="test" stopProcessing="true">
<match url="^tree/tree/(.*)$" />
<action type="Rewrite" url="gis.shiraz.ir:80/service.asmx/op/{R:1}" />
</rule>

Azure webapplication return 404 when try to access using the address bar or refresh page

I need a little help with my azure app, I have a website using ReactJS hosted on Azure, but something weird is happening.
The only page I can access using the address bar its the mydomain.com or www.mydomain.com. If I try access something like mydomain.com/login it returns 404 and a white page with the follow message
"The resource you are looking for has been removed, had its name changed, or is temporarily unavailable".
Another thing is that I can normally use the website if I start from home. Example, if i am at homepage and click at a button that sends me to /login works, but if I try to refresh or go directly from the address bar, does not work.
Now, I also have a staging at azure that has exactly the same code, and works just fine, I can access anything from anywhere.
There is anyone that know anything about that?
Anyone facing the same issue can use the below web.config file which should be placed under the /site/wwwroot directory
<?xml version="1.0"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="React Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Seems like your React routing not working properly.
You can bypass the problem by using Hash (#) in your URL:
example:
use http://example.com/#/about instead of http://example.com/about
and in your router you should have something like this:
render((
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="#/repos" component={Repos}/>
<Route path="#/about" component={About}/>
</Route>
</Router>
), document.getElementById('app'))
Downsides:
'ugly' URLs
Server-side rendering is not possible with this approach. As far as SEO is concerned, your website consists of a single page with hardly any content on it.
I solve the problem, at staging azure app was a web.config file that was not created at the production app, that is why the problem existed, so after copy and paste the web.config file to production everything works just fine.

Modify requestvalidation in WebAPI (Azure)

We have a Asp.NET web api that handles requests from Android and iOS apps. We started to experience issues with GET requests that contained query strings. A URL like this: http://localhost:10723/api/Locations?userId=32432-a4r2-f32r3 gave this response:
A potentially dangerous Request.Path value was detected from the client (?)
After some debugging I saw that the querystring had been encoded, so the actual request was http://localhost:10723/api/Locations%3FuserId=32432-a4r2-f32r3, and that caused the issue. I can make changes to the apps that will fix this, but since this a app that is in production right now, I am desperately looking for a quick fix in the API that will allow the apps to work now.
What I have tried so far:
<httpRuntime targetFramework="4.5.1" requestValidationMode="2.0" />
<pages validateRequest="false" />
And related httpRuntime web.config tricks.
I have also written a custom request validator.
But everything is telling me that this is something that happens before the pagevalidation and my request validator is hit.
I was able to solve this by adding a rewrite rule for url on the server:
<system.webServer>
<rewrite>
<rules>
<rule name="Allowing querystrings.">
<match url="^(.*)\?(.*)$" />
<conditions logicalGrouping="MatchAny" />
<action type="Rewrite" url="{R:1}?{R:2}" />
</rule>
</rules>
</rewrite>
</system.webServer>

IIS URL Rewrite ASP

I do my best to scan the forum for help to make a web.config to do a Rewrite of this kind of url
domain.com/default.asp?id=3&language=2
My hope is that this can be
domain.com/en/service
where language=2 is "en"
and id=3 is page "Service" (this name exist in a mySQL)
I can only find example that do it vice versa...
Like this
<rewrite>
<rules>
<rule name="enquiry" stopProcessing="true">
<match url="^enquiry$" />
<action type="Rewrite" url="/page.asp" />
</rule>
</rules>
</rewrite>
I would like it to be something like this... I know this isn't correct, but maybe explains my problem.
<rewrite>
<rules>
<rule name="enquiry" stopProcessing="true">
<match url="^default.asp?id=3&language=2$" />
<action type="Rewrite" url="/en/serice" />
</rule>
</rules>
</rewrite>
If you want to use regular expressions you could do something like this
<rule name="RewriteUserFriendlyURL1" stopProcessing="true">
<match url="^([^/]+)/([^/]+)/?$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="default.asp?language={R:1}&id={R:2}" />
</rule>
This would rewrite "domain.com/en/service" as "domain.com/default.asp?language=en&id=Service", or "domain.com/2/3" as "domain.com/default.asp?language=2&id=3"
To change the 2 to en and the 3 to service, along with all the other options though I think you would need a separate rule for each permutation, or have some sort of logic within your asp pages to read your querystring variables and send the corresponding values to your SQL queries. Note also that the parameters in the friendly url appear in the same order and the querystring variables in the rewritten URL, although this shouldn't really be an issue. If someone tries to access the page with the original "unfriendly" url they will find what they are looking for, whichever way round they enter the querystring variables.
Please note, I didn't actually hand code the rule above, I generated it with the URL Rewrite module in IIS manager - it makes life a lot easier
Also note, as discussed with my namesake in the other answer, this only applies to IIS7 and above
I have done this in Classic ASP using custom error pages and this seems to be the best way unless you use some sort of third party component installed on the server.
To do this, in IIS (or web.config) you need to set up 404 errors to go to a specific custom error Classic ASP page (eg. 404.asp).
In this custom error page you first need to check to see if the URL is valid. If it is you can Server.Transfer to the correct page, return a 200 response code, and parse the URL there to convert the URL to the values needed for the database lookup, etc. If it's not a valid URL then you show a custom error page and return a 404 response code.
The code to check for a valid URL and to retrieve the URL parameters will vary greatly depending on your URL structure. But to find the URL requested on the custom 404 error page you have to look at the querystring, which will be something like "404;http://domain.com:80/en/service/".
Here's some sample code that gets the parameters from the requested URL:
Dim strUrl, intPos, strPath, strRoutes
strUrl = Request.ServerVariables("QUERY_STRING")
If Left(strUrl, 4) = "404;" Then
intPos = InStr(strUrl, "://")
strPath = Mid(strUrl, InStr(intPos, strUrl, "/") + 1)
If strPath <> "" Then
If Right(strPath, 1) = "/" Then strPath = Left(strPath, Len(strPath) - 1)
End If
strRoutes = Split(strPath, "/")
'Here you can check what parameters were passed in the url
'eg. strRoutes(0) will be "en", and strRoutes(1) will be "service"
End If
And here's how you can setup custom error pages in the web.config (rather than in IIS):
<?xml version="1.0"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" subStatusCode="-1" responseMode="ExecuteURL" path="/404.asp" />
</httpErrors>
</system.webServer>
</configuration>

IIS 7.5 URL Redirect direct link to media page

I didn't think my implementation through and now I am stuck. I am using IIS 7.5, URL Rewrite 2.0 and Jplayer.
My current implementation is that I have users upload audio files to my server. To listen to these audio files, users are given a direct link to either play in the browser or through Android/iOS in app media players.
Now I have created a landing page that I want to redirect those users direct linking to the audio file to. The landing page is using Jplayer.
The problem is that I have to use the direct link to the audio file to get jplayer to play it. Since I am redirecting the direct link, it is failing to load the media url.
This also becomes a problem since my Android and iOS apps direct link to the .mp3 in order to play the file in their AV players. Is there anyway around this? Is there a better implementation? Not sure what to do at this point.
Jplayer:
$("#jquery_jplayer_1").jPlayer({
ready: function (event) {
$(this).jPlayer("setMedia", {
mp3: "http://192.168.0.28/flows/t/test/test1334187052069.mp3"
}).jPlayer("play"); // auto play;
},
swfPath: "js",
supplied: "mp3",
errorAlerts: true,
warningAlerts: true,
wmode: "window"
});
IIS 7.5 Redirect Rule:
<rewrite>
<rules>
<rule name="FlowURLs">
<match url="^flows/[_0-9a-zA-Z-]+/[_0-9a-zA-Z-]+/([._0-9a-zA-Z-]+)" />
<action type="Redirect" redirectType="Found" url="music.html?flow={R:1}" />
</rule>
</rules>
</rewrite>
A possible solution might be to check the HTTP accept header and see if it's a browser expecting to load a page. If so then you redirect to your player landing page. Otherwise you leave the request as is and let it load the audio file directly.
You can check the accept header with a conditional:
<rewrite>
<rules>
<rule name="FlowURLs">
<match url="^flows/[_0-9a-zA-Z-]+/[_0-9a-zA-Z-]+/([._0-9a-zA-Z-]+)" />
<conditions>
<add input="{HTTP_ACCEPT}" pattern="text/html" />
</conditions>
<action type="Redirect" redirectType="Found" url="music.html?flow={R:1}" />
</rule>
</rules>
</rewrite>

Resources