Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm trying to design a system that allows for multiple public endpoints that funnel into a single web service. The web service must be able to determine which endpoint was the intended destination of the request. Here's a little sample configuration that might fit the bill:

Sample proxy configuration

In this system, the "reverse proxies" (for lack of a better term) add an HTTP header to the incoming requests before they hit the web service. Otherwise, the proxies are entirely transparent to the request and response.

We're a Windows shop using IIS7/WCF.

The goal is 1) to maintain only a single web service, rather than one per domain, and 2) to decouple domain/web site management from the business logic in the web service. That is, if we know that context will always be specified with a key in the HTTP header, then we don't have to worry about domains changing or the specific content of Request.Headers["HOST"].

My questions are: is this a reasonable approach? If so, is there an app out there that will do the job of the "reverse proxies"? (Squid? IIS itself?)

Thank you for the help!

share|improve this question
    
Is there something about the service itself that requires an instance per domain? –  Paul Mar 8 '12 at 4:17
    
It doesn't technically require an instance per domain - that's really what I'm trying to avoid - but the service does behave differently depending on the domain used to access it. –  ladenedge Mar 8 '12 at 4:22
1  
I was trying to understand why it is better to have reverse proxies just to have the service query look at Request.Headers["X-Extra-Header"] than having them just look at Request.Headers["Host"] without the reverse proxies, and assumed a separate service was required per domain. –  Paul Mar 8 '12 at 4:30
    
Ah, good question. I'm hoping to insulate the web service from hostnames changing, being masked by load balancers and other operational concerns. Basically, Request.Headers["HOST"] feels brittle to me. I'm certainly willing to entertain the position that this approach is excessive or unnecessarily complicated, however! –  ladenedge Mar 8 '12 at 5:51
1  
Have you considered using an API key / HMAC to provide context? –  HTTP500 Mar 12 '12 at 17:16

3 Answers 3

up vote 2 down vote accepted
+50

It sounds to me as though what you're trying to do is have a single app that does 2 wholly separate things. At a certain point theres going to be overlap in the code base and functionality, but I don't know your app well enough to help you with that. I have 2 possible solutions for you:

  1. I would try to separate the view related code out from your controllers and models if you're going the MVC direction. That would give you a cleaner separation of the business logic. One possible way to do that is to put your views into 2 separate directories, but then include code from a shared 3rd directory. That gives you one shared library that handles the backend logic while cleanly separating the presentation logic.

  2. I wouldn't be afraid of the HTTP Host header. It's required by HTTP/1.1 and all modern browsers use it. Heck, virtual hosting is entirely dependent on it and you'd be hard pressed to find an IIS or Apache admin who would tell you not to use virtual hosts on production. The big downside of course, if you're doing the header check on the application side, is you can run into some pretty ugly if/case statements. The only thing a reverse proxy setup does is look for a Host and add another header in addition to the Host. So you're really just adding more headers and complexity to your architecture with the reverse proxying.

share|improve this answer
    
Thank you for the thoughts! Regarding (1), you can think of it as switching a brand. Eg. when a new user comes in via rp2.com, we have to display the "RP2" landing page, and we have to put them in the RP2 user store. –  ladenedge Mar 13 '12 at 2:12

Firstly, your HTTP Host field should be preserved by your reverse proxy as it passes the request through. If it's not, then your proxy is wrongly (and weirdly!) configured.

Secondly, passing extra headers and identifying traffic by that is the standard and accepted way to identify traffic handled by a load balancer. For example, that's how load balancers are usually configured to inform web servers that traffic is coming in over SSL (as SSL can't be proxied at that level).

Finally, I think you may be overcomplicating your problem. Realistically how often do domain names change compared to the content behind them?! That's not really how the web is meant to work... There's nothing wrong with your application serving content based on domain name in the HTTP Host header, it's very common practice.

share|improve this answer
    
Great comments, thank you! (I wish I could spread the bounty around a bit.) –  ladenedge Mar 17 '12 at 14:23

One way to do this would be to have a small array of cloud load-balancers each aimed at your web service. Rackspace provides LBaas, and possibly others do as well.

http://www.rackspace.com/cloud/cloud_hosting_products/loadbalancers/

Full disclosure: I do work for Rackspace, however not in sales.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.