IIS 7.5 URL Rewrite - replace domain - iis

Possible duplicate of https://stackoverflow.com/questions/26840890/i-need-to-change-domain-with-iis-7-5-url-rewrite (unanswered yet)
I have the following URLs
www.myolddomain.com/somefolder-a
www.myolddomain.com/somefolder-b
www.myolddomain.com/somefolder-c
...
I want one rule to redirect every request incoming containing myolddomain.com/somefolder to www.mynewdomain.com/somefolder with above suffix such as -a.
My rule so far looks like this:
<rule name="Redirect from old domain" enabled="true" stopProcessing="true">
<match url="(.*)myolddomain.com/somefolder(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
</conditions>
<action type="Redirect" url="https://www.mynewdomain.com/somefolder{R:2}" />
</rule>
This rule has no effect whatsoever.
Did I make a mistake here already?
Or could requests be redirected at some other place before IIS?
According to the firewall admin no redirects take place at the firewall. Could it be anything else?

Through further trial and error I found a solution:
<rule name="Redirect from old domain" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="myolddomain.com" />
<add input="{HTTP_URL}" pattern="/somefolder(.*)" />
</conditions>
<action type="Redirect" url="https://www.mynewdomain.com/somefolder{C:1}" />
</rule>
For curiousity, how is the match on the rule level supposed to work? No matter what I put there, as soon as it is anything else than .* the rule is ignored.
Hint to others: don't fall into the trap of thinking that server variables like "HTTP_URL" actually contain the URL - they do NOT. Best way to figure out what is really in which variable is a sample page like this (copied from the web - I apologize for having lost the link):
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Server Variables</title>
</head>
<body>
<table>
<tr>
<th>Server Variable</th>
<th>Value</th>
</tr>
<tr>
<td>HTTP_URL: </td>
<td><%= Request.ServerVariables["HTTP_URL"] %></td>
</tr>
<tr>
<td>Replace above server variable to retrieve different variables</td>
</tr>
</table>
</body>
</html>

Related

web.config file is rendering the page when a partial url is correct

We are having a peculiar issue.
There are a lot of products and categories on the site and we have a web.config file that redirects and rewrites the pages as per the category or product. All works good like when the page url for the category or the products is right , but when we add "anything" after the URL it does not give a page error or 404 not found, but it shows the last good page from the url.
for example:
https://websitename/sub-page/2w57w45uwas4jn
it still opens and shows the page as in
https://websitename/sub-page/
And it should go to a 404 page. The problem persists on all of these type of pages.
Another example:
https://websitename/sub-page/
can open with everything you write again after the "/"
https://websitename/sub-page/aetgashgwasegh
Any help here please as it is affecting our page ranking and SEO
The code for one url from the web.config file
<rule name="Z2-Auto-Travel-CPAP-Machine" stopProcessing="true">
<match url="^Z2-Auto-Travel-CPAP-Machine/" />
<conditions>
<add input="{UNENCODED_URL}" pattern="Z2-Auto-Travel-CPAP-Machine/" />
</conditions>
<action type="Rewrite" url="Z2-Auto-Travel-CPAP-Machine.php" />
</rule>
<rule name="Z2-Auto-Travel-CPAP-Machine_rd" stopProcessing="true">
<match url="(Z2-Auto-Travel-CPAP-Machine.*)" />
<conditions logicalGrouping="MatchAny" trackAllCaptures="false">
<add input="{HTTP_HOST}{REQUEST_URI}" pattern="Z2-Auto-Travel-CPAP-Machine.php" />
<add input="{HTTP_HOST}{REQUEST_URI}" pattern="websitename/Z2-Auto-Travel-CPAP-Machine.php" />
</conditions>
<action type="Redirect" url="Z2-Auto-Travel-CPAP-Machine/" redirectType="Permanent" />
</rule>
Both the rules are for the same product, the first rule is to rewrite the file to .php and the second rule is to redirect to the url

Angular app publish with IISNode on Smarterasp.net

