httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@apache.org
Subject cvs commit: httpd-2.0/server request.c
Date Fri, 31 Aug 2001 01:50:15 GMT
wrowe       01/08/30 18:50:15

  Modified:    server   request.c
  Log:
      Normalize all paths to run the same, common code for pre-request setup
      from the primary request, redirects and sub-requests.
  
      This will significantly reduce opporunities for inconsistancy (such
      as Ian observed, and as I repaired only a month ago.)
  
      This promotes process_request_internal to an ap_ namespace protected
      entity in server/request.c (from it's old home in http/http_request.c)
      since this fn has no http specifics.
  
  Reviewed (in concept): Cliff Woolley, Ian Holsman
  
  Revision  Changes    Path
  1.39      +158 -66   httpd-2.0/server/request.c
  
  Index: request.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/request.c,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- request.c	2001/08/30 23:58:23	1.38
  +++ request.c	2001/08/31 01:50:15	1.39
  @@ -120,6 +120,134 @@
   AP_IMPLEMENT_HOOK_VOID(insert_filter, (request_rec *r), (r))
   AP_IMPLEMENT_HOOK_RUN_ALL(int,create_request,(request_rec *r),(r),OK,DECLINED)
   
  +
  +static int decl_die(int status, char *phase, request_rec *r)
  +{
  +    if (status == DECLINED) {
  +        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_CRIT, 0, r,
  +                    "configuration error:  couldn't %s: %s", phase, r->uri);
  +        return HTTP_INTERNAL_SERVER_ERROR;
  +    }
  +    else
  +        return status;
  +}
  +
  +/* This is the master logic for processing requests.  Do NOT duplicate
  + * this logic elsewhere, or the security model will be broken by future
  + * API changes.  Each phase must be individually optimized to pick up
  + * redundant/duplicate calls by subrequests, and redirects.
  + */
  +AP_DECLARE(int) ap_process_request_internal(request_rec *r)
  +{
  +    int access_status;
  +
  +    /* Ignore embedded %2F's in path for proxy requests */
  +    if (!r->proxyreq && r->parsed_uri.path) {
  +	access_status = ap_unescape_url(r->parsed_uri.path);
  +	if (access_status) {
  +	    return access_status;
  +	}
  +    }
  +
  +    ap_getparents(r->uri);     /* OK --- shrinking transformations... */
  +
  +    if ((access_status = ap_location_walk(r))) {
  +        return access_status;
  +    }
  +
  +    if ((access_status = ap_run_translate_name(r))) {
  +        return decl_die(access_status, "translate", r);
  +        return access_status;
  +    }
  +
  +    if ((access_status = ap_run_map_to_storage(r))) {
  +        /* This request wasn't in storage (e.g. TRACE) */
  +        if (access_status == DONE)
  +	    return OK;
  +	else
  +            return access_status;
  +    }
  +
  +    if ((access_status = ap_location_walk(r))) {
  +        return access_status;
  +    }
  +
  +    /* Only on the main request! */
  +    if (r->main == NULL) {
  +        if ((access_status = ap_run_header_parser(r))) {
  +            return access_status;
  +        }
  +    }
  +
  +    switch (ap_satisfies(r)) {
  +    case SATISFY_ALL:
  +    case SATISFY_NOSPEC:
  +        if ((access_status = ap_run_access_checker(r)) != 0) {
  +            return decl_die(access_status, "check access", r);
  +        }
  +        if (ap_some_auth_required(r)) {
  +            if (((access_status = ap_run_check_user_id(r)) != 0) || !ap_auth_type(r)) {
  +                return decl_die(access_status, ap_auth_type(r)
  +		            ? "check user.  No user file?"
  +		            : "perform authentication. AuthType not set!", r);
  +            }
  +            if (((access_status = ap_run_auth_checker(r)) != 0) || !ap_auth_type(r)) {
  +                return decl_die(access_status, ap_auth_type(r)
  +		            ? "check access.  No groups file?"
  +		            : "perform authentication. AuthType not set!", r);
  +            }
  +        }
  +        break;
  +    case SATISFY_ANY:
  +        if (((access_status = ap_run_access_checker(r)) != 0) || !ap_auth_type(r)) {
  +            if (!ap_some_auth_required(r)) {
  +                return decl_die(access_status, ap_auth_type(r)
  +		            ? "check access"
  +		            : "perform authentication. AuthType not set!", r);
  +            }
  +            if (((access_status = ap_run_check_user_id(r)) != 0) || !ap_auth_type(r)) {
  +                return decl_die(access_status, ap_auth_type(r)
  +		            ? "check user.  No user file?"
  +		            : "perform authentication. AuthType not set!", r);
  +            }
  +            if (((access_status = ap_run_auth_checker(r)) != 0) || !ap_auth_type(r)) {
  +                return decl_die(access_status, ap_auth_type(r)
  +		            ? "check access.  No groups file?"
  +		            : "perform authentication. AuthType not set!", r);
  +            }
  +        }
  +        break;
  +    }
  +
  +    /* XXX Must make certain the ap_run_type_checker short circuits mime
  +     * in mod-proxy for r->proxyreq && r->parsed_uri.scheme 
  +     *                              && !strcmp(r->parsed_uri.scheme, "http")
  +     */
  +    if ((access_status = ap_run_type_checker(r)) != 0) {
  +	return decl_die(access_status, "find types", r);
  +    }
  +
  +    if ((access_status = ap_run_fixups(r)) != 0) {
  +        return access_status;
  +    }
  +
  +    /* The new insert_filter stage makes sense here IMHO.  We are sure that
  +     * we are going to run the request now, so we may as well insert filters
  +     * if any are available.  Since the goal of this phase is to allow all
  +     * modules to insert a filter if they want to, this filter returns
  +     * void.  I just can't see any way that this filter can reasonably
  +     * fail, either your modules inserts something or it doesn't.  rbb
  +     */
  +    ap_run_insert_filter(r);
  +
  +    if ((access_status = ap_invoke_handler(r)) != 0) {
  +        return access_status;
  +    }
  +
  +    return OK;
  +}
  +
  +
   /*****************************************************************
    *
    * Getting and checking directory configuration.  Also checks the
  @@ -1207,27 +1335,6 @@
       ap_set_sub_req_protocol(rnew, r);
   }
   
  -static int sub_req_common_validation(request_rec *rnew)
  -{
  -    int res;
  -    if (((   ap_satisfies(rnew) == SATISFY_ALL
  -             || ap_satisfies(rnew) == SATISFY_NOSPEC)
  -            ? ((res = ap_run_access_checker(rnew))
  -               || (ap_some_auth_required(rnew)
  -                   && ((res = ap_run_check_user_id(rnew))
  -                       || (res = ap_run_auth_checker(rnew)))))
  -            : ((res = ap_run_access_checker(rnew))
  -               && (!ap_some_auth_required(rnew)
  -                   || ((res = ap_run_check_user_id(rnew))
  -                       || (res = ap_run_auth_checker(rnew)))))
  -           )
  -        || (res = ap_run_type_checker(rnew))
  -        || (res = ap_run_fixups(rnew)))
  -        return res;
  -    else
  -        return 0;
  -}
  -
   AP_CORE_DECLARE_NONSTD(apr_status_t) ap_sub_req_output_filter(ap_filter_t *f,
                                                           apr_bucket_brigade *bb)
   {
  @@ -1260,6 +1367,9 @@
       return 0;
   } 
   
  +
  +
  +
   AP_DECLARE(request_rec *) ap_sub_req_method_uri(const char *method,
                                                   const char *new_file,
                                                   const request_rec *r,
  @@ -1291,42 +1401,10 @@
           ap_parse_uri(rnew, ap_make_full_path(rnew->pool, udir, new_file));
       }
   
  -    res = ap_unescape_url(rnew->uri);
  -    if (res) {
  +    if ((res = ap_process_request_internal(rnew))) {
           rnew->status = res;
  -        return rnew;
       }
   
  -    ap_getparents(rnew->uri);
  -
  -    if ((res = ap_location_walk(rnew))) {
  -        rnew->status = res;
  -        return rnew;
  -    }
  -
  -    res = ap_run_translate_name(rnew);
  -    if (res) {
  -        rnew->status = res;
  -        return rnew;
  -    }
  -
  -    /*
  -     * We could be clever at this point, and avoid calling directory_walk,
  -     * etc. However, we'd need to test that the old and new filenames contain
  -     * the same directory components, so it would require duplicating the
  -     * start of translate_name. Instead we rely on the cache of .htaccess
  -     * results.
  -     *
  -     * NB: directory_walk() clears the per_dir_config, so we don't inherit
  -     * from location_walk() above
  -     */
  -
  -    if ((res = ap_directory_walk(rnew))
  -        || (res = ap_file_walk(rnew))
  -        || (res = ap_location_walk(rnew))
  -        || (res = sub_req_common_validation(rnew))) {
  -        rnew->status = res;
  -    }
       return rnew;
   }
   
  @@ -1341,7 +1419,6 @@
                                                      const request_rec *r,
                                                      ap_filter_t *next_filter)
   {
  -    apr_status_t rv;
       request_rec *rnew;
       int res;
       char *fdir;
  @@ -1375,6 +1452,9 @@
       
       ap_parse_uri(rnew, rnew->uri);    /* fill in parsed_uri values */
   
  +#if 0 /* XXX When this is reenabled, the cache triggers need to be set to faux
  +       * dir_walk/file_walk values.
  +       */
       rnew->per_dir_config = r->per_dir_config;
   
       if ((dirent->valid & APR_FINFO_MIN) != APR_FINFO_MIN) {
  @@ -1385,6 +1465,7 @@
            * to an APR_DIR, then we will rerun everything anyways... 
            * this should be safe.
            */
  +        apr_status_t rv;
           if (ap_allow_options(rnew) & OPT_SYM_LINKS) {
               if (((rv = apr_stat(&rnew->finfo, rnew->filename,
                                    APR_FINFO_MIN, rnew->pool)) != APR_SUCCESS)
  @@ -1440,16 +1521,12 @@
               return rnew;
           }  
       }
  -    else {
  -        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, rnew,
  -                      "symlink doesn't point to a file or directory: %s",
  -                      r->filename);
  -        res = HTTP_FORBIDDEN;
  -    }
  +#endif
   
  -    if (res || (res = sub_req_common_validation(rnew))) {
  +    if ((res = ap_process_request_internal(rnew))) {
           rnew->status = res;
       }
  +
       return rnew;
   }
   
  @@ -1497,11 +1574,14 @@
              && ap_strchr_c(rnew->filename + fdirlen, '/') == NULL) 
       {
           char *udir = ap_make_dirstr_parent(rnew->pool, r->uri);
  -        apr_status_t rv;
   
           rnew->uri = ap_make_full_path(rnew->pool, udir, new_file);
           ap_parse_uri(rnew, rnew->uri);    /* fill in parsed_uri values */
   
  +#if 0 /* XXX When this is reenabled, the cache triggers need to be set to faux
  +       * dir_walk/file_walk values.
  +       */
  +
           rnew->per_dir_config = r->per_dir_config;
   
           /*
  @@ -1509,16 +1589,19 @@
            * we will rerun everything anyways... this should be safe.
            */
           if (ap_allow_options(rnew) & OPT_SYM_LINKS) {
  +            apr_status_t rv;
               if (((rv = apr_stat(&rnew->finfo, rnew->filename,
                                    APR_FINFO_MIN, rnew->pool)) != APR_SUCCESS)
                                                         && (rv != APR_INCOMPLETE))
                   rnew->finfo.filetype = 0;
           }
  -        else
  +        else {
  +            apr_status_t rv;
               if (((rv = apr_lstat(&rnew->finfo, rnew->filename,
                                    APR_FINFO_MIN, rnew->pool)) != APR_SUCCESS)
                                                         && (rv != APR_INCOMPLETE))
                   rnew->finfo.filetype = 0;
  +        }
   
           if ((res = check_safe_file(rnew))) {
               rnew->status = res;
  @@ -1565,6 +1648,7 @@
                             r->filename);
               res = HTTP_FORBIDDEN;
           }
  +#endif
       }
       else {
   	/* XXX: @@@: What should be done with the parsed_uri values? */
  @@ -1575,16 +1659,24 @@
            * file may not have a uri associated with it -djg
            */
           rnew->uri = "INTERNALLY GENERATED file-relative req";
  +
  +#if 0 /* XXX When this is reenabled, the cache triggers need to be set to faux
  +       * dir_walk/file_walk values.
  +       */
  +
           rnew->per_dir_config = r->server->lookup_defaults;
           res = ap_directory_walk(rnew);
           if (!res) {
               res = ap_file_walk(rnew);
           }
  +#endif
       }
   
  -    if (res || (res = sub_req_common_validation(rnew))) {
  +
  +    if ((res = ap_process_request_internal(rnew))) {
           rnew->status = res;
       }
  +
       return rnew;
   }
   
  @@ -1592,7 +1684,7 @@
   {
       int retval;
   
  -    /* see comments in process_request_internal() */
  +    /* see comments in ap_process_request_internal() */
       ap_run_insert_filter(r);
       retval = ap_invoke_handler(r);
       ap_finalize_sub_req_protocol(r);
  
  
  

Mime
View raw message