Handle the MEAN-stack application address without fragment '#' - javascript

Edit 1: Here is a mini code I made that reproduces the error. Please follow README.md to install.
Edit 2: Finally, I found one solution. Besides $locationProvider.html5Mode(true); ($locationProvider.hashPrefix('') is NOT necessary for me) and <base href="/" />, I need to add the follows in routes/index.js, rather than app.js. Then, we do NOT need to add anything more to app.js or nginx or apache like this thread mentions.
var express = require('express');
var router = express.Router();
var path = require('path');
... ...
router.get('*', function(req, res) {
res.sendfile('./views/index.html'); // load our public/index.html sendFile
// res.sendFile('index.html', { root: path.join(__dirname, 'views') }); // does not work
});
One problem is, in the server console, it gives express deprecated res.sendfile: Use res.sendFile instead routes/index.js:461:9. But res.sendFile('index.html', { root: path.join(__dirname, 'views') }); can not help, it returns 404 error.
My express version is ~4.14.0... does anyone know how to fix that?
OP:
I develop in Mac with Apache a MEAN-stack application that can be requested by
https://localhost:3000/#/home. In production with an NGINX server, the application can be requested by
https://www.myapp.io/#/home. The fragment-identifier # is needed in all cases because of angular ui-router.
So I wanted to make pretty url without # (eg, https://www.myapp.io/home, https://localhost:3000/home) work. I have done the following:
added $locationProvider.html5Mode(true); $locationProvider.hashPrefix('') in app.config(['$stateProvider'....
added <base href="/" /> in index.html
As a result, https://localhost:3000/#/home changes automatically to https://localhost:3000/home in the browser bar, similarly for https://www.myapp.io/#/home.
However, directly entering https://localhost:3000/home or https://www.myapp.io/home in the browser will raise an error (I don't know how to turn previous <h1><%= message %></h1><h2><%= error.status %></h2><pre><%= error.stack %></pre> in error.ejs to error.html, so I don't have more details).
So now, the goal is to make https://localhost:3000/home and https://www.myapp.io/home work.
By following this thread, I added the follows to app.js:
app.use('/js', express.static(__dirname + '/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));
app.all('/*', function(req, res, next) {
res.sendFile('index.html', { root: __dirname });
});
And in Apache of Mac, here is my httpd-vhosts.conf, after restarting apache,
https://localhost:3000/home still returns an error.
<VirtualHost *:443>
ServerName localhost
DocumentRoot "/Users/SoftTimur"
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile /etc/apache2/ssl/localhost.crt
SSLCertificateKeyFile /etc/apache2/ssl/localhost.key
<Directory "/Users/SoftTimur">
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
Require all granted
</Directory>
</VirtualHost>
In production, here is the NGINX server block. After restarting NGINX, https://www.myapp.io/home still returns an error.
server {
listen 443 ssl;
server_name myapp.io www.myapp.io;
ssl_certificate /etc/letsencrypt/live/myapp.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myapp.io/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:EC$
ssl_session_timeout 1d;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
index index.html;
root /opt/myapp;
location / {
try_files $uri $uri/ /index.html;
}
location ~ /.well-known {
allow all;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Accept-Encoding "";
proxy_set_header Proxy "";
proxy_pass https://127.0.0.1:3000;
# These three lines added as per https://github.com/socketio/socket.io/issues/1942 to remove sock$
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Could anyone help?

This might useful stuff,
AngularJS routing without the hash '#'
Also, use this line in your express server file.
app.use(express.static(path.join(__dirname, 'client folder')));
this will directly finds your index.html file in that views folder and loads it

try this in your express server
var express = require('express');
var app = express();
app.get('*', function (req, res) { res.sendFile(__dirname + '/views/index.html'); });
and in your angular app:
$locationProvider.hashPrefix('!').html5Mode({
enabled: true
});
$urlRouterProvider.otherwise('/');
and you still need the <base href="/"> in your index.html
let me know if this works for you
EDIT:
I just found your app in https://github.com/chengtie/mini-mean,
looks like your app.use order is wrong. Please copy paste this in your express server and check if it's okay now. pastebin

You don't need Apache or Nginx to run NodeJs in development, just node server.js is enough
Express gave you that error because you are using a deprecated API res.sendfile please use res.sendFile (capital F)
Some info for doing SPA:
When you have the '#' in your URL, the browser interpret it as a local reference and thus, won't send new request to the server
By enabling $locationProvider.html5Mode(true) you are now using html5 push state to navigate around your application history and (if I'm not mistaken you are happening to be using) angular effectively remove the '#' in url
Without the '#' (hash-bang) browser will interpret it as a new request and send it to server, so you have to map all requests from server to your SPA entry file
For exact steps of replicating this behavior, consult this article: https://scotch.io/tutorials/pretty-urls-in-angularjs-removing-the-hashtag (the base href in your entry file is important)

If it's just about the #. You can remove it in Angular itself.
Just inject locationProvider at your app entry and set htmlMode to true. In your index.html set the baseUrl.
$locationProvider.html5Mode(true)
And in you index.html add:
<base href="/" />
That will generate your urls without the #. Does that help?

Related

How to fix 'Cannot POST /index.html' in Nginx, Express and NodeJS

I'm setting up my MERN project on my production server and whilst
making sure you can manually type in URL (such as myproject.com/dashboard) I added the following line to the server section of my Nginx configuration file try_files $uri /index.html; to allow this(as stated by the react-router training page). This has now caused the following response when trying to login Cannot POST /index.html.
If I remove the line all calls to the api work(i can login again) but I cannot enter url manually.
I've tried moving the try_files line to the top of the server section incase the server section is sensitive to this.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name myproject.com;
root /home/forge/myproject.com/client/build;
...
location / {
try_files $uri /index.html;
proxy_pass http://127.0.0.1:8080;
}
...
}
const express = require('express');
const app = express();
app.use( express.static( `${__dirname}/client/build` ) );
app.use('/api/users', usersRouter);
app.use('/api/playlists', playlistRouter);
app.get('*', (req, res) => {
res.sendFile(`${__dirname}/client/build/index.html`);
});
I expect to be able to login(make calls to my api) and enter URLs manually to my project.
I think your configuration is not valid. In your config if requested file does not exists you are sending the file index.html no matter what. Will never call proxy.
Since your server has /api prefix configure that on your nginx server like this. So request starts with /api will be proxy to your backend server.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name myproject.com;
root /home/forge/myproject.com/client/build;
location /api/ {
proxy_pass http://127.0.0.1:8080;
}
location / {
try_files $uri /index.html;
}
}

Reverse proxy deployment of React apps

I'm trying to deploy multiple containerised SPAs using a reverse proxy to handle routing to each. In the current setup, each container has a production build create-react-app served by an express app which essentially just consists of:
app.use(express.static(path.join(__dirname, '..', 'build')));
app.use('/*', (req, res) => {
res.sendFile(path.join(__dirname, '..', 'build', 'index.html'));
});)
I've configured an nginx server with the following:
server {
listen 8081;
server_name example.domain.com;
location /app1 {
rewrite ^/(.*) /$1 break;
proxy_ignore_client_abort on;
proxy_pass http://localhost:3100;
proxy_redirect http://localhost:3100 https://example.domain.com/app1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
The proxying appears to work as when I navigate to http://localhost:8081/app1 the index.html of the built React app loads but all of the bundled js files are 404. I have tried setting "homepage": "/app1" in the React app's package.json but this hasn't appeared to make any difference. It is still looking for the bundled js files at the server's root: Request URL: http://localhost:8081/static/js/bundle.js
I'm at a loose end as to what to try next, any help would be much appreciated.
Best,
P
You need to add a static middleware, i.e.
app.use(express.static('static'))
Or
app.use('static', express.static('static'))
static is the folder name of all your static asset.
See: https://expressjs.com/en/starter/static-files.html
Updated:
If you have a folder "static" under "build", please use :
app.use('/static', express.static(path.join(__dirname, '..', 'build', 'static')));

NodeJS - use other port than 80 for public access [duplicate]

I am running XAMPP on Windows to host an Apache server on port 80. Now I'm trying to have a NodeJS script running in the background but the problem is that it can only listen on port 80. If it does, everything works as it should but I can't have Apache running at the same time, because Apache takes priority and just serves my website. The NodeJS script doesn't even get to listen.
My question is: how do I switch the listening port of the NodeJS script (the specific port really doesn't matter) so that Apache can still run on port 80 and I can reach the NodeJS script from all around the world.
Part of the NodeJS code:
const http = require('http');
const port = 8080;
const host = '0.0.0.0';
server = http.createServer( function(req, res) {
if (req.method == 'POST') {
var body = '';
req.on('data', function (data) {
body += data;
doStuff(body);
});
res.writeHead(200, {'Content-Type': 'text'});
res.end('received request successfully');
}
else {
res.writeHead(405, {'Content-Type': 'text'});
res.end('not allowed method ' + req.method + ', try again with GET or POST');
}
})
server.listen(port, null, function(error){
if(!!error){
console.log("\x1b[41m%s\x1b[0m", "error while initializing listener on port " + port + ": " + error);
}
else{
console.log("\x1b[32m%s\x1b[0m", "started listener at 'http://" + host + ':' + port + "'");}
});
Additional information is in my other question which got flagged as duplicate.
Looking at your other question, which was marked as duplicate of this one, you've got some additional information there that will probably help to elucidate what you're needing. Specifically, you mention the following:
I want to host multiple http servers with NodeJS, that all get and send http requests. At the same time I want to have Apache running, which occupies port 80. If I disable Apache and let NodeJS run on port 80, it will work but I can't have them running at the same time.
This script will run and receive requests locally at port 8081, but I can't seem to send an AJAX request to it through the Internet, even after forwarding the port with my router:
I think #ankit-agarwal is probably right in that you need a reverse proxy setup to forward traffic to your different backends. Assuming you've got an externally facing IP address, you should be able to access each of your backends using the ports they are listening on. For example, if the exposed public IP address of your machine is 100.120.110.43:
+---------+------+-------------------------------------+
| Backend | Port | Web Address |
+=========+======+=====================================+
| Apache | 80 | 100.120.110.43 or 100.120.110.43:80 |
| Node1 | 8080 | 100.120.110.43:8080 |
| Node2 | 8081 | 100.120.110.43:8081 |
+---------+------+-------------------------------------+
If you want to access each of the backends without specifying the port, you have to have some way to tell your internal network which backend to serve based on the request. One way of doing this is to use path based routing, where you setup your reverse proxy to route the traffic to the different backends based on the path in the url. You didn't post your Apache configuration, but you can use your current Apache server to handle this using the ProxyPass and ProxyPassReverse directives similar to below:
ProxyPass "/node1" "http://100.120.110.43:8080/"
ProxyPassReverse "/node1" "http://100.120.110.43:8080/"
ProxyPass "/node2" "http://100.120.110.43:8081/"
ProxyPassReverse "/node2" "http://100.120.110.43:8081/"
The cool thing about using a reverse proxy is that you don't have to expose your node backends to the public. Let's assume you haven't, and they are only accessible from the internal network at 0.0.0.0:port.
Listen 80
<VirtualHost *:80>
DocumentRoot /www/apache
ServerName www.apachefrontend.com
ProxyRequests off
ProxyPass /node1 http://0.0.0.0:8080/
ProxyPassReverse /node1 http://0.0.0.0:8080/
ProxyPass /node2 http://0.0.0.0:8081/
ProxyPassReverse /node2 http://0.0.0.0:8081/
</VirtualHost>
You could also point to different hosts/ips that only you have access to.
Finally, you can also use VirtualHost and ServerName if you have different DNS records to point to the different backends.
Listen 80
<VirtualHost *:80>
DocumentRoot /www/apache
ServerName www.apachefrontend.com
</VirtualHost>
<VirtualHost *:80>
ServerName www.nodebackend1.com
ProxyRequests off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
<Location />
ProxyPass / http://0.0.0.0:8080/
ProxyPassReverse / http://0.0.0.0:8080/
</Location>
</VirtualHost>
<VirtualHost *:80>
ServerName www.nodebackend2.com
ProxyRequests off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
<Location />
ProxyPass / http://0.0.0.0:8081/
ProxyPassReverse / http://0.0.0.0:8081/
</Location>
</VirtualHost>
For any of the above to work, you need to have mod_proxy and mod_proxy_http enabled in apache.
These probably aren't the most robust examples and I haven't tested them, but they should demonstrate the idea. You can learn more here.
Just change your node.js server port something like:
var server = app.listen(8080, function() {
console.log('Ready on port %d', server.address().port);
});
where 8080 is node.js server' new port.
I haven't really understood what you meant by you're not getting any response, because I ran the same code and it works fine for me.
I only noticed something here (I kept a note for you in the comment)
server = http.createServer( function(req, res) {
if (req.method == 'POST') {
var body = '';
req.on('data', function (data) {
body += data;
doStuff(body); //you haven't defined doStuff so you will end up with a error message on this line, but you sever will still run fine
});
res.writeHead(200, {'Content-Type': 'text'});
res.end('received request successfully');
}
else {
res.writeHead(405, {'Content-Type': 'text'});
res.end('not allowed method ' + req.method + ', try again with GET or POST');
}
})
When running your post request, don't forget to add "" in your body area, select raw then choose JSON(application/json). That should run fine for you, except you might get a reference error as shown below, but you should still get your response of received request successfully.
error
doStuff(body);
^
ReferenceError: doStuff is not defined
Ensure that you're doing the same thing and let us know if your issue it resolved.
Seem something already running on your 8080 port. Simply change to another port. For example 7000
And make sure that all request you call to nodejs app like this
localhost:7000 // Normal we run at port 80 url simply localhost without port
If I want use Apache and Nodejs in same port:
npm http-proxy-middleware
1. Set Apache Port = 81
[apache dir]/conf/httpd.conf
~59: Listen 81
2. Set nodejs APP port = 3050
server.listen(3050);
// on linux ports<1000 require root privilegue
3. Use third proxy APP (http-proxy-middleware)
// https://www.npmjs.com/package/http-proxy-middleware
var express = require('express');
var proxy = require('http-proxy-middleware');
// proxy middleware options
var options = {
target: 'http://localhost:81', // target host ROOT
changeOrigin: true, // needed for virtual hosted sites
ws: true, // proxy websockets
pathRewrite: {
// '^/api/old-path' : '/api/new-path', // rewrite path
// '^/api/remove/path' : '/path' // remove base path
},
router: {
// Examples:
// when request.headers.host == 'dev.localhost:3000',
// override target 'http://www.example.org' to 'http://localhost:8000'
// 'dev.localhost:3000' : 'http://localhost:8000',
// 'localhost:9000': 'localhost:9002/sub',
// '/sub': 'http://localhost:9002',
'localhost': 'http://localhost:81', //Root to Apache
'sub.localhost': 'http://localhost:3050', // internal
'sub.mydomain.com': 'http://localhost:3050', //external
},
};
// create the proxy (without context)
// var proxy_wp = proxy(options_wp);
var proxy_node = proxy(options);
// mount `exampleProxy` in web server
var app = express();
app.use(proxy_node);
app.listen(80);
Then:
localhost:80 - is apache site
sub.localhost:80 - node
localhost:80/sub - node, if you set
for task runner i use npm PM2
This is same scenario as using NodeJs in a Shared Hosting. I have written a blogpost about it here
Let me give an excerpt.
Just run the NodeJS server at let's say 8080 port.
Now, let's say your Apache serves at http://example.com, create a folder in your public_html or www. let's say the name is server. So, your new folder path is http://example.com/server
create a .htaccess file in the server folder
add the following lines,
RewriteEngine On
RewriteRule ^$ http://127.0.0.1:8080/ [P,L] #which is your node server ip:port
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ http://127.0.0.1:8080/$1 [P,L] #same ip:port
This will redirect all the requests from http://example.com/server to your Node server.

Use webpack dev server with nginx

I am trying to enable HMR on my react front end which also uses nginx/php-fpm as backend. I read a few articles and questions on stackoverflow but I still cannot get it to work.
So first of all, If I understand It correctly It should work like this:
1.I have my docker nginx container(80) mapped to port 8080
I make request to localhost:8080 which then passes It into docker container to nginx which listens on port 80.
After that I should have two options, If I want to make a request to backend, which is just API, then everything with /api in URI will be redirected to php-fpm, otherwise everything else will be redirected to webpack-dev-server.
Currently I have my nginx configured like this:
upstream backend {
server app:9000;
}
server {
root /var/www/emailApp/public;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://localhost:8080;
}
location ~ ^\/api\/.+$ {
fastcgi_pass backend;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
}
I am not sure this works correctly, but If it matches something with '/' it should try to pass it into port 8080, If it matches something with /api/ then it should pass it to php backend.
Here is my webpack config
entry: './assets/index.jsx',
output: {
filename: 'main.js',
publicPath: "http://localhost:8080/public/"
},
devServer: {
contentBase: path.join(__dirname, 'public'),
host: '0.0.0.0',
compress: true,
port: 8080
},
I mainly did this from tutorials, but I don't think that I understand It. because right now I call index.php which calls controller that returns template which contains reference to main.js that is in public folder. But event after reading documentations I quite don't understand It. The devServer part maybe, It specifies server that will listen on 0.0.0.0:8080, but If I am not mistaken I would need to change the structure of my project so I have index.html file that will include my js file in public folder, right ?

Angular + Node(Express) + SSL integration

This is my first time deploying ssl. I have express node js module running at localhost:4000. I have generated the self-signed certificate and installed in the server and it is working. Now, I have my angularjs frontend running at localhost:3000(I am using http-server to run the angular code).
To make my point more clearer, here's is the code on the server side:-
// Import node js modules
var https = require('https')
var fs = require('fs')
var express = require('express')
// Load App configuration
var config = require('./config/config')
// Database Integration Here(mongodb)
// Initialize the express app
var app = express()
// App express Configuration
// parse application/json
app.use(bodyParser.json())
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true}))
app.use(cors())
app.set('serverHost', config.server.host)
app.set('serverPort', config.server.port)
app.set('serverUrl', config.server.url)
// Initializing various app modules
// Initialize the components
//Initialize the route(controller)
// Start the app with a given port no and mode
var env = process.env.NODE_ENV || 'development'
var httpsOptions = {
key: fs.readFileSync(__dirname + '/cert/server.key'),
cert: fs.readFileSync(__dirname + '/cert/server.crt')
}
https.createServer(httpsOptions, app).listen(app.get('serverPort'), function () {
// Server and mode info
console.log('The homerungurus backend running on server: '
+ app.get('serverHost')
+ ' and the port is: '
+ app.get('serverPort'))
console.log("The mode is: " + env)
})
As you can see I have installed the certs in the server.
I don't need a http-proxy because i will deploy the angular webserver on the standard port 443.
I am not able to understand few things:-
How to enable and set ssl certificate in my angular module so that
express and angular can communicate over ssl.
How will I display the cert of my backend express node to the browser?
I hope I have made my point more clearer.
Any help is appreciated?
Ok, where do we start...
You have a backend (express node js) running on port 4000, and a frontend (angularjs with http-server) running on port 3000, so you basically have two independent webservers running. When you say you "installed" the ssl certificate on the server, I assume you have it sitting in some directory but not actually installed on one of your servers.
You have several options to deploy your code, together with your SSL certificate. The best approach would be to seperate frontend from backend by urls.
That would mean that your frontend gets served from: https://frontend.example.com
and your backend gets served from https://backend.example.com (you can change the urls to whatever you want, so something like https://example.com or https://www.example.com is fine as well)
As far as I recall, if you have https:// on your frontend, you also need https:// on your backend, otherwise you will have problems with browsers security policies. You might also have to look for same origin policy, and allow on your server that https://frontend.example.com can access https://backend.example.com, but for that open a new ticket if you need it :D
The user would see the green symbol from https://frontend.example.com
I assume you know how you would change the backend url so your angular code would use https://backend.example.com instead of http://localhost:4000
To serve now your existing servers on port 443 (that is the default port for https and is always used if you say https://... but do not specify a port) you need an http proxy.
As http proxy (you can google for reverse proxy) you can take either apache or nginx, both are very common.
There are a couple of tutorials out there, how to setup nginx / apache which are OS specific, but Im sure you will manage. Dont forget to install mod_ssl and mod_http_proxy mod for apache (I dont remember if nginx needs something specifc as well)
A typical config for an apache reverse proxy would look like this:
<VirtualHost *:80>
# this part redirects all traffic from normal http to https
ServerName frontend.example.com
ServerSignature Off
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [NE,R,L]
</VirtualHost>
<virtualhost *:443>
# this is the actual part with some security enhancements
ServerName frontend.example.com
ServerAdmin webmaster#localhost
# be carefull with HSTS, it might break your setup if you
# do not know what you do. If you are not sure, do not
# comment the next line in
# Header always add Strict-Transport-Security "max-age=15768000"
# Enable SSL
SSLEngine on
# only strong encryption ciphers
# for reference https://community.qualys.com/blogs/securitylabs/2013/08/05/configuring-apache-nginx-and-openssl-for-forward-secrecy
# and no RC4 according to https://community.qualys.com/blogs/securitylabs/2013/03/19/rc4-in-tls-is-broken-now-what
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"
SSLCompression Off
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/privkey.pem
# this next line is not needed if you have a self signed cert
SSLCertificateChainFile /path/to/chain.pem
ServerSignature Off
RequestHeader set X-FORWARDED-PROTOCOL https
RequestHeader set X-Forwarded-Ssl on
ProxyPreserveHost On
# Ensure that encoded slashes are not decoded but left in their encoded state.
# http://doc.gitlab.com/ce/api/projects.html#get-single-project
AllowEncodedSlashes NoDecode
<Location />
# New authorization commands for apache 2.4 and up
# http://httpd.apache.org/docs/2.4/upgrading.html#access
Require all granted
ProxyPassReverse http://127.0.0.1:3000
ProxyPassReverse http://frontend.example.com/
</Location>
#apache equivalent of nginx try files
# http://serverfault.com/questions/290784/what-is-apaches-equivalent-of-nginxs-try-files
# http://stackoverflow.com/questions/10954516/apache2-proxypass-for-rails-app-gitlab
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule .* http://127.0.0.1:3000%{REQUEST_URI} [P,QSA]
RequestHeader set X_FORWARDED_PROTO 'https'
You will need the exact same twice, for the frontend like shown above and for the backend, where you replace port 3000 with 4000 and frontend.example.com with backend.example.com.
I hope this helps you a bit. Its not as complete as it could, but it should give you a hint how to setup your two http servers behind a http proxy to server your ssl certificate.
The above comment made by #chickahoona is more than enough. My solution is as follows:-
I removed http-server and used nginx for my frontend because i wanted to have html5 mode and for that I needed to have url rewriting.
I have used nginx as a proxy server rather than apache.
That's it and everything else is same as #chickahoona has pointed out.

Categories