搭建服务器之处理目录
上节,(Linux C搭建HTTP服务器(一))搭建HTTP中我们只处理了普通文件,这节,我们尝试处理一下文件夹。
要处理文件夹要明白文件夹以什么形式回馈给客户端。而且要清楚我要打开的文件夹不一样,应该反馈给客户端不一样的
我们接上节的处理。
生成html
- 当打开文件夹时把文件夹中的所有文件给用(html)发送出来。所以如何写html就成了问题。这里建议使用唯一的id去定义这个html。因为我们要处理的并不是一个客户端,而是多个,如果仅有一个html的话容易出现错误,一般的处理是使用时间戳去定义(当然这里看自己的习惯)。
//定义html的名字
int ret = sprintf(filename, "%ld_%d_index.html", time(NULL), fd);
int filesize = 0;
- html的基本语法,大家一定有了解。
???</></></>(一切从简)。<br/> 那我们就需要先把这些必要的给写下来
//创建html
int srcfd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
if(srcfd < 0) {
perror("failed to open");
return -1;
}
//开头
char buf[1024] = "<html><head><title>Index of /</title></head><body bgcolor=\"white\"><h1>Index of /</h1><ul>";
filesize += write(srcfd, buf, strlen(buf));
- 读取目录内容我们拥到一个函数scandir();并将从scandir中的名字打给html;
// 读取目录内容,拼接字符串,写入文件
struct dirent ** pdents = NULL;
int nread = scandir(path, &pdents, NULL, alphasort);
for(int i = 0; i < nread ; i ++) {
memset(buf, 0x00, sizeof(buf));
strdecode(path,path);
if (pdents[i]->d_type == DT_DIR)
{
sprintf(buf, "<li><a href=\"%s/\">%s/</a></li>", pdents[i]->d_name, pdents[i]->d_name);
}
else if(pdents[i]->d_type == DT_REG) {
sprintf(buf, "<li><a href=\"%s\">%s</a></li>", pdents[i]->d_name, pdents[i]->d_name);
}
filesize += write(srcfd, buf, strlen(buf));
}
- 最后补目录
strcpy(buf, "</ul></body></html>");
filesize += write(srcfd, buf, strlen(buf));
发送目录
- 发送目录
send_header(fd, 200, "OK", get_mime_type(filename), filesize);
send_file(filename, fd);
2.删除html(用完就删,工具人)
unlink(filename);
代码
int product_file(char *path, char *filename, int bufsize, int fd)
{
//1.0 推荐生成全局唯一ID time(NULL)_fd.index.html
int ret = sprintf(filename, "%ld_%d_index.html", time(NULL), fd);
int filesize = 0;
//字节长度过长
if(ret >= bufsize) {
filename[bufsize-1] = '\0';
}
//创建或打开
int srcfd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
if(srcfd < 0) {
perror("failed to open");
return -1;
}
//写开头
char buf[1024] = "<html><head><title>Index of /</title></head><body bgcolor=\"white\"><h1>Index of /</h1><ul>";
filesize += write(srcfd, buf, strlen(buf));
// 读取目录内容,拼接字符串,写入文件
struct dirent ** pdents = NULL;
int nread = scandir(path, &pdents, NULL, alphasort);
for(int i = 0; i < nread ; i ++) {
memset(buf, 0x00, sizeof(buf));
if (pdents[i]->d_type == DT_DIR)
{
sprintf(buf, "<li><a href=\"%s/\">%s/</a></li>", pdents[i]->d_name, pdents[i]->d_name);
}
else if(pdents[i]->d_type == DT_REG) {
sprintf(buf, "<li><a href=\"%s\">%s</a></li>", pdents[i]->d_name, pdents[i]->d_name);
}
filesize += write(srcfd, buf, strlen(buf));
}
strcpy(buf, "</ul></body></html>");
filesize += write(srcfd, buf, strlen(buf));
close(srcfd);
return filesize;
}
int send_dir(char *path, int fd)
{
//1. 生成文件
//int product_file(char *path, char *filename, int bufsize, int fd)
char filename[256] = {0};
int filesize = product_file(path, filename, 256, fd);
if(filesize < 0 ) {
printf("product file err\n");
return -1;
}
//2. 发送头+文件
send_header(fd, 200, "OK", get_mime_type(filename), filesize);
send_file(filename, fd);
unlink(filename);
return 0;
}