Nginx equivalent of Apache query string rule - .htaccess

we recently moved to a nginx server for one of our WordPress site. We've had an issue with Cloudflare where the content-type of a ajax request was modified which was causing issue with Stripe integration and it didn't render.
We fixed it with the below code
RewriteCond %{REQUEST_URI} \?wc-ajax=update_order_review$
Header set Content-Type text/html
Tried the below code in Nginx
location ~ /?wc-ajax=update_order_review$ {
add_header Content-Type text/html;
}
Unfortunately it didn't work and didn't find any solution to rewrite the same in Nginx.
Can you please help sort this out?
Thanks in advance

You can use $args to access query string (without ?) and $arg_name to access a query parameter name.
Here is official Nginx doc
So for you you may try:
location / {
if ($arg_wc-ajax ~ "^update_order_review$") {
add_header Content-Type text/html;
}
}

Related

How do I allow only 1 URL in my web app to be accessed via iframe?

I'm running a NodeJS App on NGINX Web Server. I'm able to access all the URLs in my app via iframe on other websites.
Here is my NGINX conf:
proxy_hide_header X-Frame-Options;
How do I restrict the iframe to allow only 1 URL instead of all the URLs?
Also, how do I allow only a few domains to access via iframe?
Can it be done via NGINX or should it be handled via NodeJS code?
It can be done via both NGINX conf and nodejs.
For NGINX conf, please use both X-Frame-Options and Content Security Policy (frame-ancestors)
add_header Content-Security-Policy "frame-ancestors domain1 domain2 domain3"; -> it's for modern browsers
add_header X-Frame-Options "ALLOW-FROM domain1 domain2 domain3"; -> it's for older browsers
To get more details: X-Frame-Options Content-Security-Policy
It can be done by both nginx or nodejs. If you'd prefer nginx, you should use it within a location block like:
server {
location / {
add_header Content-Security-Policy "frame-ancestors 'none'";
add_header X-Frame-Options "DENY";
}
location /iframing_is_allowed {
add_header Content-Security-Policy "frame-ancestors http: https:";
proxy_hide_header X-Frame-Options;
}
}
Otherwise, if you'd prefer nodejs, you should set these headers from your JS code in the corresponding endpoints.
If you looking for what options you have, please consult to X-Frame-Options and Content-Security-Policy docs, as Thang Duc pointed.
I used this in
Ubuntu 14.04
add_header X-Frame-Options "allow-from https://*.sample.com http://*.sample.com";
add_header Content-Security-Policy "frame-ancestors https://*.sample.com http://*.sample.com";
And it worked like a charm.

Express redirect wrong url

When use express res function redirect(url), i'm redirected to the wrong url !
My website URL is mywebsite.com :
function myroute(app) {
app.get(/route, function(req, res) {
var url = getMyUrl();
console.log(url); // https://otherwebsite.com/foo?bar=baz [OK]
res.redirect(url); // redirect to https://mywebsite.com/foo?bar=baz [WRONG!]
});
}
I don't know why express redirect to mywebsite.com with good parameters instead of otherwebsite.com
No idea why...
This bug occurs on production. On my develop environment the redirect URL is the good url.
Thanks in advance
EDIT
I also tried with:
res.location(url);
and
res.setHeader(302, {Location: url});
But it always redirect to the wrong URL...
My url variable is good but I receive this header response:
HTTP/1.1 302 Found
X-Powered-By: Express
Location: https://mywebsite.com/foo?bar=baz
Vary: Accept\r\nContent-Type: text/html; charset=UTF-8
Content-Length: 170
Date: Fri, 13 Jul 2018 21:52:18 GMT
Connection: keep-alive
EDIT 2
Ok more tests here :
res.redirect("https://www.google.fr/toto?key=value"); // https://mywebsite.com/toto?key=value **[fail]**
res.redirect("https://www.google.fr/toto"); // https://mywebsite.com/toto **[fail]**
res.redirect("https://www.google.fr"); // https://www.google.fr **[success]**
It seems to not redirect to the domain I want if I add a path. Any idea ?
EDIT 3
Maybe it's caused by my vhost ?
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName mywebsite.com
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5001/
<Location />
ProxyPassReverse /
Order deny,allow
Allow from all
</Location>
SSLCertificateFile ...
SSLCertificateKeyFile ...
</VirtualHost>
</IfModule>
Providing an actual answer this time, as my previous one was (rightfully so) deleted.
The incorrect URL redirections are definitely caused by:
ProxyPassReverse /
As this is what such directive does:
"lets Apache httpd adjust the URL in the Location, Content-Location and URI headers on HTTP redirect responses."
In my case, removing this directive was causing other internal redirection issues in my application, so I was trying to find out a way to add exceptions to it.
However, it turns out I never needed ProxyPassReverse (only ProxyPass) if I adjust the 'mountpath' of my Express node js configuration to match the path of the proxy server. Not sure if this answer will help you as an actual solution, but it managed to solve it on my node application using Apache as reverse proxy.
I believe 301 needs to be included.
Try changing res.redirect(url) to res.status(301).redirect(url) and see if it fixes the issue.

