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

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.

Related

Get the original filename of symlinks in nginx

From another script i got some generated symlinks.
2QGPCKVNG1R -> /anotherdir/movie1.mp4
HJS7J9ND2L5 -> /anotherdir/movie2.mp4
LKA6A9LA7SK -> /anotherdir/movie3.mp4
Displaying these files in NGINX works fine, but I'd like to rename the files at download via content disposition.
Question is how do i get the original filename in nginx variable?
I'm not sure it is possible at all. Is that another script yours or under your control? You can generate an additional nginx config file with a map block with the same script where you can describe a ruleset for mapping an URI value to the Content-Disposition header value (or you can write an additional script to do it with readlink -f <symlink> command:
map $uri $content_disposition {
~/2QGPCKVNG1R$ movie1.mp4;
~/HJS7J9ND2L5$ movie2.mp4;
~/LKA6A9LA7SK$ movie3.mp4;
}
And then include that file to the main nginx config:
include /path/to/content-disposition-map.conf;
server {
...
add_header Content-Disposition $content_disposition;
Another way I see is to use lua-nginx-module and a LUA script like
map $symlink_target $content_disposition {
~/([^/]*)$ $1;
}
server {
...
set_by_lua_block $symlink_target {
local result = io.popen("/bin/readlink -n -f " .. ngx.var.request_filename)
return result:read()
}
add_header Content-Disposition $content_disposition;

Vue.js app served on nginx, using Axios/Express, loses HTTPS and becomes HTTP after login page

My Vue.js app switches from HTTPS to HTTP after the user logs in, and I'm not sure why. The Vue.js front-end is served using nginx, and uses Axios to access an Express back-end API that queries a local MongoDB server for login and a remote SQL Server for data. If someone could provide any guidance, that would be much appreciated, as this is for a work project.
I'm not sure if this could be a clue, but after logging into a session in the app, if I open a new tab and manually enter a URL for a view that doesn't access the Express back-end (https://subdomain.website.com/view_that_doesnt_access_express_api), the site will be secure under HTTPS, but if I do the same with a view that does access the Express back-end (https://subdomain.website.com/view_that_accesses_express_api), the site will be unsecure and the HTTPS in the location bar is shown crossed out in red.
nginx is configured with SSL and redirects 80 to 443 as follows (/etc/nginx/sites-available/project):
server {
listen 80;
server_name subdomain.website.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name _;
ssl_certificate /path/to/my/cert.crt;
ssl_certificate_key /path/to/my/key.rsa;
root /path/to/my/dist;
index index.html
access_log /var/log/nginx/site.access.log;
error_log /var/log/nginx/site.error.log;
location / {
try_files $uri /index.html =404;
}
}
The Express server is also configured to be HTTPS (app.js) with the same certification files used by nginx:
var httpscert = fs.readFile('cert.crt');
var httpskey = fs.readFile('key.rsa);
var options = {
key: httpskey,
cert: httpscert
};
var server = https.createServer(options, app);
server.listen(3000, function () {
console.log("Express HTTPS running on 3000");
})
Axios (Service.js):
import Api from '#/services/Api'
export default {
loginUser (email, password) {
return Api().post('login', {
email: email,
password: password
})
}
}
Axios (Api.js):
import axios from 'axios'
export default() => {
return axios.create({
baseURL: 'https://192.168.10.117:3000'
})
}
This is my first question on StackOverflow, so please let me know if I'm not asking this question correctly.
Thank you.
You said:
but if I do the same with a view that does access the Express back-end (https://subdomain.website.com/view_that_accesses_express_api), the site will be unsecure and the HTTPS in the location bar is shown crossed out in red.
That does not mean your setup is wrong, it just means you have on that page an asset that is served via HTTP, instead of HTTPS. And that's why the lock is crossed.
You should inspect your page source and check for any scripts or styles that are loaded via HTTP. Change those to be HTTPS and you should be good to go.

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

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.

S3 hosted website with Cloudflare returns 404 status code for any route

I have an S3 hosted website working well behind Cloudflare with the following:
example.com/ works fine
example.com/test also works but the document itself in the network tab is returning 404, naturally, because /test doesn't exist on S3.
This is a problem for SEO, how do I configure Cloudflare to treat 404s as 200s?
In Cloudfront I usually do this:
But I can find no corresponding configuration in Cloudflare. Will this have to be done in a Cloudflare worker? What did people do before Workers existed?
Turns out people just didn't host on S3 with Cloudflare before workers, and if they did, they didn't care/notice that their routes would return 404.
Anyway, this is the solution with Cloudflare workers to force the return code of 200:
addEventListener('fetch', event => {
event.respondWith(fetchAndApply(event.request))
})
async function fetchAndApply(request) {
let originalResponse = await fetch(request)
const contentType = originalResponse.headers.get("Content-Type")
// Only bother with index pages (not assets)
if (contentType && contentType.includes("text/html")) {
// Force 404's from S3 to return as 200 to prevent Google indexing issues
let response = new Response(originalResponse.body, {
...originalResponse,
status: 200,
statusText: 'OK'
}
)
// Don't cache index.html
response.headers.set('Cache-Control', 'max-age=0')
return response
}
return originalResponse
}
I beleive you can use this approach from the AWS docs.
https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html
Example #3 at the bottom of the document page.
This is S3 bucket for the demo.
EDIT: removed the URL, it served the purpose that was usable only to
author of the question.
Here is short example. Which will redirect to "home" if not found.
<RoutingRules>
<RoutingRule>
<Condition>
<HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals >
</Condition>
<Redirect>
<HostName>BUCKETNAME.s3-website-eu-west-1.amazonaws.com</HostName>
<ReplaceKeyWith></ReplaceKeyWith>
</Redirect>
</RoutingRule>

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;
}
}
...