Initial commit for http_helper app

This commit is contained in:
JP Schneider 2014-05-25 18:54:37 -05:00
Родитель ba37aeae46
Коммит ddca895d91
5 изменённых файлов: 209 добавлений и 3 удалений

Просмотреть файл

@ -1,4 +1,46 @@
http_helper
===========
# http_helper
A lightweight NodeJS app to provide redirect and proxy service, based on an included config file
# OVERVIEW
A simple node.js redirector and proxy application. Given a config file full of
redirect and proxy mappings, this application will match incoming HOST headers
and take the appropriate action by 301/302 redirecting or proxying.
This is useful for redirecting www to root domains, redirecting old domains
to new domains, proxying for SSL from non-SSL sources on AWS.
# PREREQUISITES
* node.js (v0.10.28 preferred)
* npm (comes with node.js)
# PREFLIGHT
* mv ./config-json.dist to ./config.json
* Update mappings for redirects/proxies based on your needs
As an example, if we wanted to setup a redirect to yourdomain.com
from www.yourdomain.com, we would add the following block in config.json:
"www.yourdomain.com": {
"host": "http://yourdomain.com",
"code": 301,
"function": "redirect"
},
(*Note*: The function setting can be either redirect or proxy)
# RUNNING THIS APPLICATION
Simply run node ./bin/server.js
# FURTHER INFORMATION
Author: JP Schneider (Github: jdotpz, jp@mozillafoundation.org)
Bugs/Requests: https://www.github.com/mozilla/http_helper/issues
* New Relic monitoring is written into this application. Simply provide your own
newrelic.js or config settings and it will just work.
* Messina is an amazing GELF log utility written by Brian Brennan (brianloveswords). To output
to your own GELF facility, set the following env variables
export GRAYLOG_HOST="address.to_your_logging_server.com" #defaults to localhost
export GRAYLOG_PORT=12201 #defaults to 12201
export GRAYLOG_FACILITY="httphelper-production" #defaults to openbadger
export ENABLE_GELF_LOGS=true

11
bin/server.js Normal file
Просмотреть файл

@ -0,0 +1,11 @@
#!/usr/bin/env node
if ( process.env.NEW_RELIC_ENABLED ) {
require( "newrelic" );
}
var config = require("nconf")
.argv()
.file({file:__dirname+"/../config.json"});
var helperApp = require('../lib/brain')(config.get('appOptions'), config.get('port'));
console.log('Running redirector / proxy application');

20
config-json.dist Normal file
Просмотреть файл

@ -0,0 +1,20 @@
{
"port": 80,
"appOptions": {
"host.answering_the_request.com": {
"host": "http://the.target_host.com/target/path",
"function": "proxy"
},
"a-host.youwant": {
"host": "http://the_url.to_redirect_to.com/path/to/redirect/to",
"code": 301,
"function": "redirect"
},
"a-host.youwant": {
"host": "http://the_url.to_redirect_to.com/path/to/redirect/to",
"code": 301,
"function": "redirect"
}
}
}

84
lib/brain.js Normal file
Просмотреть файл

@ -0,0 +1,84 @@
var http = require('http');
var request = require('request');
var express = require('express');
var app = express();
// Messina allows for GELF logging
var messina = require('messina');
var log = messina('myapp');
// app.use(log.middleware({ combinedOutput: true }));
module.exports = function (appOptions, port) {
app.use(log.middleware({ combinedOutput: true }));
// A simple healthcheck endpoint for load balancers to watch
app.get('/healthcheck', function(req, res){
res.send('healthcheck');
console.log('Request to ' + req.protocol + ':://' + req.host + '/' + req.path + ' returned a ' + res.statusCode );
});
// Any other path or route takes us to this block
app.get('*', function(req, res){
var requestHost = req.headers.host.split(':')[0];
var hostOptions = appOptions[requestHost];
// We only want to allow http protocol
if(req.protocol != 'http'){
console.log(req.protocol + 'is not a valid protocol');
res.send(req.protocol + ' is not a valid protocol for this app');
res.end();
return;
}
// We are only proxying or redirecting with GETs
if(req.method != 'GET'){
console.log(req.method + ' is not an acceptable method');
res.end();
return;
}
// If the host header does not have a corresponding entry in
// the config.json file, bust out.
if(!hostOptions){
console.log(req.host + ' is not a valid host');
res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain');
res.end(req.host + ' is invalid');
return;
}
// actionOptions dictates whether this is a proxy or redirect
var actionOptions = hostOptions.function;
// For requests that match a redirect host
if(actionOptions === "redirect"){
var url = hostOptions.host + req.url;
// Set the status and redirect
console.log('Redirecting ' + req.protocol + '://' + req.host + ' to ' + hostOptions.host + ' with a http status code of ' + hostOptions.code);
res.statusCode = hostOptions.code || 302;
res.setHeader('Content-Type', 'text/plain');
res.setHeader('Location', url);
res.end('Redirecting to '+url);
}
// For requests that match a proxy host
if(actionOptions === "proxy") {
var url = hostOptions.host + req.url;
request.get(url, function(error, result) {
if (error) {
res.write("there was an error requesting " + req.protocol + '://' + hostOptions.host);
res.write( JSON.stringify(error) );
return console.error(error);
}
console.log('Pulling ' + url + ' to ' + requestHost);
res.write( result.body );
res.end();
return;
});
}
});
app.listen(80) ;
}

49
package.json Normal file
Просмотреть файл

@ -0,0 +1,49 @@
{
"name": "mofo_http_manipulator",
"version": "0.0.3",
"author": "JP Schneider jdotpz",
"description": "A http manipulator cobbled together for use in MoFo infra, with code from git://github.com/pksunkara/node-redirect.git",
"main": "",
"repository": {
"type": "git",
"url": "git://github.com/jdotpz/mofo_http_manipulator.git"
},
"keywords": [
"redirect",
"302",
"server",
"proxy",
"http"
],
"homepage": "http://github.com/jdotpz/mofo_http_manipulator",
"scripts": {
"start": "./server"
},
"contributors": [
{
"name": "JP Schneider, Pavan Kumar Sunkara, Pomax",
"email": "jp@mozillafoundation.org"
}
],
"dependencies": {
"nconf": "0.6.x",
"newrelic": "*",
"messina": "0.1.1",
"habitat": "*",
"request": "*"
},
"devDependencies": {},
"engines": {
"node": ">=0.6"
},
"bugs": {
"url": "https://github.com/jdotpz/mofo_http_manipulator/issues"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/pksunkara/node-redirect/raw/master/LICENSE"
}
],
"analyze": false
}