当前位置:K88软件开发文章中心网站服务器框架nginx → 文章内容

Nginx 基本数据结构

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-23 14:28:43

fmt, ...);上面这三个函数用于字符串格式化,ngx_snprintf 的第二个参数 max 指明 buf 的空间大小,ngx_slprintf 则通过 last 来指明 buf 空间的大小。推荐使用第二个或第三个函数来格式化字符串,ngx_sprintf 函数还是比较危险的,容易产生缓冲区溢出漏洞。在这一系列函数中,Nginx 在兼容 glibc 中格式化字符串的形式之外,还添加了一些方便格式化 Nginx 类型的一些转义字符,比如%V用于格式化 ngx_str_t 结构。在 Nginx 源文件的 ngx_string.c 中有说明: /* * supported formats: * %[0][width][x][X]O off_t * %[0][width]T time_t * %[0][width][u][x|X]z ssize_t/size_t * %[0][width][u][x|X]d int/u_int * %[0][width][u][x|X]l long * %[0][width|m][u][x|X]i ngx_int_t/ngx_uint_t * %[0][width][u][x|X]D int32_t/uint32_t * %[0][width][u][x|X]L int64_t/uint64_t * %[0][width|m][u][x|X]A ngx_atomic_int_t/ngx_atomic_uint_t * %[0][width][.width]f double, max valid number fits to %18.15f * %P ngx_pid_t * %M ngx_msec_t * %r rlim_t * %p void * * %V ngx_str_t * * %v ngx_variable_value_t * * %s null-terminated string * %*s length and string * %Z '\0' * %N '\n' * %c char * %% % * * reserved: * %t ptrdiff_t * %S null-terminated wchar string * %C wchar */这里特别要提醒的是,我们最常用于格式化 ngx_str_t 结构,其对应的转义符是%V,传给函数的一定要是指针类型,否则程序就会 coredump 掉。这也是我们最容易犯的错。比如: ngx_str_t str = ngx_string("hello world"); u_char buffer[1024]; ngx_snprintf(buffer, 1024, "%V", &str); // 注意,str取地址 void ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src); ngx_int_t ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src);这两个函数用于对 str 进行 base64 编码与解码,调用前,需要保证 dst 中有足够的空间来存放结果,如果不知道具体大小,可先调用 ngx_base64_encoded_length 与 ngx_base64_decoded_length 来预估最大占用空间。 uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type);对 src 进行编码,根据 type 来按不同的方式进行编码,如果 dst 为 NULL,则返回需要转义的字符的数量,由此可得到需要的空间大小。type 的类型可以是: #define NGX_ESCAPE_URI 0 #define NGX_ESCAPE_ARGS 1 #define NGX_ESCAPE_HTML 2 #define NGX_ESCAPE_REFRESH 3 #define NGX_ESCAPE_MEMCACHED 4 #define NGX_ESCAPE_MAIL_AUTH 5 void ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type);对 src 进行反编码,type 可以是 0、NGX_UNESCAPE_URI、NGX_UNESCAPE_REDIRECT 这三个值。如果是 0,则表示 src 中的所有字符都要进行转码。如果是 NGX_UNESCAPE_URI 与 NGX_UNESCAPE_REDIRECT,则遇到'?'后就结束了,后面的字符就不管了。而 NGX_UNESCAPE_URI 与 NGX_UNESCAPE_REDIRECT 之间的区别是 NGX_UNESCAPE_URI 对于遇到的需要转码的字符,都会转码,而 NGX_UNESCAPE_REDIRECT 则只会对非可见字符进行转码。 uintptr_t ngx_escape_html(u_char *dst, u_char *src, size_t size);对 html 标签进行编码。当然,我这里只介绍了一些常用的 api 的使用,大家可以先熟悉一下,在实际使用过程中,遇到不明白的,最快最直接的方法就是去看源码,看 api 的实现或看 Nginx 自身调用 api 的地方是怎么做的,代码就是最好的文档。ngx_pool_tngx_pool_t是一个非常重要的数据结构,在很多重要的场合都有使用,很多重要的数据结构也都在使用它。那么它究竟是一个什么东西呢?简单的说,它提供了一种机制,帮助管理一系列的资源(如内存,文件等),使得对这些资源的使用和释放统一进行,免除了使用过程中考虑到对各种各样资源的什么时候释放,是否遗漏了释放的担心。例如对于内存的管理,如果我们需要使用内存,那么总是从一个 ngx_pool_t 的对象中获取内存,在最终的某个时刻,我们销毁这个 ngx_pool_t 对象,所有这些内存都被释放了。这样我们就不必要对对这些内存进行 malloc 和 free 的操作,不用担心是否某块被malloc出来的内存没有被释放。因为当 ngx_pool_t 对象被销毁的时候,所有从这个对象中分配出来的内存都会被统一释放掉。再比如我们要使用一系列的文件,但是我们打开以后,最终需要都关闭,那么我们就把这些文件统一登记到一个 ngx_pool_t 对象中,当这个 ngx_pool_t 对象被销毁的时候,所有这些文件都将会被关闭。从上面举的两个例子中我们可以看出,使用 ngx_pool_t 这个数据结构的时候,所有的资源的释放都在这个对象被销毁的时刻,统一进行了释放,那么就会带来一个问题,就是这些资源的生存周期(或者说被占用的时间)是跟 ngx_pool_t 的生存周期基本一致(ngx_pool_t 也提供了少量操作可以提前释放资源)。从最高效的角度来说,这并不是最好的。比如,我们需要依次使用 A,B,C 三个资源,且使用完 B 的时候,A 就不会再被使用了,使用C的时候 A 和 B 都不会被使用到。如果不使用 ngx_pool_t 来管理这三个资源,那我们可能从系统里面申请 A,使用 A,然后在释放 A。接着申请 B,使用 B,再释放 B。最后申请 C,使用 C,然后释放 C。但是当我们使用一个 ngx_pool_t 对象来管理这三个资源的时候,A,B 和

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9]  下一页


Nginx 基本数据结构