Passing variable between blocks in Openresty/Lua with ngx.ctx - nginx

Trying to pass a variable between two lua blocks. Supposedly, this should work with ngx.ctx, like this:
header_filter_by_lua_block {
ngx.ctx.myvar = ngx.header["X-fetch"];
}
access_by_lua_block {
ngx.header["X-send"] = ngx.ctx.myvar;
}
but it doesn't. What's wrong?
P.S. Testing with both in one block does work (basically duplicating the existing header, but this is just for illustration)
header_filter_by_lua_block {
ngx.ctx.myvar = ngx.header["X-fetch"];
ngx.header["X-send"] = ngx.ctx.myvar;
}

That's because access_by_lua_block runs before header_filter_by_lua_block.
Take a look at https://openresty-reference.readthedocs.io/en/latest/Directives/

Related

How to check if variable is not exist

I can't find in docs how I can do negative statement like one below:
if !($some_var) {
... enter here if $some_var doesn't exist or empty
}
I know that I can check that the variable is exits using the if statement:
if ($some_var) {
...
}
But I can't find how to do if not statement
Is it possible for NGINX?
Try this:
if($var = false) {
....
}

Using non-scalar variables in BuildMaster otter-script plans

I'm pulling my hair out trying to get some very basic iteration working using non-execution set variables (ie setting things at Global with potential to override at lower scope).
Setting a $variable to some value works fine but I need to do something like...
foreach $DeployConfigKey in #MapKeys(%DeployConfigs)
{
...
}
So far I'm getting nowhere fast with execution errors saying "Invalid value for property Map; expected map."
Further doing something like set %executionvar = %DeployConfigs complains that a map cannot be set to a scaler value.
The variable, DeployConfigs looks like ...
%{"Web.config": ["Web.Beta.config", "Web.Release.config"]}
and is defined at Global scope.
What am I doing wrong?
I'm using buildmaster 5.7.3
Maps are specified as %(key: value), here is an example plan that should help:
set %map = %(Web.config: #("Web.Beta.config", "Web.Release.config"));
foreach $key in #MapKeys(%map)
{
set #values = %map[$key];
Log-Information `$key = $key;
Log-Information `#values = $Join(", ", #values);
}
Sleep 3;

Using jsonPath looking for a string

I'm trying to use jsonPath and the pick function to determine if a rule needs to run or not based on the current domain. A simplified version of what I'm doing is here:
global
{
dataset shopscotchMerchants <- "https://s3.amazonaws.com/app-files/dev/merchantJson.json" cachable for 2 seconds
}
rule checkdataset is active
{
select when pageview ".*" setting ()
pre
{
merchantData = shopscotchMerchants.pick("$.merchants[?(#.merchant=='Telefora')]");
}
emit
<|
console.log(merchantData);
|>
}
The console output I expect is the telefora object, instead I get all three objects from the json file.
If instead of merchant=='Telefora' I use merchantID==16 then it works great. I thought jsonPath could do matches to strings as well. Although the example above isn't searching against the merchantDomain part of the json, I'm experiencing the same problem with that.
Your problem comes from the fact that, as stated in the documentation, the string equality operators are eq, neq, and like. == is only for numbers. In your case, you want to test if one string is equal to another string, which is the job of the eq string equality operator.
Simply swap == for eq in you JSONpath filter expression and you will be good to go:
global
{
dataset shopscotchMerchants <- "https://s3.amazonaws.com/app-files/dev/merchantJson.json" cachable for 2 seconds
}
rule checkdataset is active
{
select when pageview ".*" setting ()
pre
{
merchantData = shopscotchMerchants.pick("$.merchants[?(#.merchant eq 'Telefora')]"); // replace == with eq
}
emit
<|
console.log(merchantData);
|>
}
I put this to the test in my own test ruleset, the source for which is below:
ruleset a369x175 {
meta {
name "test-json-filtering"
description <<
>>
author "AKO"
logging on
}
dispatch {
domain "exampley.com"
}
global {
dataset merchant_dataset <- "https://s3.amazonaws.com/app-files/dev/merchantJson.json" cachable for 2 seconds
}
rule filter_some_delicous_json {
select when pageview "exampley.com"
pre {
merchant_data = merchant_dataset.pick("$.merchants[?(#.merchant eq 'Telefora')]");
}
{
emit <|
try { console.log(merchant_data); } catch(e) { }
|>;
}
}
}

assigning value in razor difficulty

I am having the following pice of code which is firing error
Error 1 Invalid expression term '='
#{
int Interest;
}
<td>#if (#item.interest.HasValue)
{
#Interest= #item.interest.Value.ToString("F2");
}
When declaring a variable, this variable needs to be assigned:
#{
string Interest = "";
}
and then:
#if (item.interest.HasValue)
{
Interest = item.interest.Value.ToString("F2");
}
This being said doing something like this in a view is a very bad design. I mean things like declaring and assigning variables based on some condition is not a logic that should be placed in a view. The view is there to display data. This logic should go to your controller or view model.
Inside your #if block you can address variables without the # sign.
#if (#item.interest.value) {
#item= #item.interest.Value
}
Is interpreted as:
#if (#item.interest.value) {
Write(item=);
Write(#item.interest.Value);
}
As you can see Write(item=) is not valid C# code.
You should use:
#if (item.interest.value) {
item = item.interest....
}
The reason your if (#item....) statement compiles, with the # sign. Is because you can prefix an identifier with the # to use reserved words as identifier names.
Try this:
#{
string Interest;
}
<td>#if (#item.interest.HasValue)
{
Interest= #item.interest.Value.ToString("F2");
}
By the way you are trying to assign a string (the result of ToString()) to an integer. This will not work.

Is there a version of the removeElement function in Go for the vector package like Java has in its Vector class?

I am porting over some Java code into Google's Go language and I converting all code except I am stuck on just one part after an amazingly smooth port. My Go code looks like this and the section I am talking about is commented out:
func main() {
var puzzleHistory * vector.Vector;
puzzleHistory = vector.New(0);
var puzzle PegPuzzle;
puzzle.InitPegPuzzle(3,2);
puzzleHistory.Push(puzzle);
var copyPuzzle PegPuzzle;
var currentPuzzle PegPuzzle;
currentPuzzle = puzzleHistory.At(0).(PegPuzzle);
isDone := false;
for !isDone {
currentPuzzle = puzzleHistory.At(0).(PegPuzzle);
currentPuzzle.findAllValidMoves();
for i := 0; i < currentPuzzle.validMoves.Len(); i++ {
copyPuzzle.NewPegPuzzle(currentPuzzle.holes, currentPuzzle.movesAlreadyDone);
copyPuzzle.doMove(currentPuzzle.validMoves.At(i).(Move));
// There is no function in Go's Vector that will remove an element like Java's Vector
//puzzleHistory.removeElement(currentPuzzle);
copyPuzzle.findAllValidMoves();
if copyPuzzle.validMoves.Len() != 0 {
puzzleHistory.Push(copyPuzzle);
}
if copyPuzzle.isSolutionPuzzle() {
fmt.Printf("Puzzle Solved");
copyPuzzle.show();
isDone = true;
}
}
}
}
If there is no version available, which I believe there isn't ... does anyone know how I would go about implementing such a thing on my own?
How about Vector.Delete( i ) ?
Right now Go doesn't support generic equality operators. So you'll have to write something that iterates over the vector and removes the correct one.

Resources