• Stars
    star
    172
  • Rank 221,201 (Top 5 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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

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.

More Repositories

1

awesome-cheatsheet

🍻 awesome cheatsheet
Python
7,137
star
2

ipc_benchmark

IPC benchmark on Linux
Python
63
star
3

lua-resty-cors

It's the implement of CORS on OpenResty
Lua
54
star
4

lua-resty-socks5-server

This is an implementation of the SOCKS v5 server in the OpenResty
Lua
50
star
5

systemtap-toolkit

my systemtap toolkit to online analyze on production
Perl
44
star
6

pre-commit-shell

🍻 pre commit wrapper shellcheck
Shell
40
star
7

id-generator

🍻 distributed id generation system fork by redis 3.0.2 which support snowflake objectid serialid and sequence number
C
34
star
8

go-fallocate

syscall "fallocate" implement with different os
Go
31
star
9

cas-nginx_http_auth_module

A component for nginx module integrated with CAS
C
27
star
10

wireshark-nsq

🍻 nsq protocol dissector for wireshark
Lua
20
star
11

readelf

One Python File To Parse ELF For Learning ELF
Python
16
star
12

awesome-wireshark-dissector

A curated list of awesome wireshark dissector. Inspired by awesome awesomeness
14
star
13

ngx_http_updown

🍻 ngx_http_updown_module is a an addon for nginx to gracefully up or down
C
11
star
14

cas-server

🍻 center authorization server for enterprise
JavaScript
10
star
15

fasturl-go

fasturl-go is a yet another url parser but zero allocted which is more faster then net/url
Go
9
star
16

lua-resty-rfc5424

This is an implementation of the RFC5424(syslog) in the OpenResty
Lua
8
star
17

git-mix

Mix the git data with AES-256-ECB mode
Rust
8
star
18

pb-inspector-go

inpsects the protobuf binary file to debug with or without schema
Go
8
star
19

bitmex-forward

bitmex multi account order status forward to discord
Python
7
star
20

hikarian

hikarian (departed) tcp + tunnel or tcp over icmp
Go
7
star
21

luaproxy

https or http proxy which use lua script to control http traffic
Go
6
star
22

lua-resty-htmlentities

Backport the html entities to luajit with the ffi binding as the entities to UTF-8 decoder.
C
6
star
23

dotfiles

personal development machine dotfiles
Vim Script
4
star
24

lua-resty-jsdecode

Javascript Escape Notation Decode To UTF-8 Bytes
C
4
star
25

ngx_http_cors_filter

🍻 ngx_http_cors_filter_module is a an addon for nginx to dynamic generate cors(Cross-Origin Resource Sharing)
C
3
star
26

babel-plugin-transform-await-debug

babel plugin to trace await elapsed time
JavaScript
3
star
27

sendpkt-rs

sendpkt send the TCP Packet from cli
Rust
3
star
28

pix

CSS pixel art generator
HTML
3
star
29

zoneproxy

zoneproxy let you easy to access different network zone
Go
3
star
30

domaintree-go

domaintree-go implements the domain trie tree which support *.example.com, abcd.com.* and regex domain match.
Go
3
star
31

ptrace-do-rs

rust bindings for libptrace-do (https://github.com/emptymonkey/ptrace_do)
Rust
2
star
32

size

Size represents a basic unit of measure (KB/MB/GB) like time.Duration
Go
2
star
33

cas-ldap

A component for support ldap protocol integrated with CAS
JavaScript
2
star
34

ngx_http_barcode

🍻 ngx_http_barcode_module is a an addon for nginx to generate barcode
C
2
star
35

promql-rs

PromQL parser via Nom6
Rust
2
star
36

syscall-table-go

Generate Linux Kernel Syscall Table Via Github Action
Go
2
star
37

blog

:(
1
star
38

learn

JavaScript
1
star
39

linefeed-go

Get the linefeed on the native platform (linux/darwin/windows)
Go
1
star
40

vscode-istio

vscode istio snippets (raw snippets from https://github.com/istio/api)
Makefile
1
star
41

closewait

closewait closes closed-wait sockets via procfs and ptrace
Rust
1
star
42

learnopenssl

learn openssl c api
Python
1
star
43

mann-kendall-go

mann kendall test in go
Go
1
star
44

fastgcd-go

fastgcd-go implements the binary gcd in go
Go
1
star
45

traz-go

transform data source to the go struct
Go
1
star
46

pidfile-go

backport pidfile pkg from docker which avoid malformed "sirupsen/logrus" and "Sirupsen/logrus"
Go
1
star
47

sockpairconn-go

sockpairconn-go represents a connection by socketpair syscall which implements the net.Conn interface
Go
1
star
48

simple-github-action

github sample from https://help.github.com/en/actions/building-actions/creating-a-javascript-action
JavaScript
1
star
49

spin-lock-tests

A few spin lock tests in N(1 2 4 6 8) threads
C++
1
star
50

fastmac

fastmac
Shell
1
star
51

sm3-go

sm3-go implements the SM3 hash algorithms as defined in http://www.oscca.gov.cn
Go
1
star
52

go-bcrypto

golang bitcoin crypto library [WIP]
C
1
star