简介:
想要了解nginx,还需要从源码入手,在看代码的同时,抽离出其中具体的数据结构,并单独运行查看效果,字符串比较简单
一、数据结构定义
1. ngx_str_t 字符串结构
/**
* 字符串结构
*/
typedef struct {
size_t len; //字符串长度
u_char *data; //具体的指针地址
} ngx_str_t;
2. ngx_keyval_t 字符串K V结构
下面这种结构主要用在如下配置中
/**
* 字符串的K V结构
*/
typedef struct {
ngx_str_t key;
ngx_str_t value;
} ngx_keyval_t;
一、数据结构图
三、具体函数实现
1. 初始化一个字符串 ngx_string
//初始化一个字符串
#define ngx_string(str) { sizeof(str) - 1, (u_char *) str }
2. 设置字符串
//将一个字符串设置为NULL
#define ngx_null_string { 0, NULL }
//设置一个字符串
#define ngx_str_set(str, text) \
(str)->len = sizeof(text) - 1; (str)->data = (u_char *) text
#define ngx_str_null(str) (str)->len = 0; (str)->data = NULL
四、具体例子
代码目录结构:
/*
* Copyright (C) Igor Sysoev
* Copyright (C) Nginx, Inc.
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#ifndef _NGX_STRING_H_INCLUDED_
#define _NGX_STRING_H_INCLUDED_
typedef struct {
size_t len;
u_char *data;
} ngx_str_t;
typedef struct {
ngx_str_t key;
ngx_str_t value;
} ngx_keyval_t;
typedef struct {
unsigned len:28;
unsigned valid:1;
unsigned no_cacheable:1;
unsigned not_found:1;
unsigned escape:1;
u_char *data;
} ngx_variable_value_t;
#define ngx_string(str) { sizeof(str) - 1, (u_char *) str }
#define ngx_null_string { 0, NULL }
#define ngx_str_set(str, text) \
(str)->len = sizeof(text) - 1; (str)->data = (u_char *) text
#define ngx_str_null(str) (str)->len = 0; (str)->data = NULL
#define ngx_tolower(c) (u_char) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c)
#define ngx_toupper(c) (u_char) ((c >= 'a' && c <= 'z') ? (c & ~0x20) : c)
#define ngx_strstr(s1, s2) strstr((const char *) s1, (const char *) s2)
#define ngx_strlen(s) strlen((const char *) s)
#define ngx_strncmp(s1, s2, n) strncmp((const char *) s1, (const char *) s2, n)
/* msvc and icc7 compile strcmp() to inline loop */
#define ngx_strcmp(s1, s2) strcmp((const char *) s1, (const char *) s2)
size_t ngx_strnlen(u_char *p, size_t n);
size_t ngx_strnlen(u_char *p, size_t n);
void ngx_strlow(u_char *dst, u_char *src, size_t n);
#endif /* _NGX_STRING_H_INCLUDED_ */
#include "nginx_string.h"
void ngx_strlow(u_char *dst, u_char *src, size_t n)
{
while (n) {
*dst = ngx_tolower(*src);
dst++;
src++;
n--;
}
}
// 求所给字符串的长度
size_t ngx_strnlen(u_char *p, size_t n)
{
size_t i;
for (i = 0; i < n; i++) {
if (p[i] == '\0') {
return i;
}
}
return n;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "nginx_string.h"
int main()
{
//1. 初始化
ngx_str_t name = ngx_string("deamon");
printf("name->len:%ld, name->data:%s\n",name.len,name.data);
//2. 初始化为空
ngx_str_t name1 = ngx_null_string;
printf("name1->len:%ld, name1->data:%s\n",name1.len,name1.data);
//3. set函数赋值
ngx_str_set(&name1, "hello alpha");
printf("name1->len:%ld, name1->data:%s\n",name1.len,name1.data);
//4. 设置为空
ngx_str_null(&name1);
printf("name1->len:%ld, name1->data:%s\n",name1.len,name1.data);
//5. 单个字符转换为小写
u_char c_l = 'L'; u_char c_h = 'H'; u_char c1; u_char c2;
printf("c_l:%c,c_h:%c\n",c_l,c_h);
c1 = ngx_tolower(c_l); c2 = ngx_tolower(c_h);
printf("c_l:%c,c_h:%c\n",c1,c2);
//6. 单个字符转换为大写
u_char cc_l = 'l'; u_char cc_h = 'h'; u_char cc1; u_char cc2;
printf("c_l:%c,c_h:%c\n",cc_l,cc_h);
cc1 = ngx_toupper(c_l); cc2 = ngx_toupper(c_h);
printf("c_l:%c,c_h:%c\n",cc1,cc2);
//7. 将大写转换为小写
ngx_str_t name3 = ngx_string("DEAMON");
printf("name3->len:%ld, name3->data:%s\n",name3.len,name3.data);
#define NGX_MAXHOSTNAMELEN 256
char hostname[NGX_MAXHOSTNAMELEN];
if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
printf("gethostname failed\n");
return -1;
}
printf("origin-hostname:%s\n",hostname);
hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';
ngx_str_t str_hostname;
size_t len = ngx_strlen(hostname);
str_hostname.len = len;
str_hostname.data = malloc(str_hostname.len);
ngx_strlow(str_hostname.data, (u_char *) hostname, len);
printf("str_hostname->len:%ld, str_hostname->data:%s\n",str_hostname.len,str_hostname.data);
//8. 字符串比较 比较前n个 比较所有
if( ngx_strncmp(str_hostname.data, "vm-0-17-ubuntu",3) == 0 ){
printf("compare result str_hostname.data:%s, vm-0-17-ubuntu,3 \n",str_hostname.data);
}
if(ngx_strcmp(str_hostname.data, "vm-0-17-ubuntu") == 0){
printf("compare result str_hostname.data:%s,vm-0-17-ubuntu \n",str_hostname.data);
}
//9.nginx中的字符数组 -- 中的k-v结构
static ngx_keyval_t ngx_http_scgi_cache_headers[] = {
{ ngx_string("HTTP_IF_MODIFIED_SINCE"),ngx_string("$upstream_cache_last_modified") },
{ ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") },
{ ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("$upstream_cache_etag") },
{ ngx_string("HTTP_IF_MATCH"), ngx_string("") },
{ ngx_string("HTTP_RANGE"), ngx_string("") },
{ ngx_string("HTTP_IF_RANGE"), ngx_string("") },
{ ngx_null_string, ngx_null_string }
};
for(size_t index = 0; index < sizeof(ngx_http_scgi_cache_headers)/sizeof(ngx_keyval_t); index ++){
printf("index:%2ld | key->len:%2ld| key is %24s | value->len:%2ld | value is %24s\n",
index,(ngx_http_scgi_cache_headers[index].key.len),
(ngx_http_scgi_cache_headers[index].key.data),
(ngx_http_scgi_cache_headers[index].value.len),
(ngx_http_scgi_cache_headers[index].value.data));
}
free(str_hostname.data);
return 0;
}
执行效果;
参考文章:
1.https://initphp.blog.csdn.net/article/details/50682163