优化http服务器目录菜单生成

http文件服务器路径目录支持无/结尾
This commit is contained in:
xiongziliang 2019-04-17 10:32:49 +08:00
parent bc1a79038c
commit c355ca51bf

View File

@ -30,6 +30,7 @@
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <algorithm> #include <algorithm>
#include <iomanip>
#include "Common/config.h" #include "Common/config.h"
#include "strCoding.h" #include "strCoding.h"
@ -296,7 +297,7 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) {
bool bClose = (strcasecmp(_parser["Connection"].data(),"close") == 0) || ( ++_iReqCnt > reqCnt); bool bClose = (strcasecmp(_parser["Connection"].data(),"close") == 0) || ( ++_iReqCnt > reqCnt);
//访问的是文件夹 //访问的是文件夹
if (strFile.back() == '/') { if (strFile.back() == '/' || File::is_dir(strFile.data())) {
//生成文件夹菜单索引 //生成文件夹菜单索引
string strMeun; string strMeun;
if (!makeMeun(strFile,_mediaInfo._vhost, strMeun)) { if (!makeMeun(strFile,_mediaInfo._vhost, strMeun)) {
@ -431,11 +432,18 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) {
inline bool HttpSession::makeMeun(const string &strFullPath,const string &vhost, string &strRet) { inline bool HttpSession::makeMeun(const string &strFullPath,const string &vhost, string &strRet) {
string strPathPrefix(strFullPath); string strPathPrefix(strFullPath);
strPathPrefix = strPathPrefix.substr(0, strPathPrefix.length() - 1); string last_dir_name;
if(strPathPrefix.back() == '/'){
strPathPrefix.pop_back();
}else{
last_dir_name = split(strPathPrefix,"/").back();
}
if (!File::is_dir(strPathPrefix.data())) { if (!File::is_dir(strPathPrefix.data())) {
return false; return false;
} }
strRet = "<html>\r\n" stringstream ss;
ss << "<html>\r\n"
"<head>\r\n" "<head>\r\n"
"<title>文件索引</title>\r\n" "<title>文件索引</title>\r\n"
"</head>\r\n" "</head>\r\n"
@ -444,20 +452,24 @@ inline bool HttpSession::makeMeun(const string &strFullPath,const string &vhost,
string strPath = strFullPath; string strPath = strFullPath;
strPath = strPath.substr(_strPath.length() + vhost.length() + 1); strPath = strPath.substr(_strPath.length() + vhost.length() + 1);
strRet += strPath; ss << strPath;
strRet += "</h1>\r\n"; ss << "</h1>\r\n";
if (strPath != "/") { if (strPath != "/") {
strRet += "<li><a href=\""; ss << "<li><a href=\"";
strRet += "/"; ss << "/";
strRet += "\">"; ss << "\">";
strRet += "根目录"; ss << "根目录";
strRet += "</a></li>\r\n"; ss << "</a></li>\r\n";
strRet += "<li><a href=\""; ss << "<li><a href=\"";
strRet += "../"; if(!last_dir_name.empty()){
strRet += "\">"; ss << "./";
strRet += "上级目录"; }else{
strRet += "</a></li>\r\n"; ss << "../";
}
ss << "\">";
ss << "上级目录";
ss << "</a></li>\r\n";
} }
DIR *pDir; DIR *pDir;
@ -475,38 +487,47 @@ inline bool HttpSession::makeMeun(const string &strFullPath,const string &vhost,
} }
setFile.emplace(pDirent->d_name); setFile.emplace(pDirent->d_name);
} }
int i = 0;
for(auto &strFile :setFile ){ for(auto &strFile :setFile ){
string strAbsolutePath = strPathPrefix + "/" + strFile; string strAbsolutePath = strPathPrefix + "/" + strFile;
if (File::is_dir(strAbsolutePath.data())) { bool isDir = File::is_dir(strAbsolutePath.data());
strRet += "<li><a href=\""; ss << "<li><span>" << i++ << "</span>\t";
strRet += strFile; ss << "<a href=\"";
strRet += "/\">"; if(!last_dir_name.empty()){
strRet += strFile; ss << last_dir_name << "/" << strFile;
strRet += "/</a></li>\r\n"; }else{
} else { //是文件 ss << strFile;
strRet += "<li><a href=\""; }
strRet += strFile;
strRet += "\">"; if(isDir){
strRet += strFile; ss << "/";
}
ss << "\">";
ss << strFile;
if (isDir) {
ss << "/</a></li>\r\n";
continue;
}
//是文件
struct stat fileData; struct stat fileData;
if (0 == stat(strAbsolutePath.data(), &fileData)) { if (0 == stat(strAbsolutePath.data(), &fileData)) {
auto &fileSize = fileData.st_size; auto &fileSize = fileData.st_size;
if (fileSize < 1024) { if (fileSize < 1024) {
strRet += StrPrinter << " (" << fileData.st_size << "B)" << endl; ss << " (" << fileData.st_size << "B)" << endl;
} else if (fileSize < 1024 * 1024) { } else if (fileSize < 1024 * 1024) {
strRet += StrPrinter << " (" << fileData.st_size / 1024 << "KB)" << endl; ss << fixed << setprecision(2) << " (" << fileData.st_size / 1024.0 << "KB)";
} else if (fileSize < 1024 * 1024 * 1024) { } else if (fileSize < 1024 * 1024 * 1024) {
strRet += StrPrinter << " (" << fileData.st_size / 1024 / 1024 << "MB)" << endl; ss << fixed << setprecision(2) << " (" << fileData.st_size / 1024 / 1024.0 << "MB)";
} else { } else {
strRet += StrPrinter << " (" << fileData.st_size / 1024 / 1024 / 1024 << "GB)" << endl; ss << fixed << setprecision(2) << " (" << fileData.st_size / 1024 / 1024 / 1024.0 << "GB)";
} }
} }
strRet += "</a></li>\r\n"; ss << "</a></li>\r\n";
}
} }
closedir(pDir); closedir(pDir);
strRet += "<ul>\r\n"; ss << "<ul>\r\n";
strRet += "</ul>\r\n</body></html>"; ss << "</ul>\r\n</body></html>";
ss.str().swap(strRet);
return true; return true;
} }
inline void HttpSession::sendResponse(const char* pcStatus, const KeyValue& header, const string& strContent) { inline void HttpSession::sendResponse(const char* pcStatus, const KeyValue& header, const string& strContent) {