Hapijs proxy : subdomain routing to maindomain/subdomain - proxy

main domain : "mymain.com"
sub domain : "subdomain.mymain.com"
when i get call from subdomain.mymain.com , i would need to display in browser contents from mymain.com/somepath/subdomain.
i would like to use proxy options in hapi-js and do the above . But with
code like
config: {
handler: function(request, reply) {
let hostValue = request.headers.host;
let path = request.params.path;
let subdomain = hostValue.split('.')[0];
return reply.proxy({
uri: 'http://mymain.com/somepath/subdomain'
});
} \/\/end of handler
} //end of config
i am not able to achieve it . Just page is empty. This is angular based project and angular route does not get executed for this.
But if do for url : subdomain.mymain.com the below
return reply.proxy({
host: 'mymain.com',
port: 80,
protocol: "http"
});
It works fine. Any clue how get this subdomain issue resolved?

In your example, you're not placing the value of subdomain into the url, change it to look like this:
config: {
handler: function(request, reply) {
let hostValue = request.headers.host;
let path = request.params.path;
let subdomain = hostValue.split('.')[0];
return reply.proxy({
uri: 'http://mymain.com/somepath/'+subdomain
});
} \/\/end of handler
} //end of config
Changing this line:
uri: 'http://mymain.com/somepath/subdomain'
to this:
uri: 'http://mymain.com/somepath/'+subdomain
Alternatively, to clean up a bit, you could try using the mapUri config option of h2o2. Something like this:
server.route({
method: 'GET',
path: '/',
handler: {
proxy: {
mapUri: function (request, callback) {
let hostValue = request.headers.host;
let subdomain = hostValue.split('.')[0];
console.log('proxying for', subdomain)
callback(null, 'http://mymain.com/somepath/'+subdomain);
}
}
}
});

Related

Axios - Request header content-type was not present in the Access-Control-Allow-Headers list - ElasticSearch

