*solved* Nginx Rewrite : Regex failed, i need some advice - nginx

I tried many versions but my regex doesn't work.
url tested : https://mywebsite.com/mypage.html#page123
All of this fail
rewrite ^/\#(.*)$ /myscript.php?mode=multi&blob=$1 break
rewrite ^/\#(page)[0-9]$ /myscript.php?mode=multi&blob=$1 break
rewrite ^/[[:graph:]](page)[0-9]$ /myscript.php?mode=multi&blob=$1 break
nginx reboot fail because {1,3} part
rewrite ^/\#(page)[0-9]{1,3}*$ /myscript.php?mode=multi&blob=$1 break
OK, this works fine but missing information about page
rewrite ^/([a-z0-9\-]+).html$ /myscript.php?mode=default&id=$1 break;
myscript.php has only one line :
print_r($\_REQUEST);
exit();
Each time, my script only print : Array ( [mode] => default [id] => mypage )
(sorry, bad english sometime)
All of this works fine too on https://regex101.com/

Related

Swagger UI not working as expected while service behind Nginx reverse-proxy

I use swagger-ui-express package(https://github.com/scottie1984/swagger-ui-express) (Node.js) and work fine with this config:
const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./swagger.json');
app.use('/api-docs',swaggerUi.serve, swaggerUi.setup(swaggerDocument));
when directly got to /api-docs every thing is fine,
but when i come from nginx for example host/myApp/api-docs redirect me to host/api-docs and it's obvious that after redirect I get 404
The problem was for the swagger-ui-express middleware that redirect user to host/api-docs and don't use the prefix of path, so I solved this problem with a trick I use middleware with this path :
const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./swagger.json');
app.use('/app-prefix/api-docs',swaggerUi.serve, swaggerUi.setup(swaggerDocument));
and in nginx I defined two location :
location /app-prefix/api-docs {
proxy_pass http://172.18.0.89:3000/app-prefix/api-docs;
}
location /app-prefix/ {
proxy_pass http://172.18.0.89:3000/;
}
so when user request to nginx , nginx route it to application second path :
/app-prefix/api-docs
and after that swagger middlware redirect it to host/app-prefix/api-docs
and redirect to correct path,
now application route and swagger works fine.
add this options and test it :
explorer: true,
swaggerOptions: {
validatorUrl: null
}
};
app.use('/api-docs',swaggerUi.serve, swaggerUi.setup(swaggerDocument, swaggerOption));```
This is an old question, but I just run into the same problem. I am able to resolve this without using ngnix rewrite.
// serve the swagger ui in a temporary directory
app.use('/temp-api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
// swagger-ui-express middleware that redirect user to /api-docs will not be aware the prefix of path by ngnix
const apiDocsRedirectPath = "application/prefix/go/here".concat('/temp-api-docs/');
app.get('/api-docs', function(req, res) {
res.redirect(apiDocsRedirectPath);
});
I also had this problem and the marked correct answer worked for me. However, I do not understand how it is working because I don't know much about Nginx.
Here is my solution for future people with this issue.
this.app.use(
"/api-docs",
swaggerUi.serve,
swaggerUi.setup(openapiSpecification as OpenAPIV3.Document)
);
The express app itself is behind an nginx proxy which looks like this
location /api/v1/myapp/ {
proxy_pass http://myapp:3001/;
}
So when a request is made to example.com/api/v1/myapp/api-docs it comes out of the proxy to myapp like myapp:3001/api-docs which is fine, up until (I think) swagger UI express tries to load resources from example.com/api-docs which will 404 of course.
I solved it by adding this as a redirect.
location /api/v1/myapp/ {
proxy_pass http://myapp:3001/;
}
location /api-docs/ {
return 302 /api/v1/myapp/api-docs/;
}
So now when swagger goes off to request things at example.com/api-docs it is redirected to the correct location block and works like normal.
Again, not an expert with this but this seems to work and I think its easy to understand.
The caveat is that you are stuck with just one /api-docs so if you have multiple swagger endpoints this does not work.
None of the answers worked for me. I've solved it using a custom middleware.
middlewares/forwardedPrefixSwagger.js
const forwardedPrefixSwagger = async (req, res, next) => {
req.originalUrl = (req.headers['x-forwarded-prefix'] || '') + req.url;
next();
};
app.js
app.use('/docs/node/api/swagger/', middlewares.forwardedPrefixSwagger, swaggerUi.serve, swaggerUi.setup(swaggerFile, options));
Note: For this to work the URL must include a trailing slash.

Wordpress URL is replacing with load balancer URL

I am using one wordpress site. In this wordpress URL I am using 2 load balancing URL in my production.
For Example My actual URL is
www.myurl.com
My load blancer URL's are
www.myurl01.drd.myurl.com
www.myurl02.drd.myurl.com
For wordpress current URL I am using the following function in function.php
function current_url() {
$pageURL = 'http';
if( isset($_SERVER["HTTPS"]) ) {
if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;
}
This function returning www.myurl01.drd.myurl.com load balancer URL instead of www.myurl.com. how can get my actual URL using this function.
Any one please suggest
Your implementation of current_url() does not handle the case where WordPress is running behind a proxy. Values in the SERVER array corresponding to the keys: HTTPS, SERVER_PORT and SERVER_NAME relate to the back-end server only.
The front-end proxy server may set specific headers to enable the back-end to detect that it is running behind a proxy. The WordPress core functions already support these extra settings and you may wish to look at those implementations before you make changes to your code.
If you want a quick fix (and assuming that your proxy server sets the value correctly) using HTTP_HOST in the place of SERVER_NAME may solve the immediate problem.
For a complete fix, you may want to look at using HTTP_X_FORWARDED_PROTO and HTTP_X_FORWARDED_PORT. If these values are defined, they should be use instead of the local equivalent.

Redirecting naked domains to www in Meteor with Iron Router

I'd like to auto-redirect users who enter the naked domain for my site over to the www subdomain. Pre-Blaze, here's the code I was using to do this with Iron Router:
Router.onBeforeAction(function() {
var rootDomainRegex = new RegExp(
'^https:\\/\\/mysite.com',
'ig'
);
if ( window && rootDomainRegex.test( window.location.href ) ) {
this.stop();
window.location = window.location.href.replace(
rootDomainRegex,
'https://www.mysite.com'
);
}
};
This stopped working when I upgraded to Meteor 0.8.0 and the Blaze-compatible version of Iron Router. (I replaced this.stop() with pause(), but that didn't help.) Now the page simply hangs when you navigate to the naked domain, with no console errors.
Does anyone have a reliable and Blaze-compatible way to redirect users from a naked domain over to www? (Or maybe this shouldn't be at the app level at all?)
Here's my post-Blaze code. (This is the code that's currently not working.)
Router.onBeforeAction(function(pause) {
var rootDomainRegex = new RegExp(
'^https:\\/\\/mysite.com',
'ig'
);
rootDomainRegex.lastIndex = 0;
if ( window && rootDomainRegex.test( window.location.href ) ) {
window.location = window.location.href.replace(
rootDomainRegex,
'https://www.mysite.com'
);
pause();
}
});
Edit with just a bit of extra info: I've just discovered that with the naked domain, the function passed to Router.onBeforeAction() simply doesn't run at all.
You should've pasted the updated code, where you've replaced this.stop with pause.
I doubt there's anything blaze-related to your code, it should just work and you should be redirected even if you don't call pause. So it probably is because your regex is not matching.
I guess you tried to call console.log(rootDomainRegex.test(window.location.href)) before the if statement and it returned true?! If you did, that's the cause, the first time you call regex.test, it matches returning true, but also increases lastIndex on the regex - because of the g flag, the second time you call test it tries to match from that lastIndex and it fails, never executing the window.location part.
HTH, try to paste the exact code you have now not working if it doesn't.

URL redirection not working properly: genetates the url http://domain.com/domain.com/

I have a WordPress site in two languages (Hebrew and English) and I need it to redirect according to browser language. I'm using qTranslate plugin to create the content in both languages. This plugin also has a redirection functionality but it creates a redirection only for the homepage and I need the redirection to happen for internal pages as well as the homepage.
Another developer wrote this code for me to create the redirection, but for some reason it creates a funny redirect. It happens only when switching language to Hebrew, then leaving the site and trying to enter directly to http://domain.com/en/ and it redirects you to http://domain.com/domain.com/ (Does not happen when switching to english).
I tried playing with the "header (Location: )" that creates the redirection for Hebrew, but couldn't figure out how to make it work - I tried using the full path instead of relative path, or removing the "/" between $_SERVER['SERVER_NAME'] and $_SERVER['REQUEST_URI'] but got recursive url or url with double "/" (http://domain.com// and also for internal pages http://domain.com//page).
The url structure is:
domain.com/ for Hebrew
domain.com/en/ for English
and when switching language then the parameter $lang=en or $lang=he is being added.
Hope this makes sense, and thanks a lot!
this is the code that is responsible for the redirection:
<?php
if (!isset($_COOKIE["uln"])) :
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
setcookie('uln', $lang, time()+86400*365, '/', '.domain.com'); // cookie stored for a year
$_COOKIE['uln'] = $lang;
endif;
//if lang=(value) is not empty
if(isset($_GET['lang'])) {
$lang = $_GET['lang'];
setcookie('uln', $lang, time()-1, '/', '.domain.com'); //this unsets the cookie for random language selection
//set the cookie "uln" again with the selected language.
setcookie('uln', $lang, time()+86400*365, '/', '.domain.com'); // cookie stored for a year
$_COOKIE['uln'] = $lang;
}
if(($_COOKIE["uln"]) == "en") {
$matched = strncmp("/en/", $_SERVER['REDIRECT_URL'], 3);
if ($matched !== 0) :
header('Location: /en'.$_SERVER['REQUEST_URI']);
endif;
} elseif(($_COOKIE["uln"]) == "he") {
$matched = strncmp("/en/", $_SERVER['REDIRECT_URL'], 3);
if ($matched === 0) :
header('Location: '.$_SERVER['SERVER_NAME'].'/'.$_SERVER['REQUEST_URI']);
endif;
}
?>
instead of
header('Location: '.$_SERVER['SERVER_NAME'].'/'.$_SERVER['REQUEST_URI']);
try
header("Location: http://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}");
URLs, especially those in Location headers, should include a protocol and domain name. I believe relative URLs in Location headers are a violation of the HTTP RFCs.
By omitting a protocol, you're unintentionally specifying a relative url instead of an absolute one.
Edit: REQUEST_URI is already prefixed with a / so including one in the concat is unnecessary.
You're missing an http:// somewhere, probably in the English -> Hebrew redirect code.
Change
header('Location: '.$_SERVER['SERVER_NAME'].'/'.$_SERVER['REQUEST_URI']);
to
header('Location: http://'.$_SERVER['SERVER_NAME'].'/'.$_SERVER['REQUEST_URI']);

Loading Google Maps API with wp_enqueue_script

I'm trying to load the Google Maps API using the following syntax:
add_action('admin_enqueue_scripts', 'load_google_maps');
...
function load_google_maps()
{
// The actual API key is configured in an options page
$key = get_option('google_maps_api_key');
$gmaps_url = 'http://maps.googleapis.com/maps/api/js?key=' . $key . '&sensor=false';
wp_enqueue_script('google-maps', $gmaps_url, NULL, NULL);
}
WordPress is escaping the "&" to "&#038". This actually makes the Google server reject the request. When I type it directly into browser address bar with "&sensor=false" at the end, it loads fine.
I saw a bug of this kind mentioned in the WordPress trac system: http://core.trac.wordpress.org/ticket/9243 but it was dismissed as invalid, and the admin responding to the request showed somehow that the "&#038" approach was fine. It is definitely not fine from Google's point of view.
I could of course just get the function to echo the HTML as a script tag, but I'd rather use the wp_enqueue_script system if possible.
Anyone know of a solution to this?
Cheers,
raff
I've got something similar in our code, and it's working fine (even encoded as &#038). I suspect your problem is that it's being double-encoded, as you already have &. Trying changing it to:
$gmaps_url = 'http://maps.googleapis.com/maps/api/js?key=' . $key . '&sensor=false';
For what it's worth, our (working) code is:
wp_register_script('googlemaps', 'http://maps.googleapis.com/maps/api/js?' . $locale . '&key=' . GOOGLE_MAPS_V3_API_KEY . '&sensor=false', false, '3');
wp_enqueue_script('googlemaps');
($locale in this case is set to hl=en)
Edit
Looks like the behaviour's changed in the latest version of WordPress - the above doesn't work (but I'll leave it for people on legacy versions). The only alternative I can see to echoing the script is to add a clean_url filter, something like this:
add_filter('clean_url', 'so_handle_038', 99, 3);
function so_handle_038($url, $original_url, $_context) {
if (strstr($url, "googleapis.com") !== false) {
$url = str_replace("&", "&", $url); // or $url = $original_url
}
return $url;
}
Pretty ugly, but perhaps marginally better than echoing the script, as it'll still use the WordPress dependency management.

Resources