nginx - Replace page content on homepage

I've been having a bit of difficulty setting up nginx on my ubuntu server. Right now its configured to proxy another website. I want to add some content to the main page right after <body>. I used:
subs_filter '<body>' '<body>' My content;
This works great, the only problem is that it's at every page, How can I use an if statement or something to make it only appear on the homepage. I tried going with
if ($uri ~ 'index.php') then do the above filter but that gives an error saying nginx: [emerg] "subs_filter" directive is not allowed here.
I looked it up but had a lot of trouble finding what I need :(.
According to nginx documentation subs_filter may in used in the http, server and location contexts.
Thus, in order to have the filter activated only for the index.php page,
location = /index.php {
subs_filter '<body>' '<body>' My content;
# other things you would do for index.php
}

Wordpress MU Cloudfront. Trailing slash redirect goes to wrong domain

I'm having some trouble with redirects within wordpress redirection causing the domain to change.
Example:
Site - noncdn.somedomain.com
CDN URL - www.domain.com
When I open links w/o a trailing slash there is a 301 redirect:
Going here: www.domain.com/page
Takes you here: noncdn.somedomain.com/page/
Since Cloudfront is hitting the server using Origin Domain, the server doesn't even know that requests are coming in from a different domain.
How do I force this 301 to use FQDN w/ correct CDN domain instead of doing a relative redirect?
I've already added this so that links on the site and images all load from Cloudfront domain, but it seems to have no effect on the redirect behavior:
add_filter('home_url','home_url_cdn',10,2);
function home_url_cdn( $path = '', $scheme = null ) {
return get_home_url_cdn( null, $path, $scheme );
}
function get_home_url_cdn( $blog_id = null, $path = '', $scheme = null ) {
$cdn_url = get_option('home');
if(get_option('bapi_site_cdn_domain')){
$cdn_url = get_option('bapi_site_cdn_domain');
}
$home_url = str_replace(get_option('home'),$cdn_url,$path);
//echo $home_url;
return $home_url;
}
Any Help is much appreciated!
Thanks!
I was tracking down a very similar issue for a while with a Cloudfront distribution of a standard static website running on Nginx. The symptoms were the same, links with a trailing slash (e.g. www.acme.com/products/) worked correctly, but omitting the trailing slash caused the user to be redirected to the origin.
The issue is that the webserver software itself is not properly attempting to resolve URIs and is instead responding with a redirect to a URL it can serve. You can test this by using curl against your site:
$ curl http://myhost.com/noslashurl
HTTP/1.1 301 Moved Permanently [...]
CloudFront is returning exactly what your server returns, in this case a 301 redirect to your origin URL. Instead of following the redirect and caching that, CloudFront caches the redirect itself. The only way to correct this is to ensure that your origin properly handles the requests and does not respond with a 301.
In my particular case, that meant updating the try_files directive for my location in the nginx configuration. As I mentioned this is a static site, and so my try_files became:
location / {
[...]
try_files $uri $uri/index.shtml /index.shtml =404;
}
You want to be sure that the try_files has an endgame, to avoid redirection cycling which will cause your server to return 500 Server Errors when a non-existent URL is requested. In this case, /index.shtml is the last-ditch attempt and failing that, it will return a 404.
I know this doesn't precisely answer your question, but yours was one of a very few I found when searching for "cloudfront without trailing slash redirects to origin", and you've not had an answer for a year, so I figured it was worth sending a response.
I had the same problem.
I fixed the issue changing some wordpress parameters.
In the elasticbeanstalk I set the parameter CUSTOM_URL for my custom domain and in the file /var/www/html/wp-includes/load.php
I set the parameters HTTP_HOST and SERVER_NAME to same value of CUSTOM_URL, and it resolved the redirect to elasticbeanstalk url.
$_SERVER['HTTP_HOST'] = $_SERVER['CUSTOM_URL'];
$_SERVER['SERVER_NAME'] = $_SERVER['CUSTOM_URL'];

Header set Access-Control-Allow-Origin in .htaccess doesn't work

I can't figure out why my .htaccess header settings doesn't work.
My .htaccess file content:
Header set Access-Control-Allow-Origin *
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "*"
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
But when I remove Header's and add them in index.php then everything works fine.
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: *");
What am i missing?
This should work:
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
Just for the record, I was running into the exact same problem and none of the answers worked.
I used a headers checker tool: http://www.webconfs.com/http-header-check.php
I was testing with my IP (http://192.0.2.1/upload) and what came back was the following:
HTTP/1.1 301 Moved Permanently =>
Date => Sat, 10 Jan 2015 04:03:35 GMT
Server => Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/1.0.0e PHP/5.3.8 mod_perl/2.0.4 Perl/v5.10.1
Location => http://192.0.2.1/upload/
Content-Length => 380
Connection => close
Content-Type => text/html; charset=iso-8859-1
There was a redirection happening and the AJAX request does not honor/follow redirects.
It turned out to be the missing slash at the end of the domain (http://192.0.2.1/upload/)
I tested again with slash at the end and I got this below. Added a slash in the script too, and it was now working.
HTTP/1.1 200 OK =>
Date => Sat, 10 Jan 2015 04:03:53 GMT
Server => Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/1.0.0e PHP/5.3.8 mod_perl/2.0.4 Perl/v5.10.1
X-Powered-By => PHP/5.3.8
Access-Control-Allow-Origin => *
Access-Control-Allow-Methods => PUT, GET, POST, DELETE, OPTIONS
Access-Control-Allow-Headers => *
Content-Length => 1435
Connection => close
Content-Type => text/html
Use this tool to test if your headers are good and to troubleshoot what is happening.
I have a shared hosting on GoDaddy. I needed an answer to this question, too, and after searching around I found that it is possible.
I wrote an .htaccess file, put it in the same folder as my action page. Here are the contents of the .htaccess file:
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
Here is my ajax call:
$.ajax({
url: 'http://www.mydomain.com/myactionpagefolder/gbactionpage.php', //server script to process data
type: 'POST',
xhr: function() { // custom xhr
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // check if upload property exists
myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // for handling the progress of the upload
}
return myXhr;
},
//Ajax events
beforeSend: beforeSendHandler,
success: completeHandler,
error: errorHandler,
// Form data
data: formData,
//Options to tell JQuery not to process data or worry about content-type
cache: false,
contentType: false,
processData: false
});
See this article for reference:
Header set Access-Control-Allow-Origin in .htaccess doesn't work
Be careful on:
Header add Access-Control-Allow-Origin "*"
This is not judicious at all to grant access to everybody. It's preferable to allow a list of know trusted host only...
Header add Access-Control-Allow-Origin "http://aaa.example"
Header add Access-Control-Allow-Origin "http://bbb.example"
Header add Access-Control-Allow-Origin "http://ccc.example"
Regards,
I activated the Apache module headers a2enmod headers, and the issue has been solved.
Try this in the .htaccess of the external root folder
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
Be careful with doing Header add Access-Control-Allow-Origin "*" This is not judicious at all to grant access to everybody. I think you should user:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "http://example.com"
</IfModule>
I +1'd Miro's answer for the link to the header-checker site http://www.webconfs.com/http-header-check.php. It pops up an obnoxious ad every time you use it, but it is, nevertheless, very useful for verifying the presence of the Access-Control-Allow-Origin header.
I'm reading a .json file from the javascript on my web page. I found that adding the following to my .htaccess file fixed the problem when viewing my web page in IE 11 (version 11.447.14393.0):
<FilesMatch "\.(json)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>
I also added the following to /etc/httpd.conf (Apache's configuration file):
AllowOverride All
The header-checker site verified that the Access-Control-Allow-Origin header is now being sent (thanks, Miro!).
However, Firefox 50.0.2, Opera 41.0.2353.69, and Edge 38.14393.0.0 all fetch the file anyhow, even without the Access-Control-Allow-Origin header. (Note: they might be checking IP addresses, since the two domains I was using are both hosted on the same server, at the same IPv4 address.)
However, Chrome 54.0.2840.99 m (64-bit) ignores the Access-Control-Allow-Origin header and fails anyhow, erroneously reporting:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin '{mydomain}' is therefore not allowed access.
I think this has got to be some sort of "first." IE is working correctly; Chrome, Firefox, Opera and Edge are all buggy; and Chrome is the worst. Isn't that the exact opposite of the usual case?
After spending half a day with nothing working.
Using a header check service though everything was working.
The firewall at work was stripping them
try this:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Credentials true
Header set Access-Control-Allow-Origin "your domain"
Header set Access-Control-Allow-Headers "X-Requested-With"
</IfModule>
It's preferable to allow a list of know trusted host.
If anyone else is trying this, the most upvoted answer should work. However, if you are having issues it could be possible the browser has cached the REQUEST. To confirm append a query string.
To complete the most upvoted answer, I want to add the case whenever the options to the header is not add in a response request, you could add the always keyword from Apache.
In my case i needed to add the access control allow origin in the response of the redirection and not in the result of the redirection.
And a redirection is giving the 302 code status so the header wasn't filled with the correct information.
In this case I needed to add it :
Header always set Access-Control-Allow-Origin "*"
For more information you can check this thread :
Apache: difference between "Header always set" and "Header set"?

Resources