I'm new to a lot of this technology, but I think I've diagnosed my issue and need some help. I've seen numerous posts on SO regarding this issue, but none have worked, though they have helped me diagnose issue.
I believe the issue is when I send the Header Content-Type w/ my pre-flight w/ Axios, it fails. This is possibly due to lower/case upper case? The error has lower case, but I tried both on the server without luck.
Basically, if I don't specify any header and Axios uses json as content-type, it works, but as soon as I specify Content-Type my pre-flight fails (even though I think post would work..).
Here is the elasticsearch.yml
cluster.name: "docker-cluster"
network.host: 0.0.0.0
http.cors.enabled : true
http.cors.allow-origin: "*"
http.cors.allow-methods: OPTIONS,HEAD,GET,POST,PUT,DELETE
http.cors.allow-headers: X-Requested-With,X-Auth-Token,Content-Type,Content-Length
#http.cors.allow-credentials: true
Here is my JS that I'm testing BTW w/ an Office Add-In solution in Visual Studio 2017 which I think is using IE as a browser.
Main Func:
var URL = "https://elasticsearch:9200/users/_search"
const data = {
"query": {
"match": {
"name": "freesoftwareservers"
}
}
};
Do_Axios('get', URL, data, null, false)
Do_Axios('post', URL, data, null, false)
Do_Axios:
async function Do_Axios(method, URL, data, headers, withCredentials) {
return axios({
method: method,
url: URL,
withCredentials: withCredentials,
//contentType: 'application/json', // does nothing
//data: JSON.stringify(data), //Causes urlformencoded which is wrong
data: data, //caues type to be json and I get error
headers: {
//"Content-Type": "application/json"
},
})
.then(function (response) {
console.log("Axios " + method + " response:");
console.log(response)
return response;
})
.catch(function (error) {
console.log(error);
});
}
Note: I can get/post if I comment out //data but then the post doesn't run my query. If I uncomment data then Axios uses urlformencoded but that doesn't work.
For now, I've been able to search API via urlformencoded queries, but I'd like to fix my ability to POST correctly to resolve future errors. I'm unsure if issue should be pointed to Axios or Elasticsearch if I open a request.
Well, I finally figured it out. I wonder how many of the other posts I read have similar issues... anyway, the issue was w/ my NGinX proxy server. No better way to learn about CORS then to setup an API and make CORS requests via IE! Without the below, I was still able to post w/ POSTMAN to the same URL which hit my nginx server, but the call from Axios/IE/JS Evironment failed.
I found these snippets and this was the magic that needed added to my "regular" configuration:
proxy_pass_header Access-Control-Allow-Origin;
proxy_pass_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
add_header Access-Control-Allow-Credentials true;
https://gist.github.com/sahilsk/b16cb51387847e6c3329
Here is my code as it stands, cleaned up but generic atm:
Note: I pass axios because I can't figure out how to get my Webpack to transform/polyfill my funcs in seperate js files. But I can declare axios in the main func and pass it and then I can move my funcs into separate files as needed for organization. There is likely a better way to do without passing axios and configuring webpack
Main Func:
var username = "freesoftwareservers"
var ipv4 = "192.168.1.255"
var showhelp = "false"
await Do_AddUserToES(axios,username, ipv4, showhelp)
Get_UserFromES(axios,username)
var index = "users"
var query = {
query: {
match: {
"username": username
}
}
};
Get_PostQueryToES(axios,query, index)
Funcs:
function Do_Axios(axios, method, URL, data, headers, withCredentials) {
return axios({
method: method,
url: URL,
withCredentials: withCredentials,
data: data,
headers: headers,
})
.then(function (response) {
console.log("Axios " + method + " response:");
console.log(response)
return response;
})
.catch(function (error) {
console.log(error);
});
}
function Get_ESURL(Bool_Search, Bool_Doc, Bool_Update, Opt_Index, Opt_IndexKey) {
var ESUrl = "https://elasticsearch:9200"
var ESSearch = "/_search"
var ESDoc = "/_doc"
var ESUpdate = "/_update"
var ReturnURL = ESUrl
if (Opt_Index != undefined) { ReturnURL = ReturnURL + "/" + Opt_Index }
if (Bool_Search == true) { ReturnURL = ReturnURL + ESSearch }
if (Bool_Doc == true) { ReturnURL = ReturnURL + ESDoc }
if (Bool_Update == true) { ReturnURL = ReturnURL + ESUpdate }
if (Opt_IndexKey != undefined) { ReturnURL = ReturnURL + "/" + Opt_IndexKey }
console.log("ReturnURL:" + ReturnURL)
return ReturnURL;
}
function Do_AddUserToES(axios, username, ipv4, showhelp) {
var adduser = {
"username": username,
"ipv4": ipv4,
"showhelp": showhelp
};
var URL = Get_ESURL(false, true, false, "users", username)
return Do_Axios(axios, 'post', URL, adduser, null, false);
}
function Get_UserFromES(axios, username) {
var URL = Get_ESURL(false, true, false, "users", username)
return Do_Axios(axios, 'get', URL, null, null, false);
}
function Get_PostQueryToES(axios, query, index) {
var URL = Get_ESURL(true, false, false, index)
return Do_Axios(axios, 'post', URL, query, null, false);
}

proxy with hapi.js and h2o2, connection close

I try to configure hapi.js to proxy requests from /{params*} path to http://localhost:3000. It works fine for root '/' but when I try call /login I receive Cannot GET /login and on request I can see 'GET /login HTTP/1.1\r\nHost: localhost:3000\r\nConnection: close\r\n\r\n'. On my UI server http://localhost:3000/login works fine.
this is my proxy configuration
proxy: {
mapUri: (request, callback) => {
//loaded from a configuration file
let url = `http://localhost:3000${request.path}`;
callback(null, url);
}
}
Anyone know how to configure hapi proxy to pass custom routes?
Acctually it started to work. This is my current route
{
method: 'GET',
path: '/{param*}',
config: {
handler: {
proxy: {
mapUri: (request, callback) => {
let tls = conf.ui.tls;
let host = conf.ui.host;
let port = conf.ui.port;
let url = `${tls ? 'https://' : 'http://'}${host}:${port}${request.path}`;
callback(null, url);
}
}
}
}
}

