How to create a CDN for an application running on localhost/Ip address without a domain (.com) - express

To improve the performance of the application , I want to host my static assets on CDN. But we have not yet created a domain using nginx. How to still use a cdn like - express-simple-cdn link -
https://www.keycdn.com/support/express-cdn-integration
i need to write this domainName.com in my app.js file of Angular app through which i host my application--
// Initialize Express in a variable in app.js
var app = express();
// Define Your CDN base path
var CDN = "https://assets.preisheld.ch";
// Register a local variable in your app which contains the CDN function
app.locals.CDN = function(path, type, classes, alt) {
if(type == 'js') {
return "<script src='"+CDN+path+"' type='text/javascript'></script>";
} else if (type == 'css') {
return "<link rel='stylesheet' type='text/css' href='"+CDN+path+"'/>";
} else if (type == 'img') {
return "<img class='"+classes+"' src='"+CDN+path+"' alt='"+alt+"' />";
} else {
return "";
}
};
How to utilize CDN in such a situation ?

So is there a dummy a place where you can create your domainName.com address for free while opening it in your local ip address
Yes! That's the hosts file. You can find it on your system here:
Windows: C:\Windows\System32\Drivers\etc\hosts
Linux: /etc/hosts
OS X: /private/etc/hosts
This file allows you to map arbitrary host names to network addresses, overriding anything that comes from DNS. For example:
127.0.0.1 yourproject.test
Now, if you go to http://yourproject.test in your browser, it will resolve to 127.0.0.1 and connect the web server running on your loopback address. If you're using IPv6, use ::1 instead of 127.0.0.1.
You can set any hostnames you want... even real ones that exist. However, it is strongly recommended that you use the .test top-level domain, as it's specifically reserved for testing purposes.

Related

AWS static website - how to connect subdomains with subfolders

I want to setup S3 static website and connect with my domain (for example domain: example.com).
In this S3 bucket I want to create one particular folder (name content) and many different subfolders with in, then I want to connect these subfolders with appropriate subdomains, so for example
folder content/foo should be available from subdomain foo.example.com,
fodler content/bar should be available from subdomain bar.example.com.
Any content subfolder should be automatically available from subdomain with that same prefix name like folder name.
I will be grateful for any possible solutions for this problem. Should I use redirection option or there is any better solution? Thanks in advance for help.
My solution base on this video:
https://www.youtube.com/watch?v=mls8tiiI3uc
Because above video don’t explain subdomain problem, here is few additional things to do:
to AWS Route53 hostage zone we should add records A with “*.domainname” as record name and edge address as Value
to certificate domains we should add also “*.domainname”- to have certificate for wildcard domain
when setting up Cloudfront distribution we should add to “Alternate domain name (CNAME)“ section “www.domainname” and also “*.domainname”
redirection/forwarding from subdomain to subfolder is realizing via Lambda#Edge function (function should be improve a bit):
'use strict';
exports.handler = (event, context, callback) => {
const path = require("path");
const remove_suffix = ".domain.com";
const host_with_www = "www.domain.com"
const origin_hostname = "www.domain.com.s3-website.eu-west-1.amazonaws.com";
const request = event.Records[0].cf.request;
const headers = request.headers;
const host_header = headers.host[0].value;
if (host_header == host_with_www) {
return callback(null, request);
}
if (host_header.startsWith('www')) {
var new_host_header = host_header.substring(3,host_header.length)
}
if (typeof new_host_header === 'undefined') {
var new_host_header = host_header
}
if (new_host_header.endsWith(remove_suffix)) {
// to support SPA | redirect all(non-file) requests to index.html
const parsedPath = path.parse(request.uri);
if (parsedPath.ext === "") {
request.uri = "/index.html";
}
request.uri =
"/" +
new_host_header.substring(0, new_host_header.length - remove_suffix.length) +
request.uri;
}
headers.host[0].value = origin_hostname;
return callback(null, request);
};
Lambda#Edge is just Lambda function connected with particular Cloudfront distribution
need to add to Cloudfront distribution additional setting for Lambda execution (this setting is needed if we want to have different redirection for different subdomian, instead all redirection will point to main directory or probably to first directory which will be cached - first request to our Cloudfront domain):

