You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
1.6 KiB
C++
76 lines
1.6 KiB
C++
#include <iostream>
|
|
#include <fstream>
|
|
#include "../cpp-httplib/httplib.h"
|
|
#include <filesystem>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <direct.h>
|
|
#include <iostream>
|
|
|
|
|
|
using namespace std;
|
|
using namespace httplib;
|
|
|
|
const string SERVER_FILE_DIR = "/ServerFiles/";
|
|
|
|
string GetExeDir()
|
|
{
|
|
char buff[_MAX_PATH];
|
|
_getcwd(buff, _MAX_PATH);
|
|
string currPath(buff);
|
|
return string(buff);
|
|
}
|
|
|
|
bool file_exists(const string& path) {
|
|
ifstream file(path, ios::binary);
|
|
return file.good();
|
|
}
|
|
|
|
void send_file(const string& file_path, Response& res) {
|
|
ifstream file(file_path, ios::binary | ios::ate);
|
|
if (!file) {
|
|
res.status = 500; // 服务器错误
|
|
res.set_content("Failed to open file", "text/plain");
|
|
return;
|
|
}
|
|
|
|
// 获取文件大小
|
|
streamsize file_size = file.tellg();
|
|
file.seekg(0, ios::beg);
|
|
|
|
res.set_content_provider(
|
|
file_size, "application/octet-stream",
|
|
[file_path](size_t offset, size_t length, DataSink& sink) {
|
|
ifstream file(file_path, ios::binary);
|
|
if (!file) return false;
|
|
|
|
file.seekg(offset, ios::beg);
|
|
vector<char> buffer(length);
|
|
file.read(buffer.data(), length);
|
|
sink.write(buffer.data(), file.gcount()); // 发送数据
|
|
|
|
return true; // 继续传输
|
|
}
|
|
);
|
|
}
|
|
|
|
int main() {
|
|
Server svr;
|
|
|
|
svr.Get(R"(/download/(.+))", [&](const Request& req, Response& res) {
|
|
string filename = req.matches[1];
|
|
string file_path = GetExeDir()+SERVER_FILE_DIR + filename;
|
|
|
|
if (!file_exists(file_path)) {
|
|
res.status = 404;
|
|
res.set_content("File not found", "text/plain");
|
|
return;
|
|
}
|
|
|
|
send_file(file_path, res);
|
|
});
|
|
|
|
cout << "Server started at http://localhost:1234\n";
|
|
svr.listen("localhost", 1234);
|
|
}
|