2014-09-30 45 views
0

这是用于Web服务器分配的,这是我希望实现的一个额外功能。我想确保客户端无法在服务器根目录之上指定文件。确定两个目录之间的相对位置

例如,假设我有一个文件夹“上方”,并且在“上面”中,我有www。我在服务器中将根目录设置为/above/www,因此服务器应该能够访问/above/www内的任何内容。也让我说above,所以/above/a1.txt,我不希望客户端能够执行GET /../a1.txt HTTP/1.0并获得该文件的访问权限。

我有90%的服务器实现,我只需要确定一个文件是否在文件系统树中给定的目录之上或者是否在下面。除了计算../字符串以外,我想不出一个超级简单的方法,如果有更多的字符串比文件夹更多,我就在我的根目录之上。

我正在运行linux,并且C++ 11是可以接受的。

+0

所以,总而言之,你想要的东西比计数更容易* – 2014-09-30 22:50:52

+0

我只是想知道是否有一个函数存在,在我执行它之前就做了我想要的。 – Evan 2014-09-30 22:53:01

+0

我以为例如Apache已经这样做了? – 2014-09-30 22:55:50

回答

0

使用boost::filesystem::path(relativePath).absolute().parent_path().string()获取relativePath所代表的文件所在目录的绝对路径。现在,您可以简单地检查"/above/www"是该目录的前缀。

0

我完成任务的方法是使用两个for循环和strtok。 这可能不是最C++的答案,但它的工作原理。

bool within_dir(const char* path, const char* root_dir) 
{ 

    assert(path != NULL); 
    assert(root_dir != NULL); 
    char *fname_dup, *root_dup, *token; 
    int root_value, path_value; 

    // Duplicate char arrays so strtok doesn't damage the originals 
    fname_dup = (char*)malloc(sizeof(char) * strlen(path) + 1); 
    assert(fname_dup != NULL); 
    bzero(fname_dup, sizeof(char) * strlen(path) +1); 
    strncpy (fname_dup, path, sizeof(char) * strlen(path)); 

    root_dup = (char*)malloc(sizeof(char) * strlen(root_dir) + 1); 
    assert(root_dup != NULL); 
    bzero(root_dup, sizeof(char) * strlen(root_dir)+ 1); 
    strncpy(root_dup, root_dir, sizeof(char) * strlen(root_dir)); 

    // Count root directory 
    for (root_value = 0, token = strtok(root_dup, "/"); 
        token != NULL; 
        token = strtok(NULL, "/")) 
    {           
      if (strcmp(token, "..") == 0) 
        root_value--; 
      else 
        root_value++; 
    } 

    // Count and compare path value to root value 
    for (path_value = 0, token = strtok(fname_dup, "/"); 
        token != NULL; 
        token = strtok(NULL, "/")) 
    { 
      if (strcmp(token, "..") == 0) 
      { 
        path_value--; 
        if (path_value < root_value) 
        { 
          free(root_dup); 
          free(fname_dup); 
          return false; 
        } 
      } 
      else 
        path_value++; 
    } 
    free(root_dup); 
    free(fname_dup); 
    return true; 

} 

基本上,代码贯穿并计算根的“正面”或“负面”方式。上升到一个水平是负面的,下降是积极的。一旦知道根的值,如果文件路径的值永远低于根的值,我们知道文件路径必须在根目录之上至少一层,因此是无效的。因为我们实际上并不关心实际值,所以只有当它从根目录上层时,我们立即停止并返回false。如果文件路径始终保持比根更积极的状态,那么filetree上的文件路径将始终较低。不保证链接。