Discussion on Nginx variable (vii)

Source: Internet
Author: User
Tags echo command

In (a) we mentioned that the value of the Nginx variable has only one type, that is, the string, but the variable may not have a meaningful value at all. A variable that has no value also has two special values: one is "illegal" (invalid) and the other is "not found" (not found).

For example, when the Nginx user variable is $foo created and not assigned, $foo the value is "illegal" and if the parameter is not mentioned in the URL parameter string of the current request XXX , then the value of the _xxx built-in variable is "not found".

Whether it's "illegal" or "not found", these two Nginx variables have special values, and the empty string ("") the value is completely different, such as the JavaScript language also has special undefined and null these two special values, and Lua language also has a special c5/> values: They are neither equivalent to an empty string, nor to a number, nor to a 0 Boolean value false . In fact, the SQL language NULL is a similar thing.

Although we see earlier in (a) that the variable created by the set directive is used in "variable interpolation", the effect is equivalent to an empty string, but that is because the set directive automatically registers a "fetch handler" for the variable it creates and converts the "illegal" variable value to an empty string. To verify this, let's look again at the example discussed in (a):

Location/foo {
echo "foo = [$foo]";
}

Location/bar {
Set $foo 32;
echo "foo = [$foo]";
}

For the sake of simplicity, it omits the previously written perimeter server configuration block. In this example, we /bar implicitly create the name of the variable in the interface with the set directive $foo , and then we /foo $foo use the echo command output directly in the interface without initializing it. /fooThe result of our test interface was

$ Curl ' Http://localhost:8080/foo '
foo = []

From the output, the uninitialized $foo variable does exactly the same as an empty string. But the attentive reader should have noticed at the time that, for the above request, the Nginx error log file (the general filename is called) has one error.log more line in it similar to the following warning:

[Warn] 5765#0: * * using uninitialized "foo" variable, ...

Who is the one who output this line of warning? The answer is that the SET command is the $foo "fetch handler" for the registration. When the /foo echo instruction in the interface is actually executed, it "foo = [$foo]" calculates the "variable interpolation" of its parameters. Then, the variable in the argument string is $foo read, and Nginx first checks its value in the container, and as a result it sees the "illegal" value, so it decides to continue calling the $foo "fetch handler" of the variable. The $foo "fetch handler" of the variable starts running, it prints out the warning message to the Nginx error log, and then returns an empty string as $foo the value and is cached in $foo the value container.

Careful readers will notice that the process just described is actually the work of the built-in variables that support the value cache, except that the set directive borrows this mechanism to handle Nginx variables that are not properly initialized. It is worth mentioning that only the "illegal" this special value will trigger the NGINX call variable "fetch handler", and the special value "not found" but not.

The above warning usually indicates that there is a typo in the variable name in our Nginx configuration, or that a variable that has not been initialized has been used in the wrong situation. Because of the presence of a value cache, this warning is not printed more than once during the lifetime of a request. Of course, the Ngx_rewrite module specifically provides a Uninitialized_variable_warn configuration directive that can be used to suppress this warning log.

As mentioned earlier, the built-in variable $arg _xxx XXX returns a special value "not found" when the request URL parameter does not exist, but unfortunately it is not easy to distinguish it from an empty string in the Nginx native configuration language (which we estimate and call it), such as:

location/test {
echo "Name: [$arg _name]";
}

Here we output $arg_name the value of the variable and intentionally does not provide the URL parameter in the request name :

$ Curl ' http://localhost:8080/test '
Name: []

As we can see, the output special value "not found" effect and the empty string is the same. Because this time is Nginx's "variable interpolation" engine automatically "can't find" to ignore.

So how do we capture the "can't find" trace of this particular value? In other words, how should we differentiate it from the empty string? Obviously, in the following request, the URL parameter name is a value, and its value should be an empty string:

$ Curl ' http://localhost:8080/test?name= '
Name: []

But we are unable to distinguish it from name the situation where the parameters are not provided at all.

Fortunately, with third-party module Ngx_lua, we can easily do this in LUA code. Take a look at the following example:

     location /test {
         content_by_lua  '
            if  Ngx.var.arg_name == nil then
                 ngx.say ("name: missing")
             else
                 ngx.say ("name: [", ngx.var.arg_name,  "]")
             end
         ' ;
    }

This example is very close to the previous example, except that we /test use the Content_by_lua configuration directive of the Ngx_lua module in the interface, embedding a small section of our own LUA code to $arg_name judge the special values of Nginx variables. In this example, when $arg_name the value is "not found" (or "illegal"), the /foo interface outputs name: missing this line of results:

Curl ' http://localhost:8080/test '
Name:missing

Because this is the first time we have access to the Ngx_lua module, we need a brief introduction first. The Ngx_lua module embeds the LUA language interpreter (or the Luajit instant compiler) into the Nginx core, allowing the user to run a program written in the Lua language directly in the Nginx core. We can choose to insert our Lua code in the different request processing stages of Nginx. These Lua codes can be either directly inline in an Nginx configuration file or placed separately in an external .lua file, and then refer to .lua the path of the file in the Nginx configuration file.

Back to the example above, we quoted the Nginx variable in the LUA code through ngx.var the LUA interface provided by the Ngx_lua module. For example, when you reference Nginx variables $VARIABLE , you can write Ngx.var.VARIABLE in Lua code. When the Nginx variable $arg_name is a special value "not Found" (or "illegal"), the ngx.var.arg_name value in the LUA world is the nil "null" in the LUA language (unlike the LUA empty string). When we output the response body content in Lua, we use the Ngx.say Lua function, which is also provided by the Ngx_lua module, which is functionally equivalent to the echo configuration instruction of the Ngx_echo module.

Now, if we provide an argument for an empty string value name , the output is not the same as it was just now:

$ Curl ' http://localhost:8080/test?name= '
Name: []

In this case, the $arg_name value of the Nginx variable is an empty string, which is neither "not found" nor "illegal", so in Lua, the Lua ngx.var.arg_name empty string ("") is returned, and the LUA value just now is nil completely distinguishable.

This distinction is very important in some scenarios, such as the existence of a Web service interface that name determines whether a collection of data is name filtered by attributes, rather than providing an empty string as the value of the parameter, and name also causing the value in the data set to be empty string To filter the records.

However, there are some limitations to the standard $arg _xxx variables, such as we use this request to test the /test interface just now:

$ Curl ' http://localhost:8080/test?name '
Name:missing

At this point, the $arg_name variable still reads "Can't find" this special value, which is obviously a violation of common sense. In addition, $arg the _XXX variable has multiple parameters with the same name in the request URL XXX , it only returns the value of the first XXX parameter, silently ignoring the other instance:

$ Curl ' Http://localhost:8080/test?name=Tom&name=Jim&name=Bob '
Name: [Tom]

To address these limitations, you can use the Ngx.req.get_uri_args function provided by the Ngx_lua module directly in Lua code.

(not to be continued)

Discussion on Nginx variable (vii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.