nginx中的听指令实例解析

  


  

  

上一篇文章我们分析了位置指令的解析过程,简单的回顾一下这个内容:每个位置对应一个ngx_http_core_loc_conf_t结构体,所有的位置通过一个双向队列连接在一起。数据结构比较复杂。
  

  


  

  

nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解。与网络有关的配置命令主要有两个:听和sever_name.listen命令设置nginx监听地址,对于IP协议,这个地址就是地址和端口,对于UNIX域套接字协议,这个地址就是路径,一条听指令只能指定一个地址或者港口,地址也可以是主机名

  

从这一篇文章开始,我们分析指听令的解析过程,指听令的配置如下:从nginx.org的手册中我们可以获取听的使用方法:

        听地址[:端口][default_server] [setfib=数量][积压数量=][rcvbuf=大小][sndbuf=大小][accept_filter=过滤](延期)(绑定)[ipv6only=|关闭](ssl) [so_keepalive=|关闭| [keepidle]: [keepintvl]: [keepcnt]],      

一个听指令携带的参数是很复杂的。不过,我们一般很少关注那些不太常用的参数,以下是一些常用的配置方式:

        听127.0.0.1:8000;   听127.0.0.1不加端口,默认监听80端口;   听8000   听*:8000   听localhost: 8000      

解析听指令中的uri和端口
  

  

从上面的内容知道,听着有多种用法,我们在解析的时候需要获取到指听令的端口号和uri部分,nginx提供了ngx_parse_url()方法来解析uri和端口,该函数在解析指听令的时候会被调用。
  

        ngx_int_t   ngx_parse_url (ngx_pool_t *池,ngx_url_t * u)   {   u_char * p;   size_t len;      p=u→url.data;   len=u→url.len;//这里是解析unix域的协议   如果(len祝辞=5,,ngx_strncasecmp (p (u_char *)unix:“5)==0) {   返回ngx_parse_unix_domain_url(池,u);   }//解析IPV6协议   如果(len,,p [0]==() {   返回ngx_parse_inet6_url(池,u);   }//解析IPV4协议   返回ngx_parse_inet_url(池,u);   }      

我们使用的是IPV4协议,这里分析ngx_parse_inet_url()函数

     //u。url=" 80 ";//u。听=1;//u.default_port=80;   静态ngx_int_t   ngx_parse_inet_url (ngx_pool_t *池,ngx_url_t * u)   {   u_char * p, *, *端口,*,* uri, * args;   size_t len;   ngx_int_t n;   结构指向sockaddr_in *罪;   #如果(NGX_HAVE_INET6)   struct sockaddr_in6 * sin6;   # endif      u→socklen=sizeof (struct指向sockaddr_in);   罪=(struct指向sockaddr_in *)和u→sockaddr;   罪恶→sin_family=AF_INET;//IPV4类型      u→家庭=AF_INET;      主机=u→url.data;//?0”      去年=主机+ u→url.len;//主机的最后字符的位置      端口=ngx_strlchr(主机,最后,“:”);//找到港口,这里为NULL      uri=ngx_strlchr(主机、最后'/');//找到uri,这里为NULL      args=ngx_strlchr(主机,最后,“& # 63;”);//找到参数参数,这里为NULL      如果(args) {   如果(uri==NULL | | args & lt;uri) {   uri=参数;   }   }      如果(uri) {   如果(u→听| | ! u→uri_part) {   u→呃=拔扌У闹骰?   返回NGX_ERROR;   }      u→uri。len=去年- uri;   u→uri。数据=https://www.yisu.com/zixun/uri;      去年=uri;      如果(uri <端口){   端口=零;   }   }      如果(端口){   港口+ +;      len=去年-端口;      n=ngx_atoi(港口,len);      如果(n <1 | | n> 65535) {   u ->呃=拔扌Ф丝凇?   返回NGX_ERROR;   }      u→端口=(in_port_t) n;   罪恶→sin_port=htons (n) (in_port_t);      u→port_text。len=兰;   u→port_text。数据=https://www.yisu.com/zixun/port;      去年=港口- 1;      其他}{   如果(uri==NULL) {      如果(u ->听){/*测试值作为端口>   {   ngx_string(“倾听”),   NGX_HTTP_SRV_CONF | NGX_CONF_1MORE,   ngx_http_core_listen,   NGX_HTTP_SRV_CONF_OFFSET,   0,   零   }      

从配置文件中我们可以知道,只听能出现在服务器模块中,可以带有多个参数。
  

  

对应的处理函数为ngx_http_core_listen、下面我们分析这个函数,我们删除了一些进行错误判断的代码,
  

        静态char *   ngx_http_core_listen (ngx_conf_t * cf, ngx_command_t * cmd, void *配置)   {   ngx_http_core_srv_conf_t *产销=相依;      ngx_str_t *值,大小;   ngx_url_t u;   ngx_uint_t n;   ngx_http_listen_opt_t lsopt;      论述→听=1;      值=https://www.yisu.com/zixun/cf->参数->英语教学;      ngx_memzero (u, sizeof (ngx_url_t));      u。url=价值[1];   u。听=1;   u.default_port=80;      如果(ngx_parse_url (cf ->池,u) !=NGX_OK) {   返回NGX_CONF_ERROR;   }      ngx_memzero (&lsopt sizeof (ngx_http_listen_opt_t));      ngx_memcpy (&lsopt.sockaddr。sockaddr, u。sockaddr u.socklen);      lsopt。socklen=u.socklen;   lsopt。积压=NGX_LISTEN_BACKLOG;   lsopt。rcvbuf=1;   lsopt。sndbuf=1;   #如果(NGX_HAVE_SETFIB)   lsopt。setfib=1;   # endif   #如果(NGX_HAVE_TCP_FASTOPEN)   lsopt。fastopen=1;   # endif   lsopt。通配符=u.wildcard;   #如果(NGX_HAVE_INET6)   lsopt。ipv6only=1;   # endif      (空白)ngx_sock_ntop (&lsopt.sockaddr。sockaddr lsopt。socklen lsopt.addr,   NGX_SOCKADDR_STRLEN, 1);      (n=2;n

nginx中的听指令实例解析