SignalR not working with DelegatingHandler

We have a delegating-handler that catches requests with a certain url prefix, and then reroutes them behind the firewall with the fed auth cookie attached...
This is working for our WebApi layer, but SingalR is firing off requests on its own while it is trying to connect that doesn't follow the pattern... I can't figure out how to force it to use the proper url prefix.
This is the url that is generated from the post request when it is trying to do long-polling: https://localhost:44330/signalr/connect?transport=longPolling&
See that it hasn't put the '/qsixlsignalr' into the url, which my delegating handler will be looking for.
var signalRBaseURL = "/qsixlsignalr"
$(function () {
// http://stackoverflow.com/questions/15467373/signalr-1-0-1-cross-domain-request-cors-with-chrome
$.support.cors = false;
var connection = $.hubConnection(signalRBaseURL);
var myHub = connection.createHubProxy('xlHub');
myHub.on('notify', function (message) {
alertsViewModel.refreshActiveCount(localStorage.getItem(PROJECT_ID));
if (window.location.pathname == '/' || window.location.pathname == '') {
alertsViewModel.refresh(localStorage.getItem(PROJECT_ID));
}
toastr.success(message);
});
connection.disconnected(function () {
setTimeout(function () {
connection.start();
}, 3000);
});
connection.logging = true;
connection.start();
});
If I remember correctly you need to tell SignalR explicitly that you don't want to use the the default url
var connection = $.hubConnection(signalRBaseURL, { useDefaultPath: false });

Laravel 4 + AngularJS (AJAX Request)

im having a problem retrieving information using my Angular Service from my back end (Laravel 4)
Im just getting error 404
this is my angular service
angular.module("SistelApp.Services.ArticleService", [])
.factory("ArticleService", ["$http", function($http) {
var doRequest = function(location) {
return $http({
method: 'GET',
url: "http://localhost/sistel/" + location + "Service"
});
};
return {
articles: function(location) {
return doRequest(location);
}
};
}]);
this is the laravel route:
Route::get("/homeService", "HomeController#getArticles");
homeController
public function getArticles() {
$array = array();
$array["name"] = "myName";
$array["lastname"] = "myLastName";
return Response::json($array);
}
Using Postman (the chrome app) if i go to the route 'HomeService' i succesfully get the data back in json format... but in my angular app i get Error 404 for /HomeService
am i missing something???
It looks like there is mistake in your code. You are missing '+':
var doRequest = function(location) {
return $http({
method: 'GET',
url: "http://localhost/sistel/" + location + "Service"
});
};
I fixed it! ... I WAS MISSING SOMETHING...
the url: "http://localhost/sistel/" + location + "Service" IS WRONG
because Laravel is routing from "http://localhost/sistel/public/
... adding the "public/" fixed my issue.. ty anyway :D

URL Rewriting with ExpressJS