Disable a hash URL (like http://localhost/#/login) without changing frontend code

I want to disable a hash URL (like http://localhost/#/login)
But I can not change the frontend code.
Can I solve it in some other ways (like Nginx or Apache Config)?
According to the spec the hash part of the URI is processed on the client-side, and does not get sent to the server.
So, unfortunately not.
reference
It can redirect the #/foo hash URL in this demo
https://jsfiddle.net/yaoyuan/exLwhy57/1/
Install Nginx.
Use https://github.com/denji/homebrew-nginx for Mac
Install Nginx module for Mac
https://denji.github.io/homebrew-nginx/#modules
brew reinstall nginx-full --with-sub-module; Then we can use the sub_filter expression
https://nginx.org/en/docs/http/ngx_http_sub_module.html
delete the js code in demo1.we get demo2 https://jsfiddle.net/yaoyuan/exLwhy57/2/;
use this nginx config
location / {
root html; (use your folder)
index index.html index.htm;
sub_filter </head>
'</head><script>
function redirect() {
if (location.hash === "#/foo") {
window.location.replace("https://example.com");
}
}
window.onhashchange = function() {
if (location.hash === "#/foo") {
window.location.replace("https://example.com");
}
}
redirect();
</script>';
sub_filter_once on;
}
run nginx -c nginx.config to use this config
We can find a new snippet in the HTML, then we solve the question.

Configuring Varnish on cPanel with multiple IP addresses

So I am trying to configure Varnish on my cPanel server which has a primary shared IP along with a few other secondary IP addresses for dedicated domains that are hosted with me.
I have followed the following guide on how to get varnish to run, and it works perfectly for the shared IP domains, but the secondary IP domains won't load at all, going to the default Apache page.
http://crybit.com/how-to-enable-varnish-in-cpanel-server/
I was looking online for other resources and found to configure multiple hosts in the default.vcl file for varnish, so I had done exactly that but the service fails to load as soon as I try launch it, even with just two hosts in the file.
Am I doing something wrong?
backend default {
.host = "11.11.11.11";
.port = "8080";
}
backend secondary1 {
.host = "22.22.22.22";
.port = "8080";
}
I have also tried configuring the following below but also to no success, service won't load!
sub vcl_recv{
if(req.http.host == "www.secondary1.com") || (req.http.host == "secondary1.com) {
set req.backend = secondary1;
} else {
set req.backend = default;
}
}
Hoping that someone can give me a hand!
Can you please check your /etc/sysconfig/varnish file and change your -a flag with your IP's.
-a 192.168.0.1:80,192.168.0.2:80 \

Node express server, CORS API restriction, including an entry in my development machine’s hosts file

I am trying to use an API that has an API CORS policy that does not support browser requests from any domain. In order to allow clientside JavaScript code to access the API, whilst developing my application, I have been advised to I serve my webapp from '*.thisCompany.com' domain.
It was advised to include an entry in my development machine’s hosts file, as follows, which I have done:
$ echo '127.0.0.1 localhost.thisCompany.com' >> /etc/hosts
Following this command when I run sudo nano /private/etc/hosts
this is the screen that I see.
Host Database
localhost is used to configure the loopback interface
when the system is booting. Do not change this entry.
127.0.0.1 localhost
127.0.0.1 localhost.thisCompany.com
And then I have been told that I should be able access my webapp at http://localhost.thisCompany.com.
I am using node express as my server and the code in my server.js file looks like this
var express = require('express');
var server = express();
var path = require('path');
var port = process.env.PORT || 'thisCompany.com';
server.use(express.static(__dirname + '/public'));
server.use('/bower_components', express.static(__dirname + '/bower_components'));
server.get('/', function(request, response) {
response.sendFile(path.join(__dirname + '/views/index.html'));
});
server.listen(port, function() {
console.log("Node app is running at localhost:" + port)
});
Can anyone advise what steps I should follow to enable me to call this API and bypass the API CORS policy?
I have read various other posts here, and also other articles online, however I cannot find the solution. Really hoping someone on this can help.
Thanks, Paul
I misunderstood how I was supposed to view a page locally on my computer after amending the hosts file on my local machine. I didn't need to add anything to my express server. The express server code remained as follows:
var express = require('express');
var server = express();
var path = require('path');
var port = process.env.PORT || 3000;
server.use(express.static(__dirname + '/public'));
server.use('/bower_components', express.static(__dirname + '/bower_components'));
server.get('/', function(request, response) {
response.sendFile(path.join(__dirname + '/views/index.html'));
});
server.listen(port, function() {
console.log("Node app is running at localhost:" + port)
});
After adding the line mentioned in my original post to my hosts file on my local machine, I then needed to launch my server and access the page by following this link.
http://localhost.thisCompany.com:3000/
Although this is quite a niche issue, I hope this post helps someone in the future.

Rewrite Requests for Images to CDN URL with Varnish

I've got Varnish (3.0.3) sitting as a load-balancer/static cache in front of two web servers. I've got a CDN set up using Original Pull method. If I grab a URL from an image on my site manually, drop in the CDN address, I can verify that original pull is working and the image is pulled to the CDN and served.
My application is fairly complex and I'm testing this CDN to see if it significantly speeds up the web app, so I don't want to rewrite any of my php code to use the CDN images just yet.
What I'd like to do is set Varnish up to rewrite requests received for image files and pull them through the CDN instead of from the two Apache servers directly in my cluster.
I've read through the Varnish documentation and a couple howto's online about doing something similar, but I just can't get it to work properly and need a little help here.
Here are a couple different ways I tried doing this (edited for brevity):
sub vcl_recv {
#if request is image, redirect to CDN
if (req.url ~ "\.(gif|ico|jpg|jpeg|png)$") {
set req.http.host = "cdn.domain.com/";
error 750 req.http.host + req.url;
}
}
sub vcl_error {
if (obj.status == 750) {
set obj.status = 302;
set obj.http.Location = obj.response;
return(deliver);
}
}
That didn't work. It resulted in broken images everywhere, and anything that did show up was using the .webp extension, so it wasn't being processed by the condition above.
So I tried this:
backend cdn {
.host = "cdn.domain.com";
.port = "80";
}
sub vcl_recv {
#if request is image, redirect to CDN
if (req.url ~ "\.(gif|ico|jpg|jpeg|png)$") {
set req.backend = cdn;
return(lookup);
}
}
This showed some images on the page, but when viewing their source, they looked to be coming from the Apache servers (the domain name wasn't that of the CDN) and only about half the images were displaying...probably browser cache.
I'd love some input here, thanks guys.
Is there no way to use Varnish for this kind of redirect? Would I be better off setting nginx up in front of Varnish to rewrite requests to the cdn?
UPDATE:
Using both answers given below, I have the redirect working and an ACL in place to allow the CDN to pull images directly vs redirecting to itself. However, though I verified the ACL is allowing connection through by using my own external IP, the CDN isn't pulling new images from the server. It gives a 502 error (odd<) instead of pulling the image from the local server to the CDN and serving it. This is what the block of my vcl_recv looks like now:
acl cdn {
"ip.of.CDN";
}
sub vcl_recv {
#if request is image, redirect to CDN
if (req.url ~ "\.(gif|ico|jpg|jpeg|png)$") {
if(!client.ip ~ cdn){
error 750 "http://cdn.domain.com" + req.url;
}
}
}
sub vcl_error {
if (obj.status == 750) {
set obj.status = 302;
set obj.http.Location = obj.response;
return(deliver);
}
}
You can definitely do this with Varnish quite easily - no need to setup nginx or anything. Actually your first solution is very close to doing the trick. It just needs a few modifications.
sub vcl_recv {
#if request is image, redirect to CDN
if (req.url ~ "\.(gif|ico|jpg|jpeg|png)$") {
error 750 "http://cdn.domain.com" + req.url;
}
}
sub vcl_error {
if (obj.status == 750) {
set obj.status = 302;
set obj.http.Location = obj.response;
return(deliver);
}
}
You forgot "http://" from your CDN URL, and you can omit the last slash from the host as all req.urls begin with /.
You also need to make sure that the vcl_error code is the first one that is run in vcl_error(). I.e. if you have multiple definitions of vcl_error, make sure that none of them get to deliver any output before the if (obj.status == 750) check is reached.
Bear in mind that this solution causes all client browsers to query your server first and then make another request to the CDN after the 302 redirect. This adds a significant delay to each image load, and is probably not the best way of determining if CDN improves your app performance.
Update: Regarding your problems with CDN showing 502 errors when trying to pull content from your origin. Relying on the remote IP address for determining the redirection is quite risky, as the CDN could very well use a number of servers to do the pull, and the addresses could change over time. That would make the VCL very laborious and error-prone to maintain.
Would it be possible setting up a unique virtual host for the CDN to use? For instance originpull.domain.com and setup the CDN so that it pulls content from that address instead of your primary www.domain.com address?
You could then modify the vcl_recv() as follows:
sub vcl_recv {
#if request is image and request is not made from CDN, redirect to CDN
if (req.http.host != "originpull.domain.com" &&
req.url ~ "\.(gif|ico|jpg|jpeg|png)$") {
error 750 "http://cdn.domain.com" + req.url;
}
}
That would ensure that the requests from CDN will never be redirected.
Assuming you have the CDN pulling it's copy of the images from the site, and your not manually pushing images to the CDN. Aren't you missing a simple exclusion of the CDN network, from either your rewrite, or backend proxy? As the CDN needs to be able to directly pull a copy of the images, from your site to populate it's caches.
Been a while since I played with Varnish, and never an expert, but something along the following lines may work:
# Defnine the IP ranges of the CDN server.
acl cdn {
"localhost";
"11.22.33.0"/24;
}
...
#if request is image, redirect to CDN, unless from the CDN
if (req.url ~ "\.(gif|ico|jpg|jpeg|png)$") {
if (!client.ip ~ cdn) {
error 750 "http://cdn.domain.com" + req.url;
}
}
...