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 Wed, 02 Jan 2002 21:58:43 GMT
wrowe       02/01/02 13:58:43

  Modified:    server   request.c
  Log:
    Merge a singular path for dir_walk to parse, if we have an r->filename
    which is an APR_DIR, and path_info contents.  Also, al la Mr. Pane,
    optimize our canonical_filename by simply noting the length of the
    identity match, and refresh canonical_filename when we are finished.
  
  Revision  Changes    Path
  1.90      +92 -16    httpd-2.0/server/request.c
  
  Index: request.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/request.c,v
  retrieving revision 1.89
  retrieving revision 1.90
  diff -u -r1.89 -r1.90
  --- request.c	2 Jan 2002 21:34:50 -0000	1.89
  +++ request.c	2 Jan 2002 21:58:43 -0000	1.90
  @@ -559,7 +559,9 @@
            * it goes out of scope, filename_len==strlen(r->filename)
            */
           apr_size_t filename_len;
  -
  +#ifdef CASE_BLIND_FILESYSTEM
  +        apr_size_t canonical_len;
  +#endif
           /*
            * We must play our own mimi-merge game here, for the few 
            * running dir_config values we care about within dir_walk.
  @@ -572,24 +574,94 @@
           opts_remove = this_dir->opts_remove;
           override = this_dir->override;
   
  -        /* Save path_info to merge back onto path_info later. If this
  -         * isn't really path_info, what would it be doing here?
  +        /* Set aside path_info to merge back onto path_info later.
  +         * If r->filename is a directory, we must remerge the path_info, 
  +         * before we continue!  [Directories cannot, by defintion, have
  +         * path info.  Either the next segment is not-found, or a file.]
  +         *
  +         * r->path_info tracks the unconsumed source path.
  +         * r->filename  tracks the path as we process it
            */
  -        save_path_info = r->path_info;
  +        if ((r->finfo.filetype == APR_DIR) && r->path_info && *r->path_info)

  +        {
  +            if ((rv = apr_filepath_merge(&r->path_info, r->filename, r->path_info,
  +                                         APR_FILEPATH_NOTABOVEROOT, r->pool))
  +                      != APR_SUCCESS) {
  +                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
  +                              "dir_walk error, path_info %s is not relative "
  +                              "to the filename path %s for uri %s", 
  +                              r->path_info, r->filename, r->uri);
  +                return HTTP_INTERNAL_SERVER_ERROR;
  +            }
  +            save_path_info = NULL;
  +        }
  +        else {
  +            save_path_info = r->path_info;
  +            r->path_info = r->filename;
  +        }
   
  -        /* Now begin to build r->filename from components, set aside the
  -         * segments we have yet to work with in r->path_info (where they
  -         * will stay when the current element resolves to a regular file.)
  -         *
  -         * r->path_info tracks the remaining source path.
  -         * r->filename  tracks the path as we build it.
  +#ifdef CASE_BLIND_FILESYSTEM
  +
  +        canonical_len = 0; 
  +        while (r->canonical_filename && r->canonical_filename[canonical_len]
  +            && (r->canonical_filename[canonical_len]
  +                      == r->path_info[canonical_len])) {
  +             ++canonical_len;
  +        }
  +        while (canonical_len
  +                 && ((r->canonical_filename[canonical_len - 1] != '/'
  +                   && r->canonical_filename[canonical_len - 1])
  +                  || (r->path_info[canonical_len - 1] != '/'
  +                   && r->path_info[canonical_len - 1]))) {
  +            --canonical_len;
  +        }
  +
  +        /* 
  +         * Now build r->filename component by component, starting
  +         * with the root (on Unix, simply "/").  We will make a huge
  +         * assumption here for efficiency, that any canonical path 
  +         * already given included a canonical root.
  +         */
  +        rv = apr_filepath_root((const char **)&r->filename,
  +                               (const char **)&r->path_info,
  +                               canonical_len 
  +                                   ? 0 : APR_FILEPATH_TRUENAME, 
  +                               r->pool);
  +        filename_len = strlen(r->filename);
  +
  +        /*
  +         * Bad assumption above?  If the root's length is longer
  +         * than the canonical length, then it cannot be trusted as
  +         * a truename.  So try again, this time more seriously.
            */
  -        r->path_info = r->filename;
  +        if ((rv == APR_SUCCESS) && canonical_len 
  +                                && (filename_len > canonical_len)) {
  +            rv = apr_filepath_root((const char **)&r->filename,
  +                                   (const char **)&r->path_info,
  +                                   APR_FILEPATH_TRUENAME, r->pool);
  +            filename_len = strlen(r->filename);
  +            canonical_len = 0;
  +        }
  +
  +#else /* ndef CASE_BLIND_FILESYSTEM, really this simple for Unix today; */
  +
           rv = apr_filepath_root((const char **)&r->filename,
                                  (const char **)&r->path_info,
  -                               APR_FILEPATH_TRUENAME, r->pool);
  +                               0, r->pool);
           filename_len = strlen(r->filename);
  -        /* Space for terminating null and an extra / is required. */
  +
  +#endif
  +
  +        if (rv != APR_SUCCESS) {
  +            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
  +                          "dir_walk error, could not determine the root "
  +                          "path of filename %s%s for uri %s", 
  +                          r->filename, r->path_info, r->uri);
  +            return HTTP_INTERNAL_SERVER_ERROR;
  +        }
  +
  +        /* Working space for terminating null and an extra / is required.
  +         */
           buflen = filename_len + strlen(r->path_info) + 2;
           buf = apr_palloc(r->pool, buflen);
           memcpy(buf, r->filename, filename_len + 1);
  @@ -842,9 +914,7 @@
                */
               if (r->finfo.filetype 
   #ifdef CASE_BLIND_FILESYSTEM
  -                && (r->canonical_filename 
  -                    && (strncmp(r->filename, 
  -                                r->canonical_filename, filename_len) == 0))
  +                && (filename_len <= canonical_len)
   #endif
                   && ((opts & (OPT_SYM_OWNER | OPT_SYM_LINKS)) == OPT_SYM_LINKS))

               {
  @@ -1027,6 +1097,12 @@
    x       return res;
    x   }
    */
  +
  +    /* Save future sub-requestors much angst in processing
  +     * this subrequest.  If dir_walk couldn't canonicalize
  +     * the file path, nothing can.
  +     */
  +    r->canonical_filename = r->filename;
   
       if (r->finfo.filetype == APR_DIR) {
           cache->cached = r->filename;
  
  
  

Mime
View raw message