I would like to rewrite my URLs on my ExpressJS website. I've used this plugin, https://github.com/joehewitt/express-rewrite, but it doesn't work...
However, I might have made a mistake...
My app.js file :
var express = require('express')
, index = require('./routes/index.js')
, admin = require('./routes/admin.js')
, contact = require('./routes/contact.js')
, posts = require('./routes/posts.js')
, http = require('http')
, path = require('path')
, hash = require('./auth').hash
, db = require('./models')
, favicons = require('connect-favicons')
, rewriter = require('express-rewrite');
var app = express();
app.configure(function () {
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon(__dirname + '/public/images/FAVICON.ico'));
app.use(favicons(__dirname + '/public/images/apple-touch-icon.png'));
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.cookieParser());
app.use(express.cookieSession({
secret: 'SECRET',
cookie: { access: false }
})
);
app.use(rewriter);
app.use(app.router);
app.use(function(req, res, next){
res.render('404.jade', {
title: "404 - Page Not Found",
showFullNav: false,
status: 404,
url: req.url
});
});
});
app.configure('development', function () {
app.use(express.errorHandler());
});
app.get('/', index.index);
app.get('/toto', rewriter.rewrite('/heytoto'));
db.sequelize.sync().complete(function(err) {
if (err) {
throw err
} else {
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'))
})
}
});
My error message :
Express
500 TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'match'
at Object.rewriter [as handle] (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express-rewrite/rewrite.js:3:26)
at next (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/proto.js:199:15)
at Object.cookieSession [as handle] (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/cookieSession.js:113:5)
at next (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/proto.js:199:15)
at Object.cookieParser [as handle] (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js:60:5)
at next (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/proto.js:199:15)
at resume (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/static.js:60:7)
at SendStream.error (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/static.js:73:37)
at SendStream.EventEmitter.emit (events.js:126:20)
at SendStream.error (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/send/lib/send.js:147:51)
You could rewrite the URL before you get to the handler you want to use.
app.use(function(req, res, next) {
if (req.url === '/toto') {
req.url = '/heytoto';
}
next();
});
app.get('/heytoto', ...);
I've used a similar method to do URL rewrites with regular expressions.
So I had sort of the same issue. I wrote an app that uses the history API on browsers and I wanted to rewrite all non-static URLs back to index.html. So for static files I did:
app.configure(function() {
app.use('/', express.static(__dirname + '/'));
});
But then for the history API generated paths I did:
app.get('*', function(request, response, next) {
response.sendfile(__dirname + '/index.html');
});
This meant that any request that wasn't a file or directory in / (such as a URL generated by the history API) wouldn't be rewritten or redirected but instead the index.html file will be served and that then does all the JS routing magic.
Hopefully that's close to what you're looking for?
A solution that works without response.sendfile(..) is to use a rewrite middleware that is inserted prior to app.use(express.static(..)) like this:
// forward all requests to /s/* to /index.html
app.use(function(req, res, next) {
if (/\/s\/[^\/]+/.test(req.url)) {
req.url = '/index.html';
}
next();
});
// insert express.static(...)
This way, expressjs properly recognizes the rewrite. The static middleware will then take care of serving the file.
1) Your rewrite middleware must appear before the middleware/function that will handle the request.
Won't work:
app.use('/hello', () => sayHello() );
app.use(() => rewriteURLToHello()); //it's too late to try to rewrite a URL to /hello
Will work:
app.use(() => rewriteURLToHello()); //we can rewrite a URL to /hello
app.use('/hello', () => sayHello() ); //rewritten URL will be handled here
2) Your middleware must not be bound to the path you're trying to rewrite
Won't work:
app.use('/hello', (req, res, next) => {
//'/hello' has been trimmed from req.url
//req.url is / if the request was for /hello
req.url = '/goodbye'; //technically setting full path to /hello/goodbye
next(); //will only call other middleware in the /hello chain
});
app.use('/goodbye', () => sayBye()); //won't work
Will work:
app.use((req, res, next) => { //runs for every path. Same as .use('/',
//'/hello' has NOT been trimmed from req.url
//req.url is /hello if the request was for /hello
if (req.url.startsWith('/hello')) {
req.url = '/goodbye'; //full path now /goodbye
}
next(); //will continue calling all middleware
});
app.use('/goodbye', () => sayBye()); //will work
you could check the url with an if condition and use app.redirect to redirect to a certain url.
Try this:
app.get('/toto', function(req, res) {
res.redirect('/heytoto');
});

Resources