I need to serve a script file from a third-party server as if it is coming from my own server. Should be a simple reverse proxy thing with url rewrite.
Prerequisites:
IIS has Url Rewrite 2.0 and ARR 3.0 installed.
What works:
when I set up an empty localhost website in IIS and add a simple rewrite rule like
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" enabled="true" stopProcessing="true">
<match url="localJs/proxiedScriptFile.js" />
<action type="Rewrite" url="https://thirdpartyserver.de/js/script.js" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I can navigate to localhost/localJs/proxiedScriptFile.js and I get correctly served https://thirdpartyserver.de/js/script.js instead. So ARR and Rewrite is working.
What doesn't work:
When I add the same rewrite rule to the web.config of my existing Umbraco 8 website (on the same IIS), I get a HTTP 404.4 error, as if ARR does not work.
What I tried:
If in Umbraco 8, I change the rewrite to point to a local dummy file of
the same type, it works - the local dummy file is served. But the file off the third-party server is not.
Adding the rewrite path or url to
Umbraco.Core.ReservedUrls or Umbraco.Core.ReservedPaths does not
change the problem.
Any idea what I am facing here?
Kind regards!
Mikael
I solved my problem by using an OWIN middleware as a proxy, rather than using UrlRerwrite/ARR. This worked right away.
If someone comes up with a pure UrlRewrite/ARR solution, I am still interested. Here what works for me:
I found this ReverseProxyMiddleware for .Net Framework. Using this, my OwinStartup contains the following code:
public override void Configuration(IAppBuilder app)
{
// this must come before the base implementation so proxy kicks in before Umbraco
app.UseProxy(
new List<ProxyRule> {
// script proxy
new ProxyRule {
Matcher = uri =>
uri.AbsoluteUri.Contains("localJs/proxiedScriptFile.js")
,
Modifier = (req, user) => {
req.RequestUri = new Uri("https://thirdpartyserver.de/js/script.js");
},
RequiresAuthentication = false
}
},
r =>
{
}
);
base.Configuration(app);
}
Works like a charm. I post it here in case somebody else faces the same challenge.
I recently started working on nodejs. I created a simple nodejs api (with express) which connect to SQL server database and return result. After my development I had challenge how to host this node js api. I decided to host my api on IIS. I got different errors and in the end I was able to make it work. Thanks to different articles on internet.
Below are the steps I followed. May be this can help anyone who is new and trying to host nodejs in windows IIS.
I recently started working on nodejs. I created a simple nodejs api (with express) which connect to SQL server database and return result. After my development I had challenge how to host this node js api. I decided to host my api on IIS. I got different errors and in the end I was able to make it work. Thanks to different articles on internet.
Below are the steps I followed. May be this can help anyone who is new and trying to host nodejs in windows IIS.
Step 1: Install IISnode. Make sure to select correct bit version as per your machine. I was using windows 10 64 bit. I installed iisnode-full-v0.2.21-x64.msi
https://github.com/azure/iisnode/wiki/iisnode-releases
Step 2: Install URL rewrite module
https://www.iis.net/downloads/microsoft/url-rewrite
Step 3: For my use I created a new website in IIS with name "Node Web Site". This site is running on port 90. Point this web site to physical path where your Nodejs api is available.
Step 4: Provide node js api folder access to "IIS_IUSRS" group. You will get access error if don't provide access.
Step 5: Add a web.config file in your node js api folder. Add below code in your config file. This will tell IIS that server.js will be handled by IISnode.
Note: I have only one file in my project (server.js). If you have multiple files then you can add all those files here.
<configuration><system.webServer><handlers><add name="iisnode" path="server.js" verb="*" modules="iisnode" /></handlers>
</system.webServer></configuration>
Step 6: Add URL rewrite rule in your config file. This is required to make url user friendly. otherwise you need to provide .JS file path in the url. below is the final config file which I have in my application.
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="api">
<match url="api/*" />
<action type="Rewrite" url="server.js" />
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<hiddenSegments>
<add segment="node_modules" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>
Before Rewrite section I was calling my application with url http://localhost/nodesample1/server.js
After rewrite url can be like
http://localhost/nodesample1/api
Step 7: Now you need to make changes in get call of express. you need to provide full path in get call.
for example before hosting application in IISNode my default get call code was like below snippet
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser());
app.get('/', function (request, response) {
response.write('running');
response.end();
});
But after IISNode hosting I had to change my get call like below
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser());
app.get('nodesample1/api', function (request, response) {
response.write('running');
response.end();
});
As I want me url to be like "http://localhost/nodesample1/api" I had to provide complete path in get call.
That's it.
This approach worked for me.
I have a MEAN (Angular 2) app working on a Windows Server.
I run my app with iisnode on the server.
The app works fine, but at some point I try to spawn a child process with node (powershell.exe). Everything works fine locally (the powershell script executes successfully) but when I test it from the server URL, the child-process never spawns.
I don't have any error message, the app just kinda pauses itself.
When I run node.js from the command prompt with "node server.js" and I go to : http://myserver.com:9000 then the app works fine and the child-process spawns sucessfully.
I've tried to put the absolute path of powershell.exe but it doesn't work neither.
localhost:9000 : app works, child-process spawns ans works fine
myserver.com:9000 : app works, child-process spawns ans works fine
myserver.com/ : app works, child-process won't spawn, no error message
Here's my web.config file :
<configuration>
<system.webServer>
<!-- indicates that the hello.js file is a node.js application
to be handled by the iisnode module -->
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="server">
<match url="/*" />
<action type="Rewrite" url="server.js" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
And here's the route .js from where I spawn the child-process :
child = spawn("powershell.exe",[`some commands`]);
child.stdout.on("data",function(data){
console.log("Powershell Data: " + data);
});
child.stderr.on("data",function(data){
console.log("Powershell Errors: " + data);
});
child.on("exit",function(){
console.log("Powershell Script finished");
//some other commands
});
child.stdin.end();
Finally, it appeared that the powershell.exe was spawning correctly.
However, the powershell script was supposed to open Powerpoint and do some actions within it. That part wouldn't work, and powershell would raise this error :
Insufficient memory to continue the execution of the program
This was solved by modifying DCOM config, as suggested here : How to deploy COM object Microsoft.Office.Interop to IIS so that my C# WCF service reference will work?
When deploying a node.js / express app to Azure Websites I am getting "Cannot GET /" error in the browser. The same application runs flawlessly on the local machine.
web.config is standard (I only removed the Static Rewrite rule), so:
<!-- 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="src/server/app.js"/>
</rule>
</rules>
Code is deployed in src/server/ (node functions) and src/client/ (static content) folders.
As per the FREB logs the src/server/apps.js is fetched, but in the end the following error is thrown:
ErrorCode The system cannot find the file specified. (0x80070002)
Inside app.js I have the following configuration for static files:
app.use(express.static('./src/client/'));
Azure Websites runs node from the folder where the file defined in the package json as the start file is located, so e.g. for the following:
"start": "node src/server/app.js"
fact it will run node app.js from the src/server folder (you can find there also the iisnode.yml file). Which results in all relative paths getting messed up. One solution for this is to use absolute paths, so e.g.:
app.use(express.static('D:/home/site/wwwroot/src/client/'));
and switching between paths using e.g. process.env.NODE_ENV variable.
Take for instance angular2-quickstart. What files need to be deployed and what settings need to be set to launch this web app from IIS?
This is a Typescript tutorial that I have opted to compile to JavaScript.
Setting up Angular 2 for me was quite an issue because the HTML5 routes (without a hashbang) weren't working.
To get an Angular2 project working on an IIS environment without serving it using the Angular-CLI (you still need it to build it!):
After you're finished with development on your project, you'll need to build (or compile) it to a different environment. If you need to set that up, read this.
The shortest build command you need is:
ng b
In your build folder (if you didn't add an external/different folder, this will be the 'dist' folder in your project), copy the contents to your IIS server.
Ensure the folder of your IIS server has the needed permissions for the IIS_IUSRS group and IUSR user to access it. (Right click on the folder -> Properties -> Security -> Edit -> Add, and type those in. You can click the 'Check Name' button to ensure it's the correct ones you're typing in)
The next issue you need to tackle is getting a web.config file to put in your server folder to fix routing issues.
If we were working with Apache, we would need an .htaccess, but for IIS, we're using a web.config. The one found here worked for me if your application is routing from the root directory of your server.
(Note: As reminded by #Demortes, this will require an additional module to be added to your IIS environment called URLRewrite)
This (web.config) file goes in the root directory of your server.
Hope this helps anyone who had similar issues to me :)
Cheers.
Download and install IIS rewrite plugin https://www.iis.net/downloads/microsoft/url-rewrite
Create application under default website.
Create a folder in c:\inetpub\wwwroot to host the application
After step 8 copy dist folder contents to c:\inetpu\wwwroot\
Before build in index.html change base href="/" to base href="//"
To skip steps 1,2 and 3 for every new build check out step 9 as alternative to step 8
Web config structure.
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Main Rule" >
<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="/<appname subfolder>/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Note: Create a Web.config in src folder and add a reference to it in angular-cli.json in assets section so that it gets copied over during each build. -
Otherwise you will have manually create this file every time ng build is used.
not applicable
In angular-cli.json put web.config in assets block
"assets": [
"assets",
"favicon.ico",
"Web.config"
],
In angular-cli.josn put custom css path example so that it will be packaged in styles..bundle.cs
"styles": [
"../node_modules/font-awesome/css/font-awesome.min.css",
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"assets/site.css",
"assets/page.css",
"assets/menu.css",
"styles.css",
"../node_modules/primeng/resources/primeng.min.css",
"../node_modules/primeng/resources/themes/omega/theme.css"
],
If you have custom scripts put those path under scripts section example
"scripts": [
"../node_modules/jquery/dist/jquery.js",
"index.js"
],
ng build --prod
Note: ng build --prod starts AOT (ahead of time compilation) by default in latest version of angular-cli
Note: ng build command deletes dist folder and recreates that folder every time you ng build command
Alternative build command:
ng build --prod --output-path 'C:\inetpub\wwwroot\<appname subfolder>' --base-href /<appname subfolder>'/
a- if you don't want to manually update base-href in index.html
b- if you don't want to copy dist folder and wwwroot folder of app.
Note1: Following command will only work if you open visual code (or any terminal app) with administrative privileges. Otherwise mkdir command to create output folder in wwwroot will fail.
Note2: You still need to update Web.config with . See step 4
Note3: Checkout slash / at both starting and end of --base-href /'/
Check direct quote from one of the posting. Not sure if changing security privileges of IIS_IUSRS group and IUSR user for ...wwwroot\
as described in one of the web links is required. May be it is not required but I am highlighting it over here for you to keep in mind.
Direct quote from another use : " Ensure the folder of your IIS server has the needed permissions for the IIS_IUSRS group and IUSR user to access it. (Right click on the folder -> Properties -> Security -> Edit -> Add, and type those in. You can click the 'Check Name' button to ensure it's the correct ones you're typing in)"
References :
- How and what to deploy Angular2 to IIS
- https://www.youtube.com/watch?v=K0XORWxG11k
The webapp itself needs no server intelligence, as it is just static files - web assets ( *.js, *.html files etc). The static files are what angular2-quickstart generates as output of its build process, which you run in your dev environment (probably locally on your personal computer). The dev environment will need node (+ npm). And infact, you can test this tutorial on your local dev environment without the need for any external server.
edit:
If u look in the package.json u can see it has lite-server:
"scripts": {
"start": "npm run lite",
"lite": "lite-server"
},
Lite server is a small server that simulates a simple (web) file server.
Lightweight development only node server that serves a web app, opens
it in the browser, refreshes when html or javascript change, injects
CSS changes using sockets, and has a fallback page when a route is not
found.
To give you an answer, to serve your app with IIS, you only need http://docs.asp.net/en/latest/fundamentals/static-files.html
I have created a small github project that has Angular2 current as of today (10/13/2016) that runs in IIS 7.5 with routing and under ng serve.
It does use the hash based URL strategy.
It uses angular-cli, the read me has details on how to setup under IIS or ng serve.
https://github.com/howserss/Angular2-IIS-sample-app
Angular 2 routing (with hash) will work without any issue on IIS. Just create default URL rewrite rule which will redirect all the requests to index.html file of your angular app. Rule will redirect all requests to index.html except for required js files and actual angular app urls (i.e. index.html or index.html#/{route-value}.
EX:
<rules>
<rule name="Default">
<match url="(.* ).js|index.html(.*)" negate="true" />
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
Angular 2 routing (without hash) will not work with IIS.
In case of pure HTML application IIS will be routing the incoming request and it will redirect the request to error page if such page does not exist at that location.
In case of .Net MVC application you can create a default route to handle all the incoming request url's and redirect it to your angular index view.
Ex Route for MVC application:
routes.MapRoute(
name: "Angular",
url: "{*url}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { url = new AppFeatureUrlConstraint() }
public class AppFeatureUrlConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (values[parameterName] != null)
{
var url = values[parameterName].ToString();
if (url.StartsWith("angular/", StringComparison.InvariantCultureIgnoreCase))
return true;
else
return false;
}
return false;
}
}
Here is a nice and detailed explanation for deploying angular app in IIS. The summarized steps for publishing as a separate website are as follows:-
Create a web site in IIS, lets say the physical path you provided for this web application is C:\Publish.
publish you angular app using the below command:-
ng build --prod
After the application is built successfully copy and paste the contents of dist folder to C:\Publish folder.
Add web.config file to folder C:\Publish with following contents:-
<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="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
All done, now just go to IIS and browse your web-site, you will see it working.
after you build it, copy all files in dist fold put in a fold in your IIS server, it only contains html, css and js files, so just host it like a static website.
It works for any web server, no matter Apache, IIS or nginx.