C 编写自己的HTTP服务器-如何查找文件的相对路径
我目前正在用C编写一个基于UNIX套接字的HTTP服务器,我将实现GET请求的一部分,该部分检查请求的文件以确保它具有适当的权限 在我了解HTTP服务器之前,我设置了一个Apache服务器,据我所知,HTTP服务器只需查找一个目录即可找到请求的文件。我不知道这是否是因为服务器不知何故在目录外没有权限,或者它是否确实验证了路径以确保它在目录内 现在我要自己实现这个,我不知道如何正确处理这个问题。C中是否有一个函数允许我确定路径是否在给定目录中(例如IsC 编写自己的HTTP服务器-如何查找文件的相对路径,c,httpserver,C,Httpserver,我目前正在用C编写一个基于UNIX套接字的HTTP服务器,我将实现GET请求的一部分,该部分检查请求的文件以确保它具有适当的权限 在我了解HTTP服务器之前,我设置了一个Apache服务器,据我所知,HTTP服务器只需查找一个目录即可找到请求的文件。我不知道这是否是因为服务器不知何故在目录外没有权限,或者它是否确实验证了路径以确保它在目录内 现在我要自己实现这个,我不知道如何正确处理这个问题。C中是否有一个函数允许我确定路径是否在给定目录中(例如Isfoo/bar/../../bazinside
foo/bar/../../baz
insidefoo/
)
在python中,我将使用os.path.relpath
并检查结果是否以。
开头,以确保路径不在给定目录之外
例如,如果目录是
/foo/bar/htdocs
,给定路径是index.html/。/../passwords.txt
,我想要。/passwords.txt
,因此,我可以从前面的。
中看到该文件位于/foo/bar/htdocs
目录之外。您会惊讶于Python的I/O功能有多少直接映射到POSIX的功能。:)
换句话说,向上看
当POSIX为一个函数提供了更具描述性的名称,并包含了额外的字母时,这真是太棒了!:)
#包括
#包括
int main()
{
字符解析_路径[100];
实路径(“../”,已解析的路径);
printf(“\n%s\n”,解析路径);
返回0;
}
你可以试试。正如同一个ser(unwind)所回答的那样。它的工作方式要简单得多:一旦服务器收到请求,它只会查看其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()
确保该文件是常规文件,并且服务器具有读取该文件的权限 作为一个简单(但不完整)的解决方案,我决定写一点代码来检查文件路径中是否有。
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;
}
没有C++?简单的ansi c?@RicardoOrtegaMagaña只是简单的ansi c,我的导师建议在作业中使用Java。我想你误解了我的问题,我想要一个特定目录的相对路径(例如,
htdocs
),这样我就可以确定文件路径是否正确。我需要一个从目录到给定相对路径的相对路径,我猜原来的问题不清楚,我会编辑。你的最后一段正是我试图解决的问题,哈哈。然后,你可以遵循我上面的指导方针,或者找到如何在开源Web服务器中完成。编写这样的代码不是一项简单的任务(特别是如果正确有效地完成的话),因此不能在这里合理地发布(太具体、太长、太复杂)。
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;
}