【问题标题】:Writing my own HTTP Server - How to find relative path of a file编写我自己的 HTTP 服务器 - 如何查找文件的相对路径
【发布时间】:2013-02-22 09:28:50
【问题描述】:

我目前正在用 C 语言编写一个基于 UNIX 套接字的 HTTP 服务器,并且我即将实现 GET 请求的一部分,该部分检查请求的文件以确保它具有适当的权限。

在我对 HTTP 服务器一无所知之前,我设置了一个 Apache 服务器,据我了解,HTTP 服务器在一个目录中查找请求的文件。我不知道这是因为服务器在某种程度上没有目录之外的权限,还是它实际上验证了路径以确保它在目录内。

现在我要自己实现它,我不确定如何正确处理它。 C 中是否有一个函数可以让我确定路径是否在给定目录内(例如 foo/bar/../../bazfoo/ 内)?

在python中,我会使用os.path.relpath并检查结果是否以..开头,以确保路径不在给定目录之外。

比如,如果目录是/foo/bar/htdocs,给定的路径是index.html/../../passwords.txt,我要../passwords.txt,所以从前面的..可以看出文件是在/foo/bar/htdocs 目录之外。

【问题讨论】:

  • 没有c++?普通的ANSI C?
  • @RicardoOrtegaMagaña 只是简单的 ANSI C,我的导师建议使用它或 Java 来完成作业。

标签: c httpserver


【解决方案1】:

您会惊讶于 Python 的 I/O 功能有多少直接映射到 POSIX 的功能。 :)

换句话说,查找realpath()

当 POSIX 有一个函数的更具描述性的名称时,这真是太棒了,包括那个额外的字母! :)

【讨论】:

  • 我认为您误解了我的问题,我想要一个来自特定目录(例如htdocs)的相对路径,以便我可以确定文件路径是否为很好。
【解决方案2】:

How to get the absolute path for a given relative path programmatically in Linux?

#include <stdlib.h> 
#include <stdio.h> 
int main() 
{ 
        char resolved_path[100]; 
        realpath("../../", resolved_path); 
        printf("\n%s\n",resolved_path); 
        return 0; 
}

你可以试试。正如同一个服务员(放松)在那里回答的那样。

【讨论】:

  • 我需要一个从目录到给定相对路径的相对路径,我想原来的问题不清楚,我会编辑。
【解决方案3】:

它的工作方式要简单得多:一旦服务器收到请求,它只查看其 htdoc(静态内容)目录以检查请求的资源是否存在:

char *htdoc = "/opt/server/htdoc"; // here a sub-directory of the server program
char *request = "GET /index.html"; // the client request
char *req_path = strchr(request, ' ') + 1; // the URI path

char filepath[512]; // build the file-system path
snprintf(filepath, sizeof(filepath) - 1, "%s/%s", htdos, req_path);

FILE *f = fopen(filepath, "r"); // try to open the file
...

请注意,此代码不安全,因为它不会通过包含“../”模式(和其他技巧)来检查请求是否在文件系统中冒险。您还应该使用stat() 来确保该文件是常规 文件并且服务器有权读取它。

【讨论】:

  • 你的最后一段正是我试图解决的问题,哈哈。
  • 然后,您可以按照我上面的指导方针或在开源 Web 服务器中找到它是如何完成的。编写这样的代码不是一件容易的事(尤其是如果正确地完成),因此不能合理地在此处发布(太具体、太长、太复杂)。
【解决方案4】:

作为一个简单(但不完整)的解决方案,我只是决定编写一些代码来检查任何.. 的文件路径。

int is_valid_fname(char *fname) {
    char *it = fname;
    while(TRUE) {
        if (strncmp(it, "..", 2) == 0) {
            return FALSE;
        }
        it = strchr(it, '/');
        if (it == NULL) break;
        it++;
    }
    return TRUE;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多