fastcgi_cache_key exclude some args in request uri - regex

My fastcgi_cache_key is:
fastcgi_cache_key "$host$request_method$request_uri";
My $request_uri has timestamp and signature in it:
/abc/xyz?product_id=10529125896&shop_id=17224077&shop=abc.com&path_prefix=%2Fa%2Fcomment&timestamp=1503044416&signature=882102c51c7b7bd4c5d8521a6565fc70c27b908547316f1123eb4af13b19f2da
So, the cache always MISS (because it has different timestamp and signature). My question is:
I want to create new var and use that var for fastcgi_cache_key. That var will has something like this:
myvar
/abc/xyz?product_id=10529125896&shop_id=17224077&shop=abc.com
fastcgi_cache_key will like this:
fastcgi_cache_key "$host$request_method$myvar";
How can I do that ? Thanks so much.

There are two ways to do it.
if ($request_uri ~ "([^\?]*)\?(.*)timestamp=([^&]*)&?(.*)") {
set $args $2$4;
}
fastcgi_cache_key "$host$request_method$args";
This will remove the timestamp. You can either modify the pattern to ignore one more field or you can use it twice to remove the field from $args.
Next option is to use openresty or Nginx with lua which allows you to execute Lua script in your code. if conditions are not considered good. But then having lua increases your software requirement

Related

pretty permalinks on custom query vars in wordpress

I am using a hierarchal custom post type (post type is called locations, slug = location) in WordPress. Locations can be nested (country/state/city)
I have successfully added custom query vars :
add_filter('query_vars', function($vars) { $vars[] = "view"; return $vars; });
which I use to decide what data to show for the location.
For example, mysite.com/location/country/?view=facts or mysite.com/location/country/state/city/?view=events
All of which is working great.
But I want to be able to access it as:
mysite.com/location/country/facts
mysite.com/location/country/state/city/facts
I have been playing around with add_rewrite_rule but can't make it work. Not sure if my $regex or $query is the problem; regex isn't my strong suit.
add_rewrite_rule( '/(view)/g', 'index.php?post_type=locations?view=$matches[1]','top' );
Try add_rewrite_endpoint, it is actually much simpler
https://developer.wordpress.org/reference/functions/add_rewrite_endpoint/
https://make.wordpress.org/plugins/2012/06/07/rewrite-endpoints-api/

How can I get a param using regex in a nginx server block?

I'm trying to get a param(h=1500 for example) via regex in a server block in an nginx server but it's not working. My last try was this:
location ~ "^/app/events/(?<eventid>\d+)/(?<image>.+)?h=(?<height>\d+)$" { ...... }
Here you can check and it works: https://regex101.com/r/kP9eY9/1
But in my server block file it does't.
If I try something like this, it works:
location ~ "^/app/events/(?<eventid>\d+)/(?<image>.+)/(?<height>\d+)$" { ...... }
Instead a param like "h=300", I just use a "/300" and I can get the value in my server block file.
I'm not a expert using regex so I can't see if there is something wrong. I need your help guys! Thank you!
From the documentation:
locations of all types test only a URI part of request line without
arguments
which means the ? and anything that follows it.
As #Richard mentioned, you can't use request arguments in locations regexps.
If you need to work with request arguments in your nginx config you might use $arg_ and/or $args syntax:
http://nginx.org/en/docs/http/ngx_http_core_module.html#var_arg_
http://nginx.org/en/docs/http/ngx_http_core_module.html#var_args
I.e
location / {
if ($arg_param = 'someval') {
# some code here
}
}

varnish split url and change url

Is there a way to split url on varnish or change url structure with it.
I know regsub or regsuball support that but they are not enough in my case.
I would like to change a url and redirect it to another domain.
For example:
http://aaa.test.com/sport/99244-article-hyun-jun-suku-kapa.html?
to redirect below address
http://m.test.com/article-hyun-jun-suku-kapa-sport-99244/
I added some lines in vcl file to do that
set req.http.xrul=regsuball(req.url,".html",""); "clear .html"
set req.http.xrul=regsub(req.http.xrul,"(\d+)","\1"); find numbers --article ID =99244
I can rid of the article ID with
set req.http.xrul=regsub(req.http.xrul,"(\d+)","");
but cannot get just only article ID
set req.http.xrul=regsub(req.http.xrul,"(\d+)","\1"); or any other method
Does varnish support split the url with "-" pattern thus I could redesign the url? Or can we get only articleID with regsub?
Is this what you want to achieve?
set req.http.X-Redirect-URL = regsuball(req.url,"^/([^/]*)/([0-9]+)-([^/]+)\.html$","http://m.test.com/\3-\1-\2");
This is working code tailored to example you provided, just one level of section placement.
If you want to support more levels of sections, you only have to adjust regexp a bit and replace / to - in second step:
set req.http.X-Redirect-URL = "http://m.test.com/" + regsuball(regsuball(req.url, "^/(.*)/([0-9]+)-([^/]+)\.html$", "\3-\1-\2"), "/", "-");
Maybe you need one more refinement. What if URL doesn't match you pattern? X-Redirect-URL will be the very same value as req.url is. You definitely don't want redirect loop, so I suggest to add mark character to the begin of X-Redirect-URL and then test for it.
Let's say:
set req.http.X-Redirect-URL = regsuball(regsuball(req.url, "^/(.*)/([0-9]+)-([^/]+)\.html$", "#\3-\1-\2"), "/", "-");
if(req.http.X-Redirect-URL ~ "^#") {
set req.http.X-Redirect-URL = regsuball(req.http.X-Redirect-URL, "#", "http://m.test.com/");
return(synth(391));
} else {
unset req.http.X-Redirect-URL;
}
and for all cases, you need in vcl_synth:
if (resp.status == 391) {
set resp.status = 301;
set resp.http.Location = req.http.X-Redirect-URL;
return (deliver);
}
Hope this helps.

