satheeshreddy / nginx-location-match-visible

:beers: help you understand how does nginx location match works:)

Home Page:https://detailyang.github.io/nginx-location-match-visible/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

nginx location match visible


Table of Contents

#Purpose

This project aims to help guys understand how does nginx location match work. Wish you can learn something from this project ๐Ÿ˜

nginx location visible #Rough

In Nginx Website, it include these docs as the following:

Syntax:	location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default:	โ€”
Context:	server, location

A location can either be defined by a prefix string, or by a regular expression. Regular expressions are specified with the preceding โ€œ*โ€ modifier (for case-insensitive matching), or the โ€œโ€ modifier (for case-sensitive matching). To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.

location blocks can be nested, with some exceptions mentioned below.

For case-insensitive operating systems such as Mac OS X and Cygwin, matching with prefix strings ignores a case (0.7.7). However, comparison is limited to one-byte locales.

Regular expressions can contain captures (0.7.40) that can later be used in other directives.

If the longest matching prefix location has the โ€œ^~โ€ modifier then regular expressions are not checked.

Also, using the โ€œ=โ€ modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a โ€œ/โ€ request happens frequently, defining โ€œlocation = /โ€ will speed up the processing of these requests, as search terminates right after the first comparison. Such a location cannot obviously contain nested locations.

Let's explain something about this:

  1. the exact match is the best priority
  2. the prefix match is the second priority, but there are two type prefix match like ^~ and /, if you are ^~, nginx will skip regular match else it will continue to match all the regular match.

a little fake code as the following:

def match(uri):
  rv = NULL

  if uri in exact_match:
    return exact_match[uri]
  
  if uri in prefix_match:
    if prefix_match[uri] is '^~':
      return prefix_match[uri]
    else:
      rv = prefix_match[uri]
    
  if uri in regex_match:
    return regex_match[uri]
  
  return rv

Letโ€™s illustrate the above by an example:

location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}
  • if we are requesting "/index.html", it will match configureation B.
  • if we are requesting "/1.jpg", it will find configuration B at first, then regular match configuration E finally.
  • if we are requesting "/images/xxx", it will match configuration D, but never match regular location becasuse of ^~

#Detail Letโ€™s talk about the something about nginx location data struct when nginx match location.

Firstly Nginx will sort the location list by the order

extra_match(alpha order)->prefix(alpha order)->regular(order write by conf)->named(alpha order)->noname(order write by conf)

Then Nginx will move named and noname location from the list, because normal request will not hit these location directly.
And Nginx will split regular location to signle list like the following.
Finally Nginx transform the location list only have match and prefix to a ternary tree like the following.

nginx location tree and regular location list

Contributing

To contribute to ngx_http_updown, clone this repo locally and commit your code on a separate branch.
PS: PR Welcome ๐Ÿš€ ๐Ÿš€ ๐Ÿš€ ๐Ÿš€

This project consist of the three parts:

  • Parse the nginx conf: nginx conf parser are not implement like compiler, it's just string manipulate. And now it cannot support rewrite directive.

  • Construct the nginx static location treeใ€regular location list and Implement the nginx_find_location method: it translate nginx c code to js code by manual

  • Render nginx match process: now render the process is deal with by canvas api, it could be implmented better actually.

The code of this project is a little dirty but workaround. It's enough to help guys to know how to work when nginx match location.

Wish it can help you as more as what I have learn from nginx code.

๐Ÿš€ Thank You !!! ๐Ÿš€

Author

GitHub @detailyang

License

nginx-location-match-visible is licensed under the MIT license.

About

:beers: help you understand how does nginx location match works:)

https://detailyang.github.io/nginx-location-match-visible/

License:MIT License


Languages

Language:JavaScript 92.4%Language:HTML 7.4%Language:Makefile 0.2%