diff --git a/dnfs/_run.sh b/dnfs/_run.sh
index befdc00..4c0aa75 100755
--- a/dnfs/_run.sh
+++ b/dnfs/_run.sh
@@ -1,5 +1,6 @@
#!/bin/bash
cd "$(dirname "$0")" || exit
-#bash ./_setup.sh
-#source ./.env/bin/activate
-exec ./dnfs.bin
+bash ./_setup.sh
+source ./.env/bin/activate
+#exec ./dnfs.bin
+exec python3 dnfs.py
diff --git a/dnfs/index.html b/dnfs/index.html
new file mode 100644
index 0000000..44262df
--- /dev/null
+++ b/dnfs/index.html
@@ -0,0 +1,144 @@
+
+
+
+
+
+ 树状笔记
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 正在迁移节点:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
确定删除该节点吗?
+
+
此节点包含文件,删除后文件将无法恢复
+
此操作不可恢复
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gateway/src/main.cpp b/gateway/src/main.cpp
index ca8f9f6..5af3a76 100644
--- a/gateway/src/main.cpp
+++ b/gateway/src/main.cpp
@@ -273,6 +273,19 @@ void registerRoutes(HttpServer &server) {
server.post("*", [](const auto& req, const auto& params) {
return handleProxy(req, params, "post");
});
+
+ server.options("*", [](const auto& req, const auto& params) {
+ pmc::net::http::response res;
+ res.result(pmc::net::http::status::ok);
+ res.set(pmc::net::http::field::access_control_allow_origin, "*");
+ res.set(pmc::net::http::field::access_control_allow_methods, "GET, POST, OPTIONS");
+ res.set(pmc::net::http::field::access_control_allow_headers, "Content-Type, Authorization");
+ res.set(pmc::net::http::field::access_control_max_age, "86400");
+ res.body() = "";
+ res.content_length(0);
+ res.prepare_payload();
+ return res;
+ });
}
http::response wrapperHttp(
@@ -444,6 +457,7 @@ http::response handleProxy(
std::string t_url = "";
std::string url = "";
std::string auth = "";
+ json::value jv_t; /* json value of the token */
{
auto flag = false;
auto it = req.base().find("Target-Url");
@@ -456,7 +470,7 @@ http::response handleProxy(
t_url = req["target-url"];
}
- if (url == "") {
+ if (t_url == "") {
t_url = _DEFT_URL;
flag = true;
}
@@ -466,7 +480,7 @@ http::response handleProxy(
url += req.target();
it = req.base().find("Authorization");
- if (it == req.base().end() && !flag) {
+ if (it == req.base().end() && !flag) { /* 不是默认代理地址且无令牌 */
throw std::runtime_error("401");
}
std::string raw = req["Authorization"];
@@ -484,21 +498,20 @@ http::response handleProxy(
}
std::cout << "auth data: " << auth << std::endl;
}
- }
- json::value jv;
- /* 令牌是否过期 */
- {
- /* TODO: 放进try包裹 */
- jv = json::parse(auth);
- json::object& obj = jv.as_object();
+ if (!flag) { /* 令牌是否过期 */
+
+ /* TODO: 放进try包裹 */
+ jv_t = json::parse(auth);
+ json::object& obj = jv_t.as_object();
- auto t = json::value_to(obj["created_at"]);
- bool r = LocalTime::isExpired(t);
+ auto t = json::value_to(obj["created_at"]);
+ bool r = LocalTime::isExpired(t);
- if (r) {
- THROW_EX_CUSTOM(HttpException, 2000, "Authorization Expired",
- 401, "*");
+ if (!r) {
+ THROW_EX_CUSTOM(HttpException, 2000, "Authorization Expired",
+ 401, "*");
+ }
}
}
diff --git a/libhttp/inc/us/HttpServer.hpp b/libhttp/inc/us/HttpServer.hpp
index 7617ff2..f157f38 100644
--- a/libhttp/inc/us/HttpServer.hpp
+++ b/libhttp/inc/us/HttpServer.hpp
@@ -60,6 +60,7 @@ public:
void post(const std::string& path, HttpRequestHandler handler);
void put(const std::string& path, HttpRequestHandler handler);
void del(const std::string& path, HttpRequestHandler handler);
+ void options(const std::string& path, HttpRequestHandler handler); // 新增 OPTIONS
void use(MiddlewareHandler middleware);
void setStaticDirectory(const std::string& path);
@@ -102,6 +103,7 @@ private:
std::vector post_handlers_;
std::vector put_handlers_;
std::vector delete_handlers_;
+ std::vector options_handlers_; // 新增 OPTIONS 路由
std::vector middlewares_;
std::string static_directory_;
@@ -113,6 +115,7 @@ private:
bool matchPath(const std::string& path, const std::regex& pattern);
http::response handleRequest(const http::request& req);
HttpRequestHandler findRoute(const std::string& method, const std::string& path);
+ bool routeExists(const std::string& method, const std::string& path); // 新增辅助方法
void addSession(const std::shared_ptr& session);
void removeSession(const Session* session);
diff --git a/libhttp/src/HttpServer.cpp b/libhttp/src/HttpServer.cpp
index a32fa74..588cad8 100644
--- a/libhttp/src/HttpServer.cpp
+++ b/libhttp/src/HttpServer.cpp
@@ -4,7 +4,7 @@
#include
#include
#include
-#include // SSL_CTX_set_cipher_list
+#include
namespace pmc {
namespace net {
@@ -85,7 +85,6 @@ private:
<< remote_ip_ << ":" << remote_port_
<< " - " << ec.message()
<< " (code=" << ec.value() << ")" << std::endl;
- // 输出 OpenSSL 详细错误堆栈
ERR_print_errors_fp(stderr);
}
}));
@@ -168,7 +167,6 @@ private:
HttpServer* server_;
bool ssl_enabled_;
- // 使用 any_io_executor 兼容多种执行器
asio::strand strand_;
std::string remote_ip_ = "unknown";
@@ -272,7 +270,6 @@ void HttpServer::initSSLContext() {
asio::ssl::context::no_sslv3 |
asio::ssl::context::single_dh_use);
- // 设置现代加密套件,确保兼容主流客户端
SSL_CTX_set_cipher_list(ssl_ctx_->native_handle(),
"ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:!aNULL:!MD5:!DSS");
@@ -391,6 +388,17 @@ void HttpServer::del(const std::string& path, HttpRequestHandler handler) {
delete_handlers_.push_back(entry);
}
+// ---- 新增 OPTIONS 路由注册 ----
+void HttpServer::options(const std::string& path, HttpRequestHandler handler) {
+ RouteEntry entry;
+ entry.path = path;
+ entry.handler = handler;
+ entry.is_wildcard = (path.find('*') != std::string::npos ||
+ path.find('?') != std::string::npos);
+ if (entry.is_wildcard) entry.pattern = wildcardToRegex(path);
+ options_handlers_.push_back(entry);
+}
+
void HttpServer::use(MiddlewareHandler m) {
middlewares_.push_back(m);
}
@@ -442,6 +450,7 @@ HttpRequestHandler HttpServer::findRoute(const std::string& method, const std::s
else if (method == "POST") handlers = &post_handlers_;
else if (method == "PUT") handlers = &put_handlers_;
else if (method == "DELETE") handlers = &delete_handlers_;
+ else if (method == "OPTIONS") handlers = &options_handlers_;
else return nullptr;
// 精确匹配优先
@@ -455,6 +464,11 @@ HttpRequestHandler HttpServer::findRoute(const std::string& method, const std::s
return nullptr;
}
+// ---- 新增辅助方法:检查路由是否存在 ----
+bool HttpServer::routeExists(const std::string& method, const std::string& path) {
+ return findRoute(method, path) != nullptr;
+}
+
// ---- 请求处理核心 ----
http::response HttpServer::handleRequest(const http::request& req) {
std::string target_path(req.target().data(), req.target().size());
@@ -486,6 +500,68 @@ http::response HttpServer::handleRequest(const http::request<
}
std::string method = http::to_string(req.method());
+
+ // ========== 处理 OPTIONS 预检请求 ==========
+ if (method == "OPTIONS") {
+ // 检查是否有自定义 OPTIONS 路由
+ auto handler = findRoute("OPTIONS", target_path);
+ if (handler) {
+ try {
+ return handler(req, params);
+ } catch (const std::exception& e) {
+ std::cerr << "[Handler] Exception: " << e.what() << std::endl;
+ res.result(http::status::internal_server_error);
+ res.body() = "500 Internal Server Error\n";
+ res.prepare_payload();
+ return res;
+ }
+ }
+
+ // 自动生成 OPTIONS 响应
+ auto origin = req.find(http::field::origin);
+ if (origin != req.end()) {
+ // 构建允许的方法列表
+ std::vector all_methods = {"GET", "POST", "PUT", "DELETE", "OPTIONS"};
+ std::vector allowed_methods;
+
+ // 检查每个方法是否有对应的路由
+ for (const auto& m : all_methods) {
+ if (m == "OPTIONS" || routeExists(m, target_path)) {
+ allowed_methods.push_back(m);
+ }
+ }
+
+ if (!allowed_methods.empty()) {
+ std::string allow_methods;
+ for (size_t i = 0; i < allowed_methods.size(); ++i) {
+ if (i > 0) allow_methods += ", ";
+ allow_methods += allowed_methods[i];
+ }
+
+ res.result(http::status::ok);
+ res.set(http::field::allow, allow_methods);
+ res.set(http::field::access_control_allow_origin,
+ std::string(origin->value()));
+ res.set(http::field::access_control_allow_methods, allow_methods);
+ res.set(http::field::access_control_allow_headers,
+ "Content-Type, Authorization, X-Requested-With, Accept, Origin");
+ res.set(http::field::access_control_max_age, "86400");
+ res.body() = "";
+ res.content_length(0);
+ res.prepare_payload();
+ return res;
+ }
+ }
+
+ // 没有 Origin 头或没有匹配的方法
+ res.result(http::status::not_found);
+ res.body() = "404 Not Found\n";
+ res.prepare_payload();
+ return res;
+ }
+ // ========== OPTIONS 处理结束 ==========
+
+ // 查找普通路由
auto handler = findRoute(method, target_path);
// 静态文件
@@ -562,6 +638,9 @@ void HttpServer::showStatus() const {
std::cout << " DELETE: " << delete_handlers_.size() << " handler(s)" << std::endl;
for (const auto& entry : delete_handlers_)
std::cout << " DELETE " << entry.path << (entry.is_wildcard ? " (wildcard)" : "") << std::endl;
+ std::cout << " OPTIONS: " << options_handlers_.size() << " handler(s)" << std::endl; // 新增
+ for (const auto& entry : options_handlers_)
+ std::cout << " OPTIONS " << entry.path << (entry.is_wildcard ? " (wildcard)" : "") << std::endl;
std::cout << "Middlewares: " << middlewares_.size() << std::endl;
std::cout << "==========================" << std::endl;
}
diff --git a/static/public/dnfs.html b/static/public/dnfs.html
index 6995789..275492a 100644
--- a/static/public/dnfs.html
+++ b/static/public/dnfs.html
@@ -98,5 +98,6 @@
百度推荐
+