Regex JSON response Gatling stress tool

Wanting to capture a variable called scanNumber in the http response loking like this:
{"resultCode":"SUCCESS","errorCode":null,"errorMessage":null,"profile":{"fullName":"TestFirstName TestMiddleName TestLastName","memberships":[{"name":"UA Gold Partner","number":"123-456-123-123","scanNumber":"123-456-123-123"}]}}
How can I do this with a regular experssion?
The tool I am using is Gatling stress tool (with the Scala DSL)
I have tried to do it like this:
.check(jsonPath("""${scanNumber}""").saveAs("scanNr")))
But I get the error:
---- Errors --------------------------------------------------------------------
> Check extractor resolution crashed: No attribute named 'scanNu 5 (100,0%)
mber' is defined
You were close first time.
What you actually want is:
.check(jsonPath("""$..scanNumber""").saveAs("scanNr")))
or possibly:
.check(jsonPath("""$.profile.memberships[0].scanNumber""").saveAs("scanNr")))
Note that this uses jsonPath, not regular expressions. JsonPath should more reliable than regex for this.
Check out the JsonPath spec for more advanced usage.
use this regex to match this in anywhere in json:
/"scanNumber":"[^"]+"/
and if you want to match just happens in structure you said use:
/\{[^{[]+\{[^{[]+\[\{[^{[]*("scanNumber":"[^"]+")/
Since json fields may change its order you should make your regex more tolerant for those changes:
val j = """{"resultCode":"SUCCESS","errorCode":null,"errorMessage":null,"profile":{"fullName":"TestFirstName TestMiddleName TestLastName","memberships":[{"name":"UA Gold Partner","number":"123-456-123-123","scanNumber":"123-456-123-123"}]}}"""
val scanNumberRegx = """\{.*"memberships":\[\{.*"scanNumber":"([^"]*)".*""".r
val scanNumberRegx(scanNumber) = j
scanNumber //String = 123-456-123-123
This will work even if the json fields will be in different order (but of course keep the structure)

How to use a wildcard in isDefined() or structKeyExists() in a URL?

I am using ColdFusion 8.0.1.
I am writing a little code in the application file that will look at the URL. If any of a certain type of property is passed, I don't want to update a property in a SESSION structure.
Basically, if a visitor accesses any page that has to do with our registration process, we do not want to update the SESSION.UserInfo.ReturnToURL variable. For every other page they access, we want to update the variable.
All pages that have to do with the registration process will have "myiq.reg" in the URL. If this were the case, I would use the code below.
// DETERMINE WHETHER TO UPDATE RETURNTOURL
if (not structKeyExists(URL, "myiq.reg")) {
URLString = "http://" & CGI.SERVER_NAME & CGI.SCRIPT_NAME & CGI.QUERY_STRING;
SESSION.UserInfo.ReturnToURL = URLString;
}
But it's not that simple. My people want to be able to pass other properties that are similar, like this:
myiq.reg_confirm
myiq.reg_password
myiq.reg_save
I need to be able to soft code these to work with any registration page that they might create in the future. Basically, I need something like this :
if (not structKeyExists(URL, "myiq.reg*")) {
SESSION.UserInfo.ReturnToURL = URLString;
}
Notice the WILDCARD after "myiq.reg". I've tried this, but it doesn't work.
How do I code this so that any page that is access with a URL property that begins with "myiq.reg" is ignored?
You could get a structKeyList() of the URL scope, and just do a regex find in that. Something like:
reFindNoCase("(?:^|,)myiq\.reg", structKeyList(URL))
(only superficially tested)
You could improve the regex a bit if you wanted to more accurately match actual variable name patterns rather than just any occurrence of myiq.reg in the string.
Something like this perhaps...
res = '';
params = StructKeyList(url);
for(i=1; i lte ListLen(params); i++) {
param = listGetAt(params, i);
if (CompareNoCase(Left(param, 8), 'myiq.reg') eq 0) {
res = param;
break;
}
}