LTP GCOV extension - code coverage report
Current view: directory - and-httpd/src - match_req.c
Test: And-httpd coverage
Date: 2006-09-11 Instrumented lines: 375
Code covered: 90.9 % Executed lines: 341

       1                 : 
       2                 : #include "httpd.h"
       3                 : #include "httpd_policy.h"
       4                 : 
       5                 : #define EX_UTILS_NO_FUNCS 1
       6                 : #include "ex_utils.h"
       7                 : 
       8                 : #include "mk.h"
       9                 : 
      10                 : #include "match_req.h"
      11                 : 
      12                 : static int httpd__match_request_tst_op_d1(Conf_parse *conf, Conf_token *token,
      13                 :                                           int *matches, int prev_match,
      14                 :                                           void *passed_data)
      15           52024 : {
      16           52024 :   struct Httpd__policy_req_tst_data *data = passed_data;
      17                 : 
      18           52024 :   return (httpd_match_request_tst_d1(data->con, data->req, conf, token,
      19                 :                                      matches, prev_match,
      20                 :                                      httpd__match_request_tst_op_d1, data));
      21                 : }
      22                 : 
      23                 : int httpd_match_request_sc_tst_d1(struct Con *con, Httpd_req_data *req,
      24                 :                                   Conf_parse *conf, Conf_token *token,
      25                 :                                   int *matches, int prev_match)
      26          563952 : {
      27                 :   struct Httpd__policy_req_tst_data data[1];        
      28                 :   
      29          563952 :   data->con = con;
      30          563952 :   data->req = req;
      31                 :   
      32          563952 :   return (httpd_match_request_tst_d1(con, req, conf, token,
      33                 :                                      matches, prev_match,
      34                 :                                      httpd__match_request_tst_op_d1, data));
      35                 : }
      36                 : 
      37                 : /* match tokens against a passed in header */
      38                 : static int httpd_match__req_hdr(Httpd_req_data *req,
      39                 :                                 Conf_parse *conf, Conf_token *token,
      40                 :                                 const Vstr_base *s1, size_t pos, size_t len,
      41                 :                                 int flags)
      42           19608 : {
      43           19608 :   if (!conf_token_list_num(token, token->depth_num))
      44            1568 :     return (!!pos); /* does the header exist */
      45                 : 
      46           18040 :   CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);
      47                 : 
      48                 :   /* FIXME: add [] tests for search etc.? */
      49                 :   
      50           18040 :   switch (flags)
      51                 :   {
      52                 :     case HTTPD_MATCH__TYPE_REQ_HDR_IM:
      53                 :     case HTTPD_MATCH__TYPE_REQ_HDR_INM: /* disallow weak etag's? */
      54                 :     {
      55             192 :       const Vstr_sect_node *val = conf_token_value(token);
      56                 :   
      57             192 :       return (val && httpd_match_etags(req, conf->data, val->pos, val->len,
      58                 :                                        s1, pos, len, TRUE));
      59                 :     }
      60                 :     case HTTPD_MATCH__TYPE_REQ_HDR_EQ:
      61             352 :       return (conf_token_cmp_val_eq(conf, token, s1, pos, len));
      62                 :     case HTTPD_MATCH__TYPE_REQ_HDR_CASE_EQ:
      63           14520 :       return (conf_token_cmp_case_val_eq(conf, token, s1, pos, len));
      64                 :     case HTTPD_MATCH__TYPE_REQ_HDR_AE:
      65            2976 :       http_parse_accept_encoding(req, TRUE);
      66                 : 
      67                 :       if (0) { }
      68            2976 :       else if (conf_token_cmp_val_cstr_eq(conf, token, "identity"))
      69               0 :         return (!!req->content_enc_identity);
      70            2976 :       else if (conf_token_cmp_val_cstr_eq(conf, token, "gzip"))
      71            1504 :         return (!!req->content_enc_gzip);
      72            1472 :       else if (conf_token_cmp_val_cstr_eq(conf, token, "bzip2"))
      73            1472 :         return (!!req->content_enc_bzip2);
      74                 : 
      75               0 :       return (FALSE);
      76                 :   }
      77                 : 
      78               0 :   ASSERT_NOT_REACHED();
      79                 :   
      80               0 :   return (FALSE);
      81                 : }
      82                 : 
      83                 : int httpd_match_request_tst_d1(struct Con *con, Httpd_req_data *req,
      84                 :                                Conf_parse *conf, Conf_token *token,
      85                 :                                int *matches, int prev_match,
      86                 :                                int (*tst_func)(Conf_parse *, Conf_token *,
      87                 :                                                int *, int, void *),
      88                 :                                void *data)
      89          703736 : {
      90          703736 :   Vstr_base *http_data = con->evnt->io_r;
      91          703736 :   Vstr_base *http_multi_data = req->http_hdrs->multi->comb;
      92          703736 :   int clist = FALSE;
      93                 :   
      94          351868 :   ASSERT(con && req);  
      95          351868 :   ASSERT(matches);
      96                 :   
      97          703736 :   CONF_SC_TOGGLE_CLIST_VAR(clist);
      98                 : 
      99          703736 :   if (token->type >= CONF_TOKEN_TYPE_USER_BEG)
     100                 :   {
     101          169484 :     unsigned int type = token->type - CONF_TOKEN_TYPE_USER_BEG;
     102          169484 :     unsigned int nxt = 0;
     103          169484 :     Vstr_ref *ref = conf_token_get_user_value(conf, token, &nxt);
     104                 :     
     105          169484 :     switch (type)
     106                 :     {
     107                 :       case HTTPD_POLICY_REQ_PATH_BEG:
     108                 :       case HTTPD_POLICY_REQ_PATH_END:
     109                 :       case HTTPD_POLICY_REQ_PATH_EQ:
     110                 :         
     111                 :       case HTTPD_POLICY_REQ_NAME_BEG:
     112                 :       case HTTPD_POLICY_REQ_NAME_END:
     113                 :       case HTTPD_POLICY_REQ_NAME_EQ:
     114                 :         
     115                 :       case HTTPD_POLICY_REQ_BWEN_BEG:
     116                 :       case HTTPD_POLICY_REQ_BWEN_END:
     117                 :       case HTTPD_POLICY_REQ_BWEN_EQ:
     118                 :         
     119                 :       case HTTPD_POLICY_REQ_BWES_BEG:
     120                 :       case HTTPD_POLICY_REQ_BWES_END:
     121                 :       case HTTPD_POLICY_REQ_BWES_EQ:
     122                 :         
     123                 :       case HTTPD_POLICY_REQ_EXTN_BEG:
     124                 :       case HTTPD_POLICY_REQ_EXTN_END:
     125                 :       case HTTPD_POLICY_REQ_EXTN_EQ:
     126                 :         
     127                 :       case HTTPD_POLICY_REQ_EXTS_BEG:
     128                 :       case HTTPD_POLICY_REQ_EXTS_END:
     129                 :       case HTTPD_POLICY_REQ_EXTS_EQ:
     130                 :       {
     131          167828 :         size_t pos = 1;
     132          167828 :         size_t len = req->fname->len;
     133          167828 :         unsigned int lim = httpd_policy_path_req2lim(type);
     134                 : 
     135          167828 :         vstr_ref_add(ref);
     136          167828 :         *matches = httpd_policy_path_lim_eq(req->fname, &pos, &len, lim,
     137                 :                                             req->vhost_prefix_len, ref);
     138                 :       }
     139          167828 :       break;
     140                 :       
     141                 :       case HTTPD_POLICY_CLIENT_IPV4_CIDR_EQ:
     142                 :       {
     143             828 :         struct sockaddr *sa = CON_CEVNT_SA(con);
     144             828 :         *matches = httpd_policy_ipv4_cidr_eq(con, req, ref->ptr, sa);
     145                 :       }
     146             828 :       break;
     147                 :         
     148                 :       case HTTPD_POLICY_SERVER_IPV4_CIDR_EQ:
     149                 :       {
     150             828 :         struct sockaddr *sa = CON_SEVNT_SA(con);
     151             828 :         *matches = httpd_policy_ipv4_cidr_eq(con, req, ref->ptr, sa);
     152                 :       }
     153             828 :       break;
     154                 :         
     155                 :       default:
     156               0 :         vstr_ref_del(ref);
     157               0 :         return (FALSE);
     158                 :     }
     159                 : 
     160          169484 :     vstr_ref_del(ref);
     161          169484 :     if (nxt)
     162          169484 :       return (conf_parse_num_token(conf, token, nxt));
     163                 :   }
     164                 : 
     165          534252 :   else if (OPT_SERV_SYM_EQ("connection-policy-eq") ||
     166                 :            OPT_SERV_SYM_EQ("connection-policy=="))
     167               0 :     OPT_SERV_X_EQ(con->policy->s->policy_name);
     168          646104 :   else if (OPT_SERV_SYM_EQ("policy-eq") || OPT_SERV_SYM_EQ("policy=="))
     169          223704 :     OPT_SERV_X_EQ(req->policy->s->policy_name);
     170          310548 :   else if (OPT_SERV_SYM_EQ("connection-tag-eq") ||
     171                 :            OPT_SERV_SYM_EQ("connection-tag=="))
     172               0 :     OPT_SERV_X_EQ(con->tag);
     173          435408 :   else if (OPT_SERV_SYM_EQ("tag-eq") || OPT_SERV_SYM_EQ("tag=="))
     174          249720 :     OPT_SERV_X_EQ(req->tag);
     175           60828 :   else if (OPT_SERV_SYM_EQ("client-ipv4-cidr-eq") ||
     176                 :            OPT_SERV_SYM_EQ("client-ipv4-cidr==")) /* NOTE: need ipv6 */
     177               4 :     return (httpd_policy_ipv4_make(con, req, conf, token,
     178                 :                                    HTTPD_POLICY_CLIENT_IPV4_CIDR_EQ,
     179                 :                                    CON_CEVNT_SA(con), matches));
     180           60824 :   else if (OPT_SERV_SYM_EQ("server-ipv4-cidr-eq") ||
     181                 :            OPT_SERV_SYM_EQ("server-ipv4-cidr==")) /* NOTE: need ipv6 */
     182             260 :     return (httpd_policy_ipv4_make(con, req, conf, token,
     183                 :                                    HTTPD_POLICY_SERVER_IPV4_CIDR_EQ,
     184                 :                                    CON_SEVNT_SA(con), matches));
     185           60980 :   else if (OPT_SERV_SYM_EQ("server-ipv4-port-eq") ||
     186                 :            OPT_SERV_SYM_EQ("server-ipv4-port=="))
     187                 :   {
     188             832 :     struct sockaddr *sa   = CON_SEVNT_SA(con);
     189             832 :     unsigned int tst_port = 0;
     190                 : 
     191             832 :     OPT_SERV_X_SINGLE_UINT(tst_port);
     192                 : 
     193             832 :     if (sa->sa_family != AF_INET)
     194               0 :       *matches = FALSE;
     195                 :     else
     196                 :     {
     197             832 :       struct sockaddr_in *sin = CON_SEVNT_SA_IN4(con);
     198             832 :       *matches = tst_port == ntohs(sin->sin_port);
     199                 :     }
     200                 :   }
     201           60148 :   else if (OPT_SERV_SYM_EQ("server-ipv6-port-eq") ||
     202                 :            OPT_SERV_SYM_EQ("server-ipv6-port=="))
     203                 :   {
     204             832 :     struct sockaddr *sa   = CON_SEVNT_SA(con);
     205             832 :     unsigned int tst_port = 0;
     206                 : 
     207             832 :     OPT_SERV_X_SINGLE_UINT(tst_port);
     208                 : 
     209             832 :     if (sa->sa_family != AF_INET6)
     210             832 :       *matches = FALSE;
     211                 :     else
     212                 :     {
     213               0 :       struct sockaddr_in6 *sin6 = CON_SEVNT_SA_IN6(con);
     214               0 :       *matches = tst_port == ntohs(sin6->sin6_port);
     215                 :     }
     216                 :   }
     217           60788 :   else if (OPT_SERV_SYM_EQ("protect-vary") || OPT_SERV_SYM_EQ("save-vary"))
     218                 :   {
     219            1888 :     unsigned int depth = token->depth_num;
     220            1888 :     int con_vary_star = con->vary_star;
     221            1888 :     int req_vary_star = req->vary_star;
     222            1888 :     int req_vary_a    = req->vary_a;
     223            1888 :     int req_vary_ac   = req->vary_ac;
     224            1888 :     int req_vary_ae   = req->vary_ae;
     225            1888 :     int req_vary_al   = req->vary_al;
     226            1888 :     int req_vary_rf   = req->vary_rf;
     227            1888 :     int req_vary_ua   = req->vary_ua;
     228            1888 :     int req_vary_ims  = req->vary_ims;
     229            1888 :     int req_vary_ius  = req->vary_ius;
     230            1888 :     int req_vary_ir   = req->vary_ir;
     231            1888 :     int req_vary_im   = req->vary_im;
     232            1888 :     int req_vary_inm  = req->vary_inm;
     233            1888 :     int req_vary_xm   = req->vary_xm;
     234                 : 
     235             944 :     ASSERT(*matches);
     236            4720 :     while (*matches && conf_token_list_num(token, depth))
     237                 :     {
     238            1888 :       CONF_SC_PARSE_DEPTH_TOKEN_RET(conf, token, depth, FALSE);
     239                 : 
     240            1888 :       if (!httpd_match_request_tst_d1(con, req, conf, token,
     241                 :                                       matches, prev_match, tst_func, data))
     242               0 :         return (FALSE);
     243                 :     }
     244                 :     
     245            1888 :     con->vary_star = con_vary_star;
     246            1888 :     req->vary_star = req_vary_star;
     247            1888 :     req->vary_a    = req_vary_a;
     248            1888 :     req->vary_ac   = req_vary_ac;
     249            1888 :     req->vary_ae   = req_vary_ae;
     250            1888 :     req->vary_al   = req_vary_al;
     251            1888 :     req->vary_rf   = req_vary_rf;
     252            1888 :     req->vary_ua   = req_vary_ua;
     253            1888 :     req->vary_ims  = req_vary_ims;
     254            1888 :     req->vary_ius  = req_vary_ius;
     255            1888 :     req->vary_ir   = req_vary_ir;
     256            1888 :     req->vary_im   = req_vary_im;
     257            1888 :     req->vary_inm  = req_vary_inm;
     258            1888 :     req->vary_xm   = req_vary_xm;
     259                 :   }
     260           57012 :   else if (OPT_SERV_SYM_EQ("Accept-Encoding:"))
     261                 :   { /* in theory could call http_parse_accept_encoding() and make sure
     262                 :      * they are allowing gzip ... but non-zero len is probably fine for now */
     263            4480 :     Vstr_sect_node *h_ae = req->http_hdrs->multi->hdr_accept_encoding;
     264                 : 
     265            4480 :     req->vary_ae = TRUE;
     266            4480 :     *matches = httpd_match__req_hdr(req, conf, token,
     267                 :                                     http_multi_data, h_ae->pos, h_ae->len,
     268                 :                                     HTTPD_MATCH__TYPE_REQ_HDR_AE);
     269                 :   }
     270           52532 :   else if (OPT_SERV_SYM_EQ("If-Modified-Since:"))
     271                 :   {
     272              96 :     Vstr_sect_node *h_ims = req->http_hdrs->hdr_if_modified_since;
     273                 : 
     274              96 :     req->vary_ims = TRUE;
     275              96 :     *matches = httpd_match__req_hdr(req, conf, token,
     276                 :                                     http_data, h_ims->pos, h_ims->len,
     277                 :                                     HTTPD_MATCH__TYPE_REQ_HDR_EQ);
     278                 :   }
     279           52436 :   else if (OPT_SERV_SYM_EQ("If-Unmodified-Since:"))
     280                 :   {
     281              96 :     Vstr_sect_node *h_ius = req->http_hdrs->hdr_if_unmodified_since;
     282                 : 
     283              96 :     req->vary_ius = TRUE;
     284              96 :     *matches = httpd_match__req_hdr(req, conf, token,
     285                 :                                     http_data, h_ius->pos, h_ius->len,
     286                 :                                     HTTPD_MATCH__TYPE_REQ_HDR_EQ);
     287                 :   }
     288           52340 :   else if (OPT_SERV_SYM_EQ("If-Range:"))
     289                 :   {
     290              96 :     Vstr_sect_node *h_ir = req->http_hdrs->hdr_if_range;
     291                 : 
     292              96 :     req->vary_ir = TRUE;
     293              96 :     *matches = httpd_match__req_hdr(req, conf, token,
     294                 :                                     http_data, h_ir->pos, h_ir->len,
     295                 :                                     HTTPD_MATCH__TYPE_REQ_HDR_EQ);
     296                 :   }
     297           52244 :   else if (OPT_SERV_SYM_EQ("If-Match:"))
     298                 :   {
     299              96 :     Vstr_sect_node *h_im = req->http_hdrs->multi->hdr_if_match;
     300                 : 
     301              96 :     req->vary_im = TRUE;
     302              96 :     *matches = httpd_match__req_hdr(req, conf, token,
     303                 :                                     http_multi_data, h_im->pos, h_im->len,
     304                 :                                     HTTPD_MATCH__TYPE_REQ_HDR_IM);
     305                 :   }
     306           52148 :   else if (OPT_SERV_SYM_EQ("If-None-Match:"))
     307                 :   {
     308              96 :     Vstr_sect_node *h_inm = req->http_hdrs->multi->hdr_if_none_match;
     309                 : 
     310              96 :     req->vary_inm = TRUE;
     311              96 :     *matches = httpd_match__req_hdr(req, conf, token,
     312                 :                                     http_multi_data, h_inm->pos, h_inm->len,
     313                 :                                     HTTPD_MATCH__TYPE_REQ_HDR_INM);
     314                 :   }
     315           52052 :   else if (OPT_SERV_SYM_EQ("X-Moz:"))
     316                 :   { /* in theory could call http_parse_accept_encoding() and make sure
     317                 :      * they are allowing gzip ... but non-zero len is probably fine for now */
     318              64 :     Vstr_sect_node *h_xm = req->http_hdrs->hdr_x_moz;
     319                 : 
     320              64 :     req->vary_xm = TRUE;
     321              64 :     *matches = httpd_match__req_hdr(req, conf, token,
     322                 :                                     http_data, h_xm->pos, h_xm->len,
     323                 :                                     HTTPD_MATCH__TYPE_REQ_HDR_EQ);
     324                 :   }
     325           59216 :   else if (OPT_SERV_SYM_EQ("Host:") ||
     326                 :            /* compat */
     327                 :            OPT_SERV_SYM_EQ("hostname-eq") || OPT_SERV_SYM_EQ("hostname=="))
     328                 :   { /* doesn't do escaping because DNS is ASCII */
     329           14456 :     Vstr_sect_node *h_h = req->http_hdrs->hdr_host;
     330           14456 :     Vstr_base *d_h      = req->policy->default_hostname;
     331                 : 
     332           14456 :     if (h_h->len)
     333            9800 :       *matches = httpd_match__req_hdr(req, conf, token,
     334                 :                                       http_data, h_h->pos, h_h->len,
     335                 :                                       HTTPD_MATCH__TYPE_REQ_HDR_CASE_EQ);
     336                 :     else
     337            4656 :       *matches = httpd_match__req_hdr(req, conf, token,
     338                 :                                       d_h, 1, d_h->len,
     339                 :                                       HTTPD_MATCH__TYPE_REQ_HDR_CASE_EQ);
     340                 :   }
     341           38732 :   else if (OPT_SERV_SYM_EQ("port-eq") || OPT_SERV_SYM_EQ("port=="))
     342                 :   {
     343            2400 :     Vstr_sect_node *h_h = req->http_hdrs->hdr_host;
     344            2400 :     unsigned int tmp = 0;
     345                 :     
     346            2400 :     OPT_SERV_X_SINGLE_UINT(tmp);
     347                 : 
     348            2400 :     if (h_h->len)
     349               0 :       *matches = tmp == req->http_host_port;
     350                 :     else
     351                 :     { /* FIXME: ipv6 */
     352            2400 :       struct sockaddr_in *sinv4 = EVNT_ACPT_SA_IN4(con->evnt);
     353                 :       
     354            1200 :       ASSERT(sinv4->sin_family == AF_INET);
     355            2400 :       *matches = tmp == ntohs(sinv4->sin_port);
     356                 :     }
     357                 :   }
     358           35196 :   else if (OPT_SERV_SYM_EQ("User-Agent:") ||
     359                 :            /* compat */
     360                 :            OPT_SERV_SYM_EQ("user-agent-eq") || OPT_SERV_SYM_EQ("UA-eq") ||
     361                 :            OPT_SERV_SYM_EQ("user-agent==") || OPT_SERV_SYM_EQ("UA=="))
     362                 :   { /* doesn't do escaping because URLs are ASCII */
     363              64 :     Vstr_sect_node *h_ua = req->http_hdrs->hdr_ua;
     364                 : 
     365              64 :     req->vary_ua = TRUE;
     366              64 :     *matches = httpd_match__req_hdr(req, conf, token,
     367                 :                                     http_data, h_ua->pos, h_ua->len,
     368                 :                                     HTTPD_MATCH__TYPE_REQ_HDR_EQ);
     369                 :   }
     370           35196 :   else if (OPT_SERV_SYM_EQ("user-agent-search-eq") || /* required compat */
     371                 :            OPT_SERV_SYM_EQ("user-agent-search==") ||
     372                 :            OPT_SERV_SYM_EQ("user-agent-srch-eq") ||
     373                 :            OPT_SERV_SYM_EQ("user-agent-srch==") ||
     374                 :            OPT_SERV_SYM_EQ("UA-srch-eq") ||
     375                 :            OPT_SERV_SYM_EQ("UA-srch=="))
     376                 :   { /* doesn't do escaping because URLs are ASCII */
     377             128 :     Vstr_sect_node *h_ua = req->http_hdrs->hdr_ua;
     378                 : 
     379             128 :     req->vary_ua = TRUE;
     380             128 :     CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);
     381             128 :     *matches = !!conf_token_srch_val(conf, token, http_data,
     382                 :                                      h_ua->pos, h_ua->len);
     383                 :   }
     384           35004 :   else if (OPT_SERV_SYM_EQ("Referer:")    || OPT_SERV_SYM_EQ("Referrer:") ||
     385                 :            /* compat */
     386                 :            OPT_SERV_SYM_EQ("referrer-eq") || OPT_SERV_SYM_EQ("referer-eq") ||
     387                 :            OPT_SERV_SYM_EQ("referrer==")  || OPT_SERV_SYM_EQ("referer=="))
     388                 :   { /* doesn't do escaping because URLs are ASCII */
     389              64 :     Vstr_sect_node *h_ref = req->http_hdrs->hdr_referer;
     390                 : 
     391              64 :     req->vary_rf = TRUE;
     392              64 :     *matches = httpd_match__req_hdr(req, conf, token,
     393                 :                                     http_data, h_ref->pos, h_ref->len,
     394                 :                                     HTTPD_MATCH__TYPE_REQ_HDR_CASE_EQ);
     395                 :   }
     396           35068 :   else if (OPT_SERV_SYM_EQ("referrer-beg") || OPT_SERV_SYM_EQ("referer-beg"))
     397                 :     /* required compat */
     398                 :   { /* doesn't do escaping because URLs are ASCII */
     399             192 :     Vstr_sect_node *h_ref = req->http_hdrs->hdr_referer;
     400                 : 
     401             192 :     req->vary_rf = TRUE;
     402             192 :     CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);
     403             192 :     *matches = conf_token_cmp_case_val_beg_eq(conf, token, http_data,
     404                 :                                               h_ref->pos, h_ref->len);
     405                 :   }
     406           34940 :   else if (OPT_SERV_SYM_EQ("referrer-search-eq") || /* required compat */
     407                 :            OPT_SERV_SYM_EQ("referrer-search==") ||
     408                 :            OPT_SERV_SYM_EQ("referrer-srch-eq") ||
     409                 :            OPT_SERV_SYM_EQ("referrer-srch==") ||
     410                 :            OPT_SERV_SYM_EQ("referer-search-eq") ||
     411                 :            OPT_SERV_SYM_EQ("referer-search==") ||
     412                 :            OPT_SERV_SYM_EQ("referer-srch-eq") ||
     413                 :            OPT_SERV_SYM_EQ("referer-srch=="))
     414                 :   { /* doesn't do escaping because URLs are ASCII */
     415             256 :     Vstr_sect_node *h_ref = req->http_hdrs->hdr_referer;
     416                 : 
     417             256 :     req->vary_rf = TRUE;
     418             256 :     CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);
     419             256 :     *matches = !!conf_token_srch_case_val(conf, token,
     420                 :                                           http_data, h_ref->pos, h_ref->len);
     421                 :   }
     422           34428 :   else if (OPT_SERV_SYM_EQ("http-0.9-eq") || OPT_SERV_SYM_EQ("http-0.9==") ||
     423                 :            OPT_SERV_SYM_EQ("http-vers-eq-0.9") ||
     424                 :            OPT_SERV_SYM_EQ("http-vers==0.9") ||
     425                 :            OPT_SERV_SYM_EQ("http-version-eq-0.9") ||
     426                 :            OPT_SERV_SYM_EQ("http-version==0.9"))
     427               0 :     *matches =  req->ver_0_9;
     428           34428 :   else if (OPT_SERV_SYM_EQ("http-1.0-eq") || OPT_SERV_SYM_EQ("http-1.0==") ||
     429                 :            OPT_SERV_SYM_EQ("http-vers-eq-1.0") ||
     430                 :            OPT_SERV_SYM_EQ("http-vers==1.0") ||
     431                 :            OPT_SERV_SYM_EQ("http-version-eq-1.0") ||
     432                 :            OPT_SERV_SYM_EQ("http-version==1.0"))
     433               0 :     *matches = !req->ver_0_9 && !req->ver_1_1;
     434           34428 :   else if (OPT_SERV_SYM_EQ("http-1.1-eq") || OPT_SERV_SYM_EQ("http-1.1==") ||
     435                 :            OPT_SERV_SYM_EQ("http-vers-eq-1.1") ||
     436                 :            OPT_SERV_SYM_EQ("http-vers==1.1") ||
     437                 :            OPT_SERV_SYM_EQ("http-version-eq-1.1") ||
     438                 :            OPT_SERV_SYM_EQ("http-version==1.1"))
     439                 :   {
     440               0 :     *matches = req->ver_1_1;
     441               0 :     ASSERT(!req->ver_0_9 || !*matches);
     442                 :   }
     443           34428 :   else if (OPT_SERV_SYM_EQ("http-vers>=1.0") ||
     444                 :            OPT_SERV_SYM_EQ("http-version>=1.0"))
     445               0 :     *matches = !req->ver_0_9;
     446           34428 :   else if (OPT_SERV_SYM_EQ("http-vers>1.0") ||
     447                 :            OPT_SERV_SYM_EQ("http-version>1.0") ||
     448                 :            OPT_SERV_SYM_EQ("http-vers>=1.1") ||
     449                 :            OPT_SERV_SYM_EQ("http-version>=1.1"))
     450                 :   {
     451               0 :     *matches = HTTPD_VER_GE_1_1(req);
     452               0 :     ASSERT(!req->ver_0_9 || !*matches);
     453                 :   }
     454           34428 :   else if (OPT_SERV_SYM_EQ("http-vers>1.1") ||
     455                 :            OPT_SERV_SYM_EQ("http-vers>=1.2"))
     456                 :   {
     457               0 :     *matches = req->ver_1_x;
     458               0 :     ASSERT(!req->ver_0_9 || !*matches);
     459                 :   }
     460           34556 :   else if (OPT_SERV_SYM_EQ("method-eq") || OPT_SERV_SYM_EQ("method=="))
     461                 :   { /* doesn't do escaping because methods are ASCII */
     462             128 :     Vstr_sect_node *meth = VSTR_SECTS_NUM(req->sects, 1);
     463                 :     
     464             128 :     CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);
     465             128 :     *matches = conf_token_cmp_val_eq(conf, token,
     466                 :                                      http_data, meth->pos, meth->len);
     467                 :   }
     468           34332 :   else if (OPT_SERV_SYM_EQ("tm-dow-eq") || OPT_SERV_SYM_EQ("tm-dow=="))
     469                 :   { /* so we can do msff :) */
     470              32 :     Opt_serv_opts *opts = req->policy->s->beg;
     471              32 :     Httpd_opts *hopts = (Httpd_opts *)opts;
     472              32 :     const struct tm *tm = date_gmtime(hopts->date, req->now);
     473              32 :     int tmp = 0;
     474                 : 
     475              32 :     if (!tm) return (FALSE);
     476                 : 
     477              32 :     req->vary_star = TRUE;
     478              32 :     OPT_SERV_X_SINGLE_UINT(tmp);
     479              32 :     *matches = tmp == tm->tm_wday;
     480                 :   }
     481           34284 :   else if (OPT_SERV_SYM_EQ("content-lang-eq") ||
     482                 :            OPT_SERV_SYM_EQ("content-language-eq") ||
     483                 :            OPT_SERV_SYM_EQ("content-lang==") ||
     484                 :            OPT_SERV_SYM_EQ("content-language=="))
     485                 :   {
     486              32 :     req->vary_al = TRUE;
     487              32 :     CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);
     488              32 :     if (!req->content_language_vs1)
     489              32 :       *matches = conf_token_cmp_val_eq(conf, token, conf->tmp, 1, 0);
     490                 :     else
     491               0 :       *matches = conf_token_cmp_val_eq(conf, token,
     492                 :                                        HTTP__XTRA_HDR_PARAMS(req,
     493                 :                                                              content_language));
     494                 :   }
     495           34252 :   else if (OPT_SERV_SYM_EQ("content-lang-ext-eq") ||
     496                 :            OPT_SERV_SYM_EQ("content-language-extension-eq") ||
     497                 :            OPT_SERV_SYM_EQ("content-lang-ext==") ||
     498                 :            OPT_SERV_SYM_EQ("content-language-extension=="))
     499                 :   {
     500              32 :     req->vary_al = TRUE;
     501              32 :     CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);
     502              32 :     if (!req->ext_vary_al_vs1)
     503              32 :       *matches = conf_token_cmp_val_eq(conf, token, conf->tmp, 1, 0);
     504                 :     else
     505               0 :       *matches = conf_token_cmp_val_eq(conf, token,
     506                 :                                        HTTP__XTRA_HDR_PARAMS(req, ext_vary_al));
     507                 :   }
     508           34220 :   else if (OPT_SERV_SYM_EQ("content-type-eq") ||
     509                 :            OPT_SERV_SYM_EQ("content-type=="))
     510                 :   {
     511              32 :     req->vary_a = TRUE;
     512              32 :     CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);
     513              32 :     if (!req->content_type_vs1)
     514              32 :       *matches = conf_token_cmp_val_eq(conf, token, conf->tmp, 1, 0);
     515                 :     else
     516               0 :       *matches = conf_token_cmp_val_eq(conf, token,
     517                 :                                        HTTP__XTRA_HDR_PARAMS(req,
     518                 :                                                              content_type));
     519                 :   }
     520           34188 :   else if (OPT_SERV_SYM_EQ("content-type-ext-eq") ||
     521                 :            OPT_SERV_SYM_EQ("content-type-extension-eq") ||
     522                 :            OPT_SERV_SYM_EQ("content-type-ext==") ||
     523                 :            OPT_SERV_SYM_EQ("content-type-extension=="))
     524                 :   {    
     525              32 :     req->vary_a = TRUE;
     526              32 :     CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);
     527              32 :     if (!req->ext_vary_a_vs1)
     528              32 :       *matches = conf_token_cmp_val_eq(conf, token, conf->tmp, 1, 0);
     529                 :     else
     530               0 :       *matches = conf_token_cmp_val_eq(conf, token,
     531                 :                                        HTTP__XTRA_HDR_PARAMS(req, ext_vary_a));
     532                 :   }
     533                 :   else
     534                 :   { /* spend time doing path/name/extn/bnwe */
     535           34140 :     Vstr_ref *ref = NULL;
     536           34140 :     unsigned int type = 0;
     537           34140 :     unsigned int lim  = 0;
     538           34140 :     size_t pos = 1;
     539           34140 :     size_t len = req->fname->len;
     540                 :     
     541                 :     if (0) { }
     542           34140 :     else if (OPT_SERV_SYM_EQ("path-beg"))
     543              44 :       type = HTTPD_POLICY_REQ_PATH_BEG;
     544           34096 :     else if (OPT_SERV_SYM_EQ("path-end"))
     545            1720 :       type = HTTPD_POLICY_REQ_PATH_END;
     546           32492 :     else if (OPT_SERV_SYM_EQ("path-eq") || OPT_SERV_SYM_EQ("path=="))
     547             116 :       type = HTTPD_POLICY_REQ_PATH_EQ;
     548           32260 :     else if (OPT_SERV_SYM_EQ("basename-beg"))
     549               4 :       type = HTTPD_POLICY_REQ_NAME_BEG;
     550           32256 :     else if (OPT_SERV_SYM_EQ("basename-end"))
     551               4 :       type = HTTPD_POLICY_REQ_NAME_END;
     552           32256 :     else if (OPT_SERV_SYM_EQ("basename-eq") || OPT_SERV_SYM_EQ("basename=="))
     553               4 :       type = HTTPD_POLICY_REQ_NAME_EQ;
     554           32248 :     else if (OPT_SERV_SYM_EQ("extension-beg"))
     555               4 :       type = HTTPD_POLICY_REQ_EXTN_BEG;
     556           32244 :     else if (OPT_SERV_SYM_EQ("extension-end"))
     557               4 :       type = HTTPD_POLICY_REQ_EXTN_END;
     558           32244 :     else if (OPT_SERV_SYM_EQ("extension-eq") || OPT_SERV_SYM_EQ("extension=="))
     559               4 :       type = HTTPD_POLICY_REQ_EXTN_EQ;
     560           32236 :     else if (OPT_SERV_SYM_EQ("extensions-beg"))
     561               4 :       type = HTTPD_POLICY_REQ_EXTS_BEG;
     562           32232 :     else if (OPT_SERV_SYM_EQ("extensions-end"))
     563               4 :       type = HTTPD_POLICY_REQ_EXTS_END;
     564           32232 :     else if (OPT_SERV_SYM_EQ("extensions-eq") ||
     565                 :              OPT_SERV_SYM_EQ("extensions=="))
     566               4 :       type = HTTPD_POLICY_REQ_EXTS_EQ;
     567           32224 :     else if (OPT_SERV_SYM_EQ("basename-without-extension-beg"))
     568               4 :       type = HTTPD_POLICY_REQ_BWEN_BEG;
     569           32220 :     else if (OPT_SERV_SYM_EQ("basename-without-extension-end"))
     570               4 :       type = HTTPD_POLICY_REQ_BWEN_END;
     571           32220 :     else if (OPT_SERV_SYM_EQ("basename-without-extension-eq") ||
     572                 :              OPT_SERV_SYM_EQ("basename-without-extension=="))
     573               4 :       type = HTTPD_POLICY_REQ_BWEN_EQ;
     574           32212 :     else if (OPT_SERV_SYM_EQ("basename-without-extensions-beg"))
     575               4 :       type = HTTPD_POLICY_REQ_BWES_BEG;
     576           32208 :     else if (OPT_SERV_SYM_EQ("basename-without-extensions-end"))
     577               4 :       type = HTTPD_POLICY_REQ_BWES_END;
     578           32208 :     else if (OPT_SERV_SYM_EQ("basename-without-extensions-eq") ||
     579                 :              OPT_SERV_SYM_EQ("basename-without-extensions=="))
     580               4 :       type = HTTPD_POLICY_REQ_BWES_EQ;
     581                 :     else
     582           32200 :       return (opt_serv_sc_tst(conf, token, matches, prev_match,
     583                 :                               tst_func, data));
     584                 : 
     585             970 :     ASSERT(type);
     586                 :     
     587            1940 :     if (!httpd_policy_path_make(con, req, conf, token, type, &ref))
     588                 :     {
     589               0 :       vstr_ref_del(ref);
     590               0 :       return (FALSE);
     591                 :     }
     592                 :     
     593            1940 :     lim = httpd_policy_path_req2lim(type);
     594            1940 :     *matches = httpd_policy_path_lim_eq(req->fname, &pos, &len, lim,
     595                 :                                         req->vhost_prefix_len, ref);
     596                 :   }
     597                 : 
     598          501788 :   return (TRUE);
     599                 : }
     600                 : 
     601                 : int httpd__policy_request_d1(struct Con *con, Httpd_req_data *req,
     602                 :                              Conf_parse *conf, Conf_token *token,
     603                 :                              int *stop)
     604           14688 : {
     605           14688 :   int clist = FALSE;
     606                 :   
     607           14688 :   CONF_SC_TOGGLE_CLIST_VAR(clist);
     608                 : 
     609           14688 :   if (token->type >= CONF_TOKEN_TYPE_USER_BEG)
     610                 :   {
     611            2780 :     unsigned int type = token->type - CONF_TOKEN_TYPE_USER_BEG;
     612            2780 :     unsigned int nxt = 0;
     613            2780 :     Vstr_ref *ref = conf_token_get_user_value(conf, token, &nxt);
     614                 :     
     615            2780 :     switch (type)
     616                 :     {
     617                 :       case HTTPD_POLICY_CON_POLICY:
     618             592 :         httpd_policy_change_con(con, ref->ptr);
     619             592 :         break;
     620                 :         
     621                 :       case HTTPD_POLICY_REQ_POLICY:
     622            2188 :         httpd_policy_change_req(con, req, ref->ptr);
     623            2188 :         break;
     624                 :         
     625                 :       default:
     626               0 :         vstr_ref_del(ref);
     627               0 :         return (FALSE);
     628                 :     }
     629                 : 
     630            2780 :     vstr_ref_del(ref);
     631            2780 :     if (nxt)
     632            2780 :       return (conf_parse_num_token(conf, token, nxt));
     633                 :   }
     634                 :   
     635           11908 :   else if (OPT_SERV_SYM_EQ("<close>"))
     636                 :   {
     637              32 :     evnt_close(con->evnt);
     638              32 :     return (TRUE);
     639                 :   }
     640           11876 :   else if (OPT_SERV_SYM_EQ("<stop>"))
     641                 :   {
     642              64 :     *stop = TRUE;
     643              64 :     return (TRUE);
     644                 :   }
     645           11812 :   else if (OPT_SERV_SYM_EQ("connection-policy"))
     646                 :   {
     647              48 :     const Httpd_policy_opts *policy = NULL;
     648                 : 
     649              48 :     if (!(policy = httpd__policy_build(con, conf, token,
     650                 :                                        HTTPD_POLICY_CON_POLICY)))
     651              32 :       return (FALSE);
     652              16 :     httpd_policy_change_con(con, policy);
     653                 :   }
     654           11764 :   else if (OPT_SERV_SYM_EQ("policy"))
     655                 :   {
     656              52 :     const Httpd_policy_opts *policy = NULL;
     657                 : 
     658              52 :     if (!(policy = httpd__policy_build(con, conf, token,
     659                 :                                        HTTPD_POLICY_REQ_POLICY)))
     660              32 :       return (FALSE);
     661              20 :     httpd_policy_change_req(con, req, policy);
     662                 :   }
     663           11712 :   else if (OPT_SERV_SYM_EQ("connection-tag"))
     664              64 :     OPT_SERV_X_VSTR(req->policy->s->beg, con->tag);
     665           11648 :   else if (OPT_SERV_SYM_EQ("tag"))
     666            3392 :     OPT_SERV_X_VSTR(req->policy->s->beg, req->tag);
     667            8256 :   else if (OPT_SERV_SYM_EQ("org.and.httpd-conf-req-1.0") ||
     668                 :            OPT_SERV_SYM_EQ("org.and.jhttpd-conf-req-1.0"))
     669                 :   {
     670            8256 :     Httpd_opts *opts = (Httpd_opts *)con->policy->s->beg;
     671            8256 :     return (httpd_conf_req_d0(con, req, /* server beg time is "close enough" */
     672                 :                               opts->beg_time, conf, token));
     673                 :   }
     674                 :   else
     675               0 :     return (FALSE);
     676                 :   
     677            3492 :   return (TRUE);
     678                 : }
     679                 : 
     680                 : static int httpd__policy_request_d0(struct Con *con, struct Httpd_req_data *req,
     681                 :                                     Conf_parse *conf, Conf_token *token,
     682                 :                                     int *stop)
     683          537968 : {
     684                 :   static int prev_match = TRUE;
     685          537968 :   unsigned int depth = token->depth_num;
     686          537968 :   int matches = TRUE;
     687                 : 
     688          537968 :   if (token->type != CONF_TOKEN_TYPE_SLIST)
     689               0 :     return (FALSE);
     690                 : 
     691          842248 :   while (conf_token_list_num(token, depth))
     692                 :   {
     693          563216 :     CONF_SC_PARSE_DEPTH_TOKEN_RET(conf, token, depth, FALSE);
     694                 : 
     695          563216 :     if (!httpd_match_request_sc_tst_d1(con, req, conf, token,
     696                 :                                        &matches, prev_match))
     697               0 :       return (FALSE);
     698                 : 
     699          563216 :     if (!matches)
     700                 :     {
     701          527920 :       prev_match = FALSE;
     702          527920 :       return (TRUE);
     703                 :     }
     704                 :   }
     705           10048 :   --depth;
     706                 : 
     707           10048 :   prev_match = TRUE;
     708                 : 
     709           30720 :   while (conf_token_list_num(token, depth))
     710                 :   {
     711           14016 :     CONF_SC_PARSE_DEPTH_TOKEN_RET(conf, token, depth, FALSE);
     712                 :     
     713           14016 :     if (!httpd__policy_request_d1(con, req, conf, token, stop))
     714            3296 :       return (FALSE);
     715           10720 :     if (*stop || con->evnt->flag_q_closed) /* don't do anything else */
     716              96 :       return (TRUE);
     717                 :   }
     718                 : 
     719            6656 :   return (TRUE);
     720                 : }
     721                 : 
     722                 : int httpd_policy_request(struct Con *con, struct Httpd_req_data *req,
     723                 :                          Conf_parse *conf, const Conf_token *beg_token)
     724           31841 : {
     725                 :   Conf_token token[1];
     726           31841 :   Vstr_ref *ref = NULL;
     727           31841 :   unsigned int num = 0;
     728                 :   
     729           31841 :   if (!beg_token->num) /* not been parsed */
     730           13561 :     return (TRUE);
     731                 :   
     732           18280 :   *token = *beg_token;
     733           18280 :   if (!httpd__match_iter_beg(conf, token, &ref, &num))
     734               0 :     return (TRUE);  
     735                 : 
     736                 :   do
     737                 :   {
     738          537968 :     int stop = FALSE;
     739                 :     
     740          537968 :     conf_parse_num_token(conf, token, token->num);
     741          268984 :     assert(token->type == (CONF_TOKEN_TYPE_USER_BEG+HTTPD_CONF_MAIN_MATCH_REQ));
     742                 :     
     743         1704736 :     while (token->type != CONF_TOKEN_TYPE_SLIST)
     744          897784 :       conf_parse_token(conf, token);
     745                 :     
     746          537968 :     if (!httpd__policy_request_d0(con, req, conf, token, &stop))
     747            3296 :       goto conf_fail;
     748          534672 :     if (stop || con->evnt->flag_q_closed) /* don't do anything else */
     749                 :       break;
     750          534576 :   } while (httpd__match_iter_nxt(conf, token, &ref, &num));
     751                 : 
     752           14984 :   vstr_ref_del(ref);
     753           14984 :   vstr_del(conf->tmp, 1, conf->tmp->len);
     754           14984 :   return (TRUE);
     755                 : 
     756            3296 :  conf_fail:
     757            3296 :   vstr_ref_del(ref);
     758            3296 :   vstr_del(conf->tmp, 1, conf->tmp->len);
     759            3296 :   if (!req->user_return_error_code)
     760                 :   {
     761              64 :     conf_parse_backtrace(conf->tmp, "<policy-request>", conf, token);
     762              64 :     HTTPD_ERR(req, 503);
     763                 :   }
     764            3296 :   return (FALSE);
     765                 : }
     766                 : 

Generated by: LTP GCOV extension version 1.4