diff --git a/conf/config.ini b/conf/config.ini
index d8c64678..3114c652 100644
--- a/conf/config.ini
+++ b/conf/config.ini
@@ -158,6 +158,12 @@ sendBufSize=65536
sslport=443
#是否显示文件夹菜单,开启后可以浏览文件夹
dirMenu=1
+#虚拟目录, 虚拟目录名和文件路径使用","隔开,多个配置路径间用";"隔开
+#例如赋值为 app_a,/path/to/a;app_b,/path/to/b 那么
+#访问 http://127.0.0.1/app_a/file_a 对应的文件路径为 /path/to/a/file_a
+#访问 http://127.0.0.1/app_b/file_b 对应的文件路径为 /path/to/b/file_b
+#访问其他http路径,对应的文件路径还是在rootPath内
+kVirtualPath=
[multicast]
#rtp组播截止组播ip地址
diff --git a/src/Common/config.cpp b/src/Common/config.cpp
index 93dc71d6..2b3db74a 100644
--- a/src/Common/config.cpp
+++ b/src/Common/config.cpp
@@ -124,6 +124,7 @@ onceToken token([](){
mINI::Instance()[kMaxReqSize] = 4 * 10240;
mINI::Instance()[kKeepAliveSecond] = 15;
mINI::Instance()[kDirMenu] = true;
+ mINI::Instance()[kVirtualPath] = "";
#if defined(_WIN32)
mINI::Instance()[kCharSet] = "gb2312";
diff --git a/src/Common/config.h b/src/Common/config.h
index 23430020..917c76c6 100644
--- a/src/Common/config.h
+++ b/src/Common/config.h
@@ -183,7 +183,7 @@ extern const string kKeepAliveSecond;
extern const string kCharSet;
//http 服务器根目录
extern const string kRootPath;
-//http 服务器虚拟目录 虚拟目录名和磁盘物理路径使用“,”隔开,多个配置路径间用 "|"隔开,例如 path1,d:/record|path2,e:/record
+//http 服务器虚拟目录 虚拟目录名和文件路径使用","隔开,多个配置路径间用";"隔开,例如 path_d,d:/record;path_e,e:/record
extern const string kVirtualPath;
//http 404错误提示内容
extern const string kNotFound;
diff --git a/src/Http/HttpFileManager.cpp b/src/Http/HttpFileManager.cpp
index 0e1e34c4..75251f27 100644
--- a/src/Http/HttpFileManager.cpp
+++ b/src/Http/HttpFileManager.cpp
@@ -79,6 +79,7 @@ static bool makeFolderMenu(const string &httpPath, const string &strFullPath, st
return false;
}
string strPathPrefix(strFullPath);
+ //url后缀有没有'/'访问文件夹,处理逻辑不一致
string last_dir_name;
if (strPathPrefix.back() == '/') {
strPathPrefix.pop_back();
@@ -90,12 +91,12 @@ static bool makeFolderMenu(const string &httpPath, const string &strFullPath, st
return false;
}
stringstream ss;
- ss << "\r\n"
- "
\r\n"
- "文件索引\r\n"
- "\r\n"
- "\r\n"
- "文件索引:";
+ ss << "\r\n"
+ "\r\n"
+ "文件索引\r\n"
+ "\r\n"
+ "\r\n"
+ "文件索引:";
ss << httpPath;
ss << "
\r\n";
@@ -107,9 +108,9 @@ static bool makeFolderMenu(const string &httpPath, const string &strFullPath, st
ss << "\r\n";
ss << "
";
@@ -122,7 +123,7 @@ static bool makeFolderMenu(const string &httpPath, const string &strFullPath, st
if ((pDir = opendir(strPathPrefix.data())) == NULL) {
return false;
}
- set setFile;
+ multimap > file_map;
while ((pDirent = readdir(pDir)) != NULL) {
if (File::is_special_dir(pDirent->d_name)) {
continue;
@@ -130,34 +131,35 @@ static bool makeFolderMenu(const string &httpPath, const string &strFullPath, st
if (pDirent->d_name[0] == '.') {
continue;
}
- setFile.emplace(pDirent->d_name);
+ file_map.emplace(pDirent->d_name, std::make_pair(pDirent->d_name, strPathPrefix + "/" + pDirent->d_name));
}
//如果是root目录,添加虚拟目录
if (httpPath == "/") {
GET_CONFIG(string, virtualPath, Http::kVirtualPath);
- mediakit::Parser pathParser;
- StrCaseMap args = pathParser.parseArgs(virtualPath, "|", ",");
- for (auto arg : args) {
- setFile.emplace(arg.first);
+ StrCaseMap args = Parser::parseArgs(virtualPath, ";", ",");
+ for (auto &pr : args) {
+ file_map.emplace(pr.first, std::make_pair(string("虚拟目录:") + pr.first, File::absolutePath("", pr.second)));
}
}
int i = 0;
- for (auto &strFile :setFile) {
- string strAbsolutePath = strPathPrefix + "/" + strFile;
+ for (auto &pr :file_map) {
+ auto &strAbsolutePath = pr.second.second;
bool isDir = File::is_dir(strAbsolutePath.data());
ss << "" << i++ << "\t";
ss << "";
- ss << strFile;
+ //路径名称
+ ss << pr.second.first;
if (isDir) {
ss << "/\r\n";
continue;
@@ -470,19 +472,20 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
static string getFilePath(const Parser &parser,const MediaInfo &mediaInfo, TcpSession &sender){
GET_CONFIG(bool, enableVhost, General::kEnableVhost);
- GET_CONFIG(string, rootPath, Http::kRootPath);
GET_CONFIG(string, virtualPath, Http::kVirtualPath);
- mediakit::Parser pathParser;
- StrCaseMap args = pathParser.parseArgs(virtualPath, "|", ",");
+ StrCaseMap args = Parser::parseArgs(virtualPath, ";", ",");
auto path = args[mediaInfo._app];
- string ret;
- if (path == "") {
- ret = File::absolutePath(
- enableVhost ? mediaInfo._vhost + parser.Url() : parser.Url(), rootPath);
- }else {
- ret = File::absolutePath(
- enableVhost ? mediaInfo._vhost + "/" + mediaInfo._streamid : mediaInfo._streamid, path);
+ string url;
+ if (path.empty()) {
+ //访问的是根路径
+ GET_CONFIG(string, rootPath, Http::kRootPath);
+ path = rootPath;
+ url = parser.Url();
+ } else {
+ //访问的是虚拟路径
+ url = parser.Url().substr(1 + mediaInfo._app.size());
}
+ auto ret = File::absolutePath(enableVhost ? mediaInfo._vhost + url : url, path);
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastHttpBeforeAccess, parser, ret, static_cast(sender));
return ret;
}