I've setup a Web Farm in IIS 8 (Windows 2012) with ARR 3.0. The Farm has two servers. Is it possible to configure all requests to be directed to a specific server (if healthy) and only if this server is not healthy, the requests to be directed to the second server?
I haven't found a solution but I implemented a workaround that solves my problem. I used the Health Test feature of the Server Farm. On the preferred server the health test url responds OK. On the secondary server the health test url checks if the preferred server is functional and responds with a HTTP status code outside the acceptable status codes if it is, or OK if it isn't.
Implementation with ASP
The Health Test URL is http://serverFarm/HealthTest.asp where 'serverFarm' is the Server Farm name given when the farm was created.
Preferred Server's HealtTest.asp
<%# LANGUAGE=JScript CODEPAGE=65001%>
<%
Response.Write('OK');
%>
Secondary Server's HealthTest.asp
<%
var XMLHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP");
var ReqURL = 'http://preferred.server.ip/HealthTest.asp';
try {
XMLHTTP.open("GET" , ReqURL, false);
XMLHTTP.send("");
if(200 == XMLHTTP.status)
{
Response.Status = "403 Primary server Active";
}
else
Response.Write('OK');
} catch (e) {
Response.Write('OK');
}
%>
Related
this is just a beginner level question looking for some advice, which the following may misuse some key terms as well because of lacking knowledge, but hopefully can deliver the key message to all of you:
Background:
my company is hosting a website in AWS, everything works fine except it cannot be loaded in China because of the well known Chinese Great Firewall that will block all unregistered/unlicensed websites outside of China; the best solution is perhaps to host a server in China and get an ICP license to be approved by the Chinese government, but that will take time and many other considerations. So we are now looking for some alternatives to let our customers from China able to read content from our site.
Main idea:
use a Cloudflare service worker to fetch HTTP resources from a given webpage first and then send the HTTP content to users by the Service Worker (since Cloudflare is accessible in China)
Example:
Let Cloudflare's registered Service Worker URL be: sample.workers.dev
Target website content to serve: google.com
When user tries to access this domain (sample.workers.dev), the service worker should try to load all HTTP content including images and scripts and css from google.com in backend, then return HTTP content to the users directly
This will work for my company's clients because we will usually generate a url and send over to the user by email or some other means, so we can send them a third party url that is accessible in China while actually loading content from our original website.
I tried all examples given by Cloudflare already: https://developers.cloudflare.com/workers/templates/
But so far no luck to archive what I want exactly.
Any thoughts?
yes, it's possible. i remember someone from Cloudflare implements it as an example.
Found it: https://github.com/lebinh/cloudflare-workers/blob/master/src/proxy.ts
However, Cloudflare workers does support streaming API now IIRC so there's a better way to do it.
/**
* HTTP Proxy to arbitrary URL with Cloudflare Worker.
*/
/**
* Cloudflare Worker entrypoint
*/
if (typeof addEventListener === 'function') {
addEventListener('fetch', (e: Event): void => {
// work around as strict typescript check doesn't allow e to be of type FetchEvent
const fe = e as FetchEvent
fe.respondWith(proxyRequest(fe.request))
});
}
async function proxyRequest(r: Request): Promise<Response> {
const url = new URL(r.url)
const prefix = '/worker/proxy/'
if (url.pathname.startsWith(prefix)) {
const remainingUrl = url.pathname.replace(new RegExp('^' + prefix), '')
let targetUrl = decodeURIComponent(remainingUrl)
if (!targetUrl.startsWith('http://') && !targetUrl.startsWith('https://')) {
targetUrl = url.protocol + '//' + targetUrl
}
return fetch(targetUrl)
} else {
return new Response('Bad Request', {status: 400, statusText: 'Bad Request'})
}
}
interface FetchEvent extends Event {
request: Request;
respondWith(r: Promise<Response> | Response): Promise<Response>;
}
WEB Server I want to connect to
I have a web service running in a private network. This server is a web service which I can see working in the browser if I set the socks proxy in the browser.
My Service
I need node.js server on my machine to use the socks proxy to connect and call the web server
My UseCase
I need to do post requests for xml data as well as do some get requests.
My Problem
My app is not able to connect to the server hidden behind the socks proxy.
I do not want to set the global proxy for node or anything, only for one part of the app.
Updated : Working Solution
While the answer directs in the correct direction, I will include the final working solution here for reference as it needed a few modifications to the examples on github
var shttp = require('socks5-http-client');
var options = {} ;
options.host = 'ip.of.web.service';
options.port = 1919; //port of webservice
options.path = '/control/getjson'; //path on webservice to get
options.socksPort = 8778; //socks proxy port
options.socksHost = 'ip.of.socks.proxy';
var req = shttp.get(options, function (res) {
res.setEncoding('utf8');
res.on('readable', function () {
callback(res); //send response to my function for further processing.
});
});
Using socks proxy is not natively supported in the built in http client object.
Following 2 libraries makes it easy to connect to http endpoints through a socks proxy. Give it a try
Use socks5-http-client for connecting to http endpoints
Use socks5-https-client for connecting to https endpoints
I started getting random 502 errors on my page. Is this connected with Azure or my website? I didn't do any changes since Thursday, so I am little skeptical about being my code.
502 - Web server received an invalid response while acting as a gateway or proxy server. There is a problem with the page you are looking for, and it cannot be displayed. When the Web server (while acting as a gateway or proxy) contacted the upstream content server, it received an invalid response from the content server.
I was checking the logs, but all it says is at which url it happens, and it happens on main root page.
In my case this happened because of an infinite loop in the code, which was only triggered in production but not on my local machine. Fixing the infinite loop obviously fixed the 502. ;-)
Update: Meta-example of the infinite loop (C#).
public IList<Model> PropertyOne
{
get
{
return !_productionOnlyCondition ? _models.ToList() : PropertyTwo;
}
}
public IList<Model> PropertyTwo
{
get
{
return PropertyOne.Where(model => model.Condition).ToList();
}
}
I hired a VPS (Windows Server 2008) with the aim of hosting a website.
So i configured IIS 7.5 to run a html website.
The website reads data (HTTP GET requests) from a little node.js application running on the same VPS on port 3000.
On the other hand, for every GET call i am getting:
failed to load resource the server responded with a status of 404 (not found)
Ok my fault. I needed to change the http request from
$.get( "/myfunction", function( data ) {
});
to
$.get( "http://localhost:3000/myfunction", function( data ) {
});
Is there a way to currently do virtual hosting with node.js server (i.e. host multiple domains under one IP) ?
Sure, you can use bouncy or node-http-proxy specifically for that.
There's also an Express solution. Check out this example.
Web browsers send a the header property 'host' which identifies the domain host they are trying to contact. So the most basic way would be to do:
http = require('http');
server = http.createServer(function(request, response) {
switch(request.headers.host) {
case 'example.com': response.write('<h1>Welcome to example.com</h1>'); break;
case 'not.example.com': response.write('<h1>This is not example.com</h1>'); break;
default:
response.statusCode = 404;
response.write('<p>We do not serve the host: <b>' + request.headers.host + '</b>.</p>');
}
response.end();
});
server.listen(80);
I would recomend express-vhost because the others solutions are based on a proxy server, it means that each one of you vhost should open a different port.