My online host service smarterasp.net require some changes made to publish my angular compiled app (Angular v. 11.1.1) as a node js app. On their quickstart guide(https://www.smarterasp.net/support/kb/a1970/quick-start-node_js.aspx?KBSearchID=818443) they say: "We are Hosting node.js applications in IIS on Windows via IISNode, so you need to update listening port to use "process.env.PORT" in your code" and there's code given as an example:
HelloWorld Sample:
hello.js
var http = require('http');
http.createServer(function(req, res) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('Hello, world!');
}).listen(process.env.PORT);
web.config
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="hello.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="mysite">
<match url="/*" />
<action type="Rewrite" url="hello.js" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
"You do not have to run any command line with npm or node.exe to host nodejs with us." They say.
Now, the problem is: My compiled Angular app consists on many .js files, but the hello.js example given only has a string return res.end('Hello, world!');. My questions are:
What's the correct code to use in my case (instead of the hello.js) and where should I put this code? I already try to put it inside my index.html file, inside the header tags, inside a script, but the web browser console shows me the error (Uncaught ReferenceError: require is not defined).
Once I uploaded my test files, my website shows a black screen.
This is my attempt of script inside my index.html file:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>DummyTitle</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.write(req.url);
res.end();
}).listen(process.env.PORT);
</script>
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght#300;400;500&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body style="background-color: black;">
<app-root></app-root>
</body>
</html>
And this is my web.config file (following the angular guide about IIS (https://angular.io/guide/deployment)):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Angular Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/mainwebpage/index.html" />
</rule>
</rules>
</rewrite>
<handlers>
<add name="iisnode" path="*.js" verb="*" modules="iisnode" />
</handlers>
</system.webServer>
</configuration>
Has somebody found the same issue before? Help please!!
After a few days I figure out the quick start guide provided was wrong (https://www.smarterasp.net/support/kb/a1970/quick-start-node_js.aspx?KBSearchID=818443) I had absolutely no necesity to redirect my requests/responses to a server as suggested on the hello.js file. Probably because my angular app doesn't use server side rendering (SSR, Angular universal).
The solution was simply paste the compiled angular files at the designated folder and add a web.config. To my surprise I discover that the example of web.config file given on the official angular site (https://angular.io/guide/deployment#fallback-configuration-examples) was also wrong. Here's my web.config file, hoping it helps other poor souls looking for an inexistence documentation:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Angular Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="./index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
If you have server.js file put the code "process.env.PORT" inside the server.js file.
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
</handlers>
</system.webServer>
</configuration>
This handler registration allows the same web site to contain other *.js files (e.g. jQuery libraries) that IIS will continue serving as static files.
Reference link:
use node.js express on iis with iisnode

Random HTTP 5xx errors from IISnode

I'm working on the Botbuilder framework using the NODEjs SDK and i have the current setup for directline conversations
A nodejs web UI which is a chat interface for the bot
A nodejs bot logic server
Both these servers are hosted in an azure web app (windows server 2016) with an IIS-node webserver
Currently the server containing the bot logic has the below routes (using the restify framework)
server.post('/receiveMessage', connector.listen());
server.post('/beginSpecialDialog', function(req,res,next){
var _body = req.body;
logger("info", "server", "/beginSpecialDialog triggered", null, {"conversationId": _body._directlineAddress.conversation.id})
if(_body._directlineAddress.secret !== config.BOT.DIRECTLINE_SECRET){
logger("warn", "server", "directline credentials do not match", null, {"conversationId": _body._directlineAddress.conversation.id, "secretSent":_body._directlineAddress.secret, "err":err});
res.send(401);
}
bot.beginDialog(_body._directlineAddress, _body._dialogId, _body._specialParams, function(err){
if(err){
logger("warn", "server", "error occured on starting main dialog from url", null, {"conversationId": _body._directlineAddress.conversation.id, "err":err});
res.send(400, {"err": err.stack });
}
else{
res.send(200);
}
});
});
The /beginSpecialDialog is initiated by the webUI server whenever we need to convey the bot to start a special Dialog for the webUI browser.
However , sometimes (1 in every 10 requests or so) - this route isnt being processed by the bot server. I get a 5xx response from the bot server with the below details
</head>
<body>
<div id="content">
<div class="content-container">
<h3>HTTP Error 500.1013 - Internal Server Error</h3>
<h4>The page cannot be displayed because an internal server error has occurred.</h4>
</div>
<div class="content-container">
<fieldset><h4>Most likely causes:</h4>
<ul> <li>IIS received the request; however, an internal error occurred during the processing of the request. The root cause of this error depends on which module handles the request and what was happening in the worker process when this error occurred.</li> <li>IIS was not able to access the web.config file for the Web site or application. This can occur if the NTFS permissions are set incorrectly.</li> <li>IIS was not able to process configuration for the Web site or application.</li> <li>The authenticated user does not have permission to use this DLL.</li> <li>The request is mapped to a managed handler but the .NET Extensibility Feature is not installed.</li> </ul>
</fieldset>
</div>
<div class="content-container">
<fieldset><h4>Things you can try:</h4>
<ul> <li>Ensure that the NTFS permissions for the web.config file are correct and allow access to the Web server's machine account.</li> <li>Check the event logs to see if any additional information was logged.</li> <li>Verify the permissions for the DLL.</li> <li>Install the .NET Extensibility feature if the request is mapped to a managed handler.</li> <li>Create a tracing rule to track failed requests for this HTTP status code. For more information about creating a tracing rule for failed requests, click here. </li> </ul>
</fieldset>
</div>
<div class="content-container">
<fieldset><h4>Detailed Error Information:</h4>
<div id="details-left">
<table border="0" cellpadding="0" cellspacing="0">
<tr class="alt"><th>Module</th><td> iisnode</td></tr>
<tr><th>Notification</th><td> ExecuteRequestHandler</td></tr>
<tr class="alt"><th>Handler</th><td> iisnode</td></tr>
<tr><th>Error Code</th><td> 0x0000006d</td></tr>
</table>
</div>
<div id="details-right">
<table border="0" cellpadding="0" cellspacing="0">
<tr class="alt"><th>Requested URL</th><td> https://test-bot-website:80/server.js</td></tr>
<tr><th>Physical Path</th><td> D:\home\site\wwwroot\server.js</td></tr>
<tr class="alt"><th>Logon Method</th><td> Anonymous</td></tr>
<tr><th>Logon User</th><td> Anonymous</td></tr>
</table>
<div class="clear"></div>
</div>
</fieldset>
</div>
<div class="content-container">
<fieldset><h4>More Information:</h4>
This error means that there was a problem while processing the request. The request was received by the Web server, but during processing a fatal error occurred, causing the 500 error.
<p>View more information »</p>
<p>Microsoft Knowledge Base Articles:</p>
</fieldset>
</div>
</div>
</body>
</html>
heres the log from the IIS node webserver
2018-01-25 06:22:58 TEST-BOT-WEBSITE POST /beginSpecialDialog X-ARR-LOG-ID=da648f30-dda9-4103-8a48-862b65eef82d 443 - 23.102.157.162 - - - test-bot-website.azurewebsites.net 500 1013 109 298 1425 120540
Could anyone shed some light as to why this happens? heres my web.config file
<configuration>
<system.webServer>
<!-- Visit http://blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx for more information on WebSocket support -->
<webSocket enabled="false" />
<handlers>
<!-- Indicates that the server.js file is a node.js site to be handled by the iisnode module -->
<add name="iisnode" path="server.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<!-- BEGIN rule TAG FOR WWW and HTTP to HTTPS REDIRECT -->
<rule name="First_Secure" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTPS}" pattern="OFF" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}" />
</rule>
<rule name="Second_Redirect" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTPS}" pattern="ON" />
<add input="{HTTP_HOST}" pattern="^(www\.)(.*)$" ignoreCase="false" />
</conditions>
<action type="Redirect" url="https://{C:2}" />
</rule>
<!-- END rule TAG FOR WWW and HTTP to HTTPS REDIRECT -->
<!-- Do not interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^server.js\/debug[\/]?" />
</rule>
<!--This redirects home page to /public/index.html-->
<rule name="DefaultDocRewrite" stopProcessing="True">
<match url="^$" />
<action type="Rewrite" url="/public/index.html" />
</rule>
<!--This redirects all urls to public -->
<rule name="StaticContentRewrite">
<action type="Rewrite" url="public{REQUEST_URI}"/>
</rule>
<!--This catches if the file exists under public directory and stops processing, so that iis will serve static files -->
<rule name="StaticContent" stopProcessing="True">
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" />
<add input="{REQUEST_URI}" pattern="^/public/" />
</conditions>
</rule>
<!-- All other URLs are mapped to the node.js site entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="server.js"/>
</rule>
</rules>
</rewrite>
<!-- 'bin' directory has no special meaning in node.js and apps can be placed in it -->
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin"/>
</hiddenSegments>
</requestFiltering>
</security>
<!-- Make sure error responses are left untouched -->
<httpErrors existingResponse="PassThrough" />
<!--
You can control how Node is hosted within IIS using the following options:
* watchedFiles: semi-colon separated list of files that will be watched for changes to restart the server
* node_env: will be propagated to node as NODE_ENV environment variable
* debuggingEnabled - controls whether the built-in debugger is enabled
See https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config for a full list of options
-->
<!-- Runs node processes on each core you have in the machine -->
<iisnode watchedFiles="web.config" nodeProcessCountPerApplication="0"/>
</system.webServer>
</configuration>

IIS rewrite rule not working

I would like to rewrite this:
domain.com/gallery/123123/name-of-the-image/
To display content from here: domain.com/gallery/showImage/name-of-the-image-123123
Here's my current code:
<rule name="Gallery - Single image">
<match url="^gallery/([0-9])/([a-z-/]+)/?$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="gallery/showImage/{R:2}-{R:1}" />
</rule>
How should I alter the rewrite code to make it work?
Big thanks in advance
Your regex to match the URL should be:
^domain\.com\/gallery\/(\d+)\/([a-z-]+)\/?$
and the rewrite URL should be:
domain.com/gallery/showImage/{R:2}-{R:1}

IISNode and Express 3 yields http 403.13 error

I am setting up IISNode on IIS 7 locally on my Win7 box. I followed the instructions on the site and the samples are working fine.
I created a new website and AppPool in IIS Manager to run a brand new shell of an Express site. I've added the web.config to tie the iisnode module to my starting .js file.
When I browse to the default route (/) I get an Http 403.14 error (Server is configured to not list the contents of the directory).
I have attempted to remap the IISNode sample directory to where my Express app is and the same error occurs.
If I attempt to go to a non-existing route, I DO get Connect's 404 error message of Cannot VERB ROUTE.
I feel like I"m missing something simple and (hopefully obvious).
Has anyone ran into this and can provide me some insight? Looking online has provided little light in terms of even when I can check.
I figured out what issue I was having. In my web.config, I had the default IISNode section and the handler section to map the iisnode module to my app.js file.
However, when using Express, every route has to go through that file. So by adding the rewrite section as below it resolved my issue.
<rewrite>
<rules>
<rule name="Catch All">
<match url="/*" />
<action type="Rewrite" url="app.js" />
</rule>
</rules>
</rewrite>
For a more advanced URL rewriting configuration check out the web.config template at http://tomasz.janczuk.org/2012/05/yaml-configuration-support-in-iisnode.html. This template allows you to redirect requests for static content to the IIS static file handler, as well as retain access to iisnode logs over HTTP.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<rule name="LogFile" patternSyntax="ECMAScript" stopProcessing="true">
<match url="iisnode"/>
</rule>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^server.js\/debug[\/]?" />
</rule>
<rule name="StaticContent">
<action type="Rewrite" url="public{{REQUEST_URI}}"/>
</rule>
<rule name="DynamicContent">
<conditions>
<add input="{{REQUEST_FILENAME}}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="server.js"/>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
The web.config above has the following effect:
It specifies server.js as the entry point to your node.js application.
It redirects all requests for URLs that map to physical files in the “public” subdirectory to an IIS static file handler. Using IIS static file handler has a large performance benefit compared to serving static content from within a node.js application. The handler leverages IIS and OS low level caching mechanisms which offer superb performance.
It allows IIS to serve the log files that capture output of a node.js application as static files such that you can access them over HTTP. By default, if your server.js entry point is reached at http://example.com/server.js, the log files would be accessible at http://example.com/iisnode.
It exposes the built-in node-inspector debugger at http://example.com/server.js/debug. Learn more about debugging with iisnode.
It sends all other HTTP requests to be processed by your node.js application in server.js.
Fin more info in my link there I have a working example a the bottom of the question
Below its the project configuration
below the code for server.js
"use strict";
var express = require('express');
// determind what mode we are
var env = process.env.NODE_ENV = process.env.NODE_ENV||'developemnt';
var app = express();
//configure the view engine
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
//app.use('/public', express.static(__dirname + '../public'));
//the asterisk handles all routes includes javascript, css, html request...
app.get('*', function (req , res) {
res.render('index');
});
var PORT = 3030;
app.listen((process.env.PORT!==undefined)?process.env.PORT:PORT);
console.log('Listening to PORT : ' + process.env.PORT );
Below the index.html
<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"/>
<base href="/">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
</head>
<body ng-app="idetikApp">
<div ng-view=""></div>
<script src="app/app.js"></script>
</body>
</html>
web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="server/server.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<rule name="LogFile" patternSyntax="ECMAScript" stopProcessing="true">
<match url="iisnode"/>
</rule>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^server/server.js\/debug[\/]?" />
</rule>
<rule name="StaticContent">
<action type="Rewrite" url="public{{REQUEST_URI}}"/>
</rule>
<rule name="DynamicContent">
<conditions>
<add input="{{REQUEST_FILENAME}}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="server/server.js"/>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
app.js
angular.module('idetikApp', [ 'ngResource', 'ngRoute']);
angular.module('idetikApp').config(function ($routerProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routerProvider.when('/', {templateUrl: '/partials/main', controller:'mainctrl'})
});
angular.module('idetikApp').controller('mainctrl', function ($scope) {
$scope.mayvar = "hello world"
})
and the main.html
<h1>this is a partial</h1>
<h2>{{myvar}}</h2>
and my folder structure
but now I cant find my files inside public :(

Resources