How to set routing between nginx locations based on regex with wildcard - regex

I have some http api behind nginx, and i want to make filter requests to API based on requests parameters value. Parameters are passed directly in url like
https://api.com/api/v1/action?param1=value1&param2=value2&etc...
Lets assume that i want to filter requests with some value of param2 to some other url.
I thought that it will be easy like
location ~* /api/.*param2=somevalue.* { #location; }
But nginx cant find the match even if there is no alternative location at all.
I'm confused. Are these wildcards are truly wildcards, or I miss something? But what?
I already tried escaping and different modifiers but no luck. :(

Related

Regex to find URL including those that simply start with // (Protocol-relative URLs)

This Regex finds URLs that begin with http and https
https?:\/\/(www\.)?[-a-zA-Z0-9#:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9#:%_\+.~#?&//=]*)
I am trying to figure out how to modify this to including those URLs which omit the http or https part. I understand that these are called 'Protocol-relative URLs'
example: //example.com and not http://example.com
Simply make the protocol part optional:
(https?:)?(\/\/)?(www\.)?[-a-zA-Z0-9#:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9#:%_\+.~#?&//=]*)
By the way I assume you really wanted example.com and not //example.com (since no one writes a URL that way).

CloudFront redirect request with Lambda to trailing slash

I have a static SPA page that is using S3 as it's origin with CloudFront. If I visit www.domain.com/page, I will get the CloudFront path prefixed bucket-directory/prod/page/ which is expected.
Is it possible to capture the path in AWS Lambda and append the trailing slash to a request, so it becomes, www.domain.com/page > [Lambda] > www.domain.com/page/
I've been looking and trying the following resources to little avail:
http://blog.rowanudell.com/redirects-in-serverless/
http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html
Getting a perfect setup for a SPA or static page on Cloudfront is not trivial. In short, you will need to use (at least) an origin request lambda function setting for your CF distro. You need to handle a few edge cases like:
hashes
redirects to urls with trailing slashes (that you mentioned)
forwarding of query parameters when redirecting
For a quick starting function you can check this article https://tinyendian.com/articles/better-origin-response-function-for-cloudfront-hosted-static-pages explaining the actual code that you can copy from here https://gist.github.com/karolmajta/6aad229b415be43f5e0ec519b144c26e
Of course it is likely that as your app changes, you will need to modify this snippet here and there to match your needs.
You can do that via two ways.
In the CloudFront pattern, you can check for bucket-directory/prod/page and do a redirect with a lambda to bucket-directory/prod/page/.
Also you need to make sure the pattern to be in the following order,
bucket-directory/prod/page <-- this will get to lambda to perform redirect
bucket-directory/prod/page/
page will a regex based on your naming convention.
Or You can write a Lambda Function that can take the url and modify the url to append a slash if it is not there and forward the request to the origin.
http://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html
Lambda Edge will make it much easier and avoids a redirect.
With Lambdda Edge you can change from bucket-directory/prod/page to bucket-directory/something/someotherpage as well.
The documentation link should help.

How to convert url to regex statement

I want to use ACL for authorization (https://www.npmjs.com/package/acl) but i can't use it with complex urls like http://domain.com/api/v1/resource/:id1/anotherResource/:id2
Using node js, express can handle finding right function from the url from request's originalUrl or something else. I need to put regular expressions statements of requested urls into configuration of ACL.
I debugged express step by step and found regex form of url on 84th line of Layer.js but I need to know every regex form of url to use ACL module as a middleware.
Is there any way to get regexp string (like in the picture below) of url to use in middleware?
Use path-to-regexp module which is used internally by expressjs (actually you were very close to finding it while debugging)

Avoiding double caching of items available from different URIs using Varnish

In the Varnish Cache wiki it states an example of how to regsub to avoid caching request to www.example.com and example.com separately. The example from https://www.varnish-cache.org/trac/wiki/RedirectsAndRewrites is:
set req.http.host = regsub(req.http.host, "^www\.example\.com$","example.com");
"Requests to www.example.com and example.com will all go to the backend as "example.com" and end up cached by that string." This means duplicate caching does not occur.
I have multiple sites using the same varnish server (VCL) so am looking to replace "example.com" with a statement that will work on multiple URLs. eg:
www.example1.co.uk > example1.co.uk
www.example2.com > example2.com
What would be the appropriate regex (if that is the correct term) for this?
There are multiple separate domains (different sites with different content on different domains) using this VCL I am hoping to avoid having to alter the vcl when new sites are added/removed. Therefore a generic solution is what I am after, something that can be applied to any domain to remove the possibility of a duplicate with/without the WWW alias being store/served by Varnish. (Having trouble phrasing this, hope it is clearer!!)
I am aware that redirecting can be done outside of varnish, in Apache etc, but not looking for that as a solution.
set req.http.host = regsub(req.http.host,
"^www\.(.*)$",
"\1");
This will strip www off any domain. (I do feel reluctant to give you this answer, as it goes against my religion)
You might get penalized by search engines for serving the same content on multiple URLs, but SEO is a different topic.
Instead of what Chris suggested, you can just remove the www part:
set req.http.host = regsub(req.http.host, "^www\.", "");
Should be a teeny tiny bit faster, too

Can you use ProxyPassMatch to change the query string of a URL?

I am not sure if what I'm trying to do is valid, so please bear with me.
I am trying to use the ProxyMassMatch (Apache) Directive through a reverse proxy setup to change URLs which appear on a given page when accessed through my localhost and remove an "sid" parameter. I am aware this particular regex only accounts for when the parameter is not the first cgi arg, but the bigger problem I am having is this doesn't seem to work at all so I'm thinking maybe I do not understand ProxyPassMatch, despite reading the docs multiple times.
To visualize, if this were working, I would be able to mouse-over a url on my "localhost" page and instead of:
http://forums.mysite.com/viewtopic?foo=bar&sid=9746b404cec3e5270f79e6c1de861dae
I would see:
http://forums.mysite.com/viewtopic?foo=bar
I have successfully removed this cgi arg with mod_rewrite, but because of other mechanisms, I've been asked to do this using ProxyPassMatch so the URLs on the actual page do not display the "sid" parameter. Does anyone have any insight into this?
Here's one of the many variations I've tried in my .conf file.
ProxyPassMatch "(.*forums\.mysite\.com\/viewtopic\.php)(.*[^&]*)(&sid=.*)" "http://localhost/forums.mysite.com/$2"