How to create custom function in default.vcl within Varnish? - varnish

I have repetitive code in my vcl and I want to create custom function without embedding inline C code. Is it possible?

You can define a custom subroutine like this
sub my_subroutine {
...
}
and call it like this:
call my_subroutine;
From: http://book.varnish-software.com/4.0/chapters/VCL_Basics.html
Subroutines in VCL take neither arguments nor return values. Each
subroutine terminates by calling return (action), where action is a
keyword that indicates the desired outcome. Subroutines may inspect
and manipulate HTTP header fields and various other aspects of each
request. Subroutines instruct how requests are handled.
Subroutine example:
sub pipe_if_local { if (client.ip ~ local) {
return (pipe); } }
To call a subroutine, use the call keyword followed by the
subroutine’s name:
call pipe_if_local;
Varnish has built-in subroutines that are hook into the Varnish
workflow. These built-in subroutines are all named vcl_*. Your own
subroutines cannot start their name with vcl_.

Related

Differentiating between when a user calls a method and when a computer calls a method

I'm having trouble with figuring out how to know when a user calls a class method and when the method is called within my own code.
class animal:
def lower_stats(self):
if user_called==True:
return("You monster")
else:
self.hunger-=10
def other_code(self):
...
self.lower_stats()
How can I make it to where when a user calls .lower_stats() it returns "You monster", but when .other_code() executes .lower_stats(), 10 will be subtracted from self.hunger?
The methode itself can not know whether it got called by a code or from elsewhere.
It basically gets always called as a codeblock no distinctions made.
The only way to like get similar behaviour is making the methods private by annotating it with two double underscores at the start of the methode name.
And writing a public one that does something when a user calls it.
Geeks For Geeks Private Methodes Python
Tho that won't really stop people from calling the private function cause in python there are no real private methodes.
Another way would be having some kind of logic inside the function to authorize the call to the function.
Tho that can be bypassed...

Is there a way to restrict which functions could be called through google.script.run?

I just deployed my first google apps script web app. However, I'm concerned about all the functions defined in the code.gs. They could be called by anyone with access to the dev console in chrome. They could call google.script.run on any of them.
Some of those functions are there only as a foundation to use in other functions (example below). Is there a way to restrict which functions could be called through google.script.run?
function openRentManagerDatabase (spreaSheetId) {
return SpreadsheetApp.openByIspreadsheetId);
}
Yes, you can do it.
add _after function name, that way it will become a private function and will become inaccessible for google.script.run.
It will look like this:-
function openRentManagerDatabase_(spreaSheetId) {
return SpreadsheetApp.openByIspreadsheetId);
}
Do note that making it private means you can't run it directly from appscript editor by selecting it.
So when you want to run it by calling it through another function, you have to use _ everytime, just like this openRentManagerDatabase_().
Reference:
Private functions

Command not found on a funciton calling from another [duplicate]

In the script below, does the order in which items are declared matter?
For example, if the add_action points to a function that has not yet been defined? Does it matter or should the function declaration always precede any code in which its called?
add_action('load-categories.php', 'my_admin_init');
function my_admin_init(){
//do something
}
That doesn't matter if the function is declared before or after the call but the function should be there in the script and should be loaded in.
This is the first method and it will work:
some_func($a,$b);
function some_func($a,$b)
{
echo 'Called';
}
This is the second method and will also work:
function some_func($a,$b)
{
echo 'Called';
}
some_func($a,$b);
From the PHP manual:
Functions need not be defined before they are referenced, except when a function is conditionally defined as shown in the two examples below.
However, while this is more of a personal preference, I would highly recommend including all the functions you actually use in an external functions.php file then using a require_once() or include_once() (depending on tastes) at the very top of your main PHP file. This makes more logical sense -- if someone else is reading your code, it is blindingly obvious that you are using custom functions and they are located in functions.php. Saves a lot of guesswork IMO.
you can call a function before it's defined, the file is first parsed and then executed.
No.
It is not C :P...
As you can see here , the whole file is first being parsed and then executed.
If a function that doesn't exist is being called, php will throw an error.
Fatal error: Call to undefined function
As per my personal experience, In some special cases (Like, passing array's in function or function inside a function and so on). It's best option to define the function above the call. Because of this sometimes neither function works nor PHP throw an error.
In normal php functions, it doesn't matter. You can use both of the types.
It does not matter, as long as it is declared somewhere on the page.
as seen here:
http://codepad.org/aYbO7TYh
Quoting the User-defined functions section of the manual :
Functions need not be defined before
they are referenced, except when a
function is conditionally defined
So, basically : you can call a function before its definition is written -- but, of course, PHP must be able to see that definition, when try to call it.

Passing Varnish struct variables across VCL reloads

I built a Varnish VMOD that defines an object, which is instantiated in vcl_init and is always kept in memory, and used in individual requests.
My configuration is split up in several VCL files, that get loaded from a "master" VCL depending on some request parameters.
The master VCL also instantiates the object in question, which I want to use in another VCL. The reason why I don't instantiate the object in the same VCL I use it in, is that I have another VCL that defines some ACL-restricted routes to update the object from a data source.
E.g. master.vcl:
sub vcl_init {
new myobj = mymodule.myobject();
}
sub vcl_recv {
if (req.url ~ "^pub/") {
return (vcl (pub_vcl));
}
// Other switches...
}
pub.vcl:
sub vcl_recv {
if myobj.mymethod() {
set req.http.x-bogus = "true";
}
}
But in this case, compilation fails because myobj is undefined in pub.vcl, which means it does not carry from master.vcl.
I also thought about adding the test and header setting in master.vcl before loading pub.vcl, but that won't work because loading a VCL calls std.rollback(req) which unsets all the request headers, which is the only variable accessible in vcl_recv.
Is there a way to pass this state across VCL reloads?
Thanks.
You can't do this with objects directly as they are scoped by the VCL and can't "escape" it. As you've experienced, you need to load the labeled vcl first, so you also need to create the object in it.
But nothing prevents you from creating objects that reference a global variable so all objects have access to the same data.
Alternatively, you can use the Event function to use a PRIV_VCL (https://stackoverflow.com/a/60753085) also referencing a global pointer and avoid using objects completely. This is what is done here for example: https://github.com/varnish/varnish-modules/blob/master/src/vmod_vsthrottle.c#L345

Prestashop | Remove transplant restrictions

So, there's a problem - I need to transplant "Categories Block" module to "displayTopColumn" hook (yep, designer put categories list near (on?) slider). But, by default, there is no possibilities to do this. I don't like that awful Prestashop restrictions, so maybe there is solution for this problem - remove those restrictions?
Thanks.
Removing those restrictions would not resolve anything for a simple reason: if you could hook the module blockcategories to displayTopColumn, this module would not know what to display in this hook because there is no hookDisplayTopColumn() function in it.
However, you can modify the module, and add a function to manage this hook.
To do so, open the file blockcategories.php and add the following:
public function hookDisplayTopColumn($params)
{
// Your code
}
If you want to display here the same content as in the hookLeftColumn hook, you can simply do this:
public function hookDisplayTopColumn($params)
{
return $this->hookLeftColumn($params);
}
You can also create your own function and template by copying, pasting and modifying the code you can find in the function hookLeftColumn() or in the function hookFooter().

Resources