Can an iisnode-hosted web application work out the virtual path at which it is hosted?
Asked Answered
Z

4

6

I am using iisnode to host a node web application in IIS on Windows. When I set up my routes on the web server (say Express or Restify) I want do do it in a way that is independent of the path that IIS is hosting the application at.

For example, my application could be hosted at two different paths on two machines running IIS; the first could host it at /foo and the second at /bar. Say my application wants to set up a route at /baz - on the first machine I would need to configure the route at /foo/baz and on the second I would have to use /bar/baz which means duplicating some of the configuration held in IIS.

Is it possible to reliably work out the path from within an application hosted with iisnode so that I can calculate the correct routes to set up? Or is there another technique I can use to avoid needing to do so?

Zahara answered 10/5, 2012 at 18:36 Comment(0)
D
3

I am not aware of a way to avoid seeing the path segment corresponding to the virtual directory within your node.js application hosted in iisnode. The best way to ensure your application code is host agnostic is to host it at the root of an IIS web site.

Dishwasher answered 10/5, 2012 at 19:2 Comment(3)
That's not possible in my case :(Zahara
This is such a pity... It is quite a pain having to use the virtual directoy in all paths (images, stylesheets, routes, redirections...)Objectionable
is this a limitation in iisnode itself? or is it a limitation in one of iisnode's dependencies?Ternan
O
2

@GraemeF: This is a little hacky, but this is who I got around this limitation.

First, I added a global variable to my app called home:

var express = require('express'),
    app = express.createServer(),
    home = process.env.deployPath || '';

Then, I set up my routes using the home variable:

app.get(home + '/baz', function(req, res) {
    res.send('This is the /baz route');
    res.end();
});

Then, it's just a matter of setting the deployPath appSetting in your apps web.config:

Machine 1:

<appSettings>
    <add key="deployPath" value="/foo" />
</appSettings>

Machine 2:

<appSettings>
    <add key="deployPath" value="/bar" />
</appSettings>

You can manually set the value on each machine, have your build process set the value, or even add the setting to the target machine's global web.config.

Oram answered 27/6, 2012 at 13:37 Comment(3)
@Tomasz, would it be possible to set an process environment variable to the HttpRuntime.AppDomainAppVirtualPath? Normally, I would just submit a pull request, but I don't know C++ at all.Oram
That's pretty much what I did, but it isn't really working out what the path is, we're just cheating by telling it! I'd really like to avoid having to add this extra configuration step. (also, I don't know if Tomasz will see your suggestion there!)Zahara
I also created an issue in github.Oram
O
1

This answer suggests getting the path from the web.config file.

Also, this link might be of some help as well:

The solution turns out to be well addressed, at least for "express" framework apps using app.use()

When you call app.use(app.router), you can pass a namespace prefix for your virtual directory and then requests will succeed BUT who would want to hard-code their virtual directory name into their app [yuck!]?

The solution turns out to be quite simple because IISNODE promotes appSettings to environment variables. Taking advantage of this fact, you can add an entry to the apps web.config such as:

<appSettings>
        <add key="appvirtdir" value="/nodetest" />
</appSettings>

Then you can make one simple modification to your server.js file like this:

app.configure(function () {
....
    app.use(process.env.appvirtdir || '', app.router);
....
});
Objectionable answered 20/11, 2015 at 11:46 Comment(0)
C
0

Both express and restify allow the definition of paths with regex. By using regex paths you can avoid prefix issues entirely.

Instead of

server.get({ path: '/virtual/directory/structure/status/',...

use

server.get({ path: /.*\/status/,...

and there'll be no need for any magic.

Cartage answered 16/9, 2016 at 4:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.