浏览代码

feat: 优化Nginx存储解析逻辑并调整测试配置

- 在`src/error.rs`中为`status_code`方法添加`#[allow(dead_code)]`属性
- 在`src/storage/nginx.rs`中改进`parse_entries`方法,解析`pre`元素以获取文件修改时间和大小
- 更新`tests/nginx/Dockerfile`和`nginx-test.conf`,调整测试目录结构和服务器配置

Signed-off-by: longjin <longjin@DragonOS.org>
longjin 1 周之前
父节点
当前提交
b1059bcb8c
共有 4 个文件被更改,包括 58 次插入11 次删除
  1. 1 2
      src/error.rs
  2. 52 4
      src/storage/nginx.rs
  3. 3 3
      tests/nginx/Dockerfile
  4. 2 2
      tests/nginx/nginx-test.conf

+ 1 - 2
src/error.rs

@@ -52,6 +52,7 @@ impl HttpError {
         }
     }
 
+    #[allow(dead_code)]
     pub fn status_code(&self) -> u16 {
         match self {
             Self::Forbidden { .. } => 403,
@@ -133,5 +134,3 @@ impl HttpError {
         }
     }
 }
-
-pub type Result<T> = std::result::Result<T, HttpError>;

+ 52 - 4
src/storage/nginx.rs

@@ -1,6 +1,7 @@
 use std::time::SystemTime;
 
 use async_trait::async_trait;
+use chrono::{TimeZone, Utc};
 use reqwest::Url;
 use scraper::{Html, Selector};
 use url::Url as UrlParser;
@@ -65,10 +66,23 @@ impl NginxStorageProvider {
 
     fn parse_entries(&self, html: &str, path: &str) -> anyhow::Result<Vec<StorageEntry>> {
         let document = Html::parse_document(html);
-        let selector = Selector::parse("a").unwrap();
+        let link_selector =
+            Selector::parse("a").map_err(|e| anyhow::anyhow!("Invalid selector: 'a': {}", e))?;
+        let pre_selector = Selector::parse("pre")
+            .map_err(|e| anyhow::anyhow!("Invalid selector: 'pre': {}", e))?;
         let mut entries = Vec::new();
 
-        for element in document.select(&selector) {
+        // 获取pre元素中的文本内容
+        let pre_text = document
+            .select(&pre_selector)
+            .next()
+            .ok_or_else(|| anyhow::anyhow!("No pre element found in nginx autoindex"))?
+            .text()
+            .collect::<String>();
+        // 按行分割pre文本
+        let lines: Vec<&str> = pre_text.split('\n').collect();
+
+        for element in document.select(&link_selector) {
             if let Some(href) = element.value().attr("href") {
                 if href == "../" {
                     continue;
@@ -76,11 +90,45 @@ impl NginxStorageProvider {
 
                 let name = element.text().collect::<String>();
                 let url = format!("{}/{}", path.trim_end_matches('/'), href);
+
+                // 查找对应的行来获取日期和大小
+                let (modified, size) = lines
+                    .iter()
+                    .find(|line| line.contains(&name))
+                    .map(|line| {
+                        let parts: Vec<&str> = line.split_whitespace().collect();
+                        if parts.len() >= 4 {
+                            // 尝试解析日期和时间
+                            let date_time = format!("{} {}", parts[1], parts[2]);
+                            let modified =
+                                chrono::NaiveDateTime::parse_from_str(&date_time, "%d-%b-%Y %H:%M")
+                                    .unwrap_or(
+                                        chrono::DateTime::<chrono::Utc>::from(SystemTime::now())
+                                            .naive_utc(),
+                                    );
+
+                            // 尝试解析文件大小
+                            let size = parts[3].parse::<usize>().ok();
+
+                            (modified, size)
+                        } else {
+                            (
+                                chrono::DateTime::<chrono::Utc>::from(SystemTime::now())
+                                    .naive_utc(),
+                                None,
+                            )
+                        }
+                    })
+                    .unwrap_or((
+                        chrono::DateTime::<chrono::Utc>::from(SystemTime::now()).naive_utc(),
+                        None,
+                    ));
+                let modified: SystemTime = SystemTime::from(Utc.from_utc_datetime(&modified));
                 let entry = StorageEntry {
                     name,
                     url,
-                    modified: SystemTime::now(), // nginx autoindex doesn't provide modified time
-                    size: None,                  // nginx autoindex doesn't provide file size
+                    modified,
+                    size,
                 };
                 entries.push(entry);
             }

+ 3 - 3
tests/nginx/Dockerfile

@@ -1,15 +1,15 @@
 # 使用官方nginx镜像作为基础
-FROM nginx:latest
+FROM nginx:1.27.0
 
 # 复制测试用的nginx配置
 COPY nginx-test.conf /etc/nginx/conf.d/default.conf
 
 # 创建测试目录结构
 RUN mkdir -p /usr/share/nginx/html/test && \
-    mkdir -p /usr/share/nginx/html/dir1/dir2 && \
+    mkdir -p /usr/share/nginx/html/test/dir1/dir2 && \
     echo "test1" > /usr/share/nginx/html/test/file1.txt && \
     echo "test2" > /usr/share/nginx/html/test/file2.txt && \
-    echo "nested" > /usr/share/nginx/html/dir1/dir2/file3.txt
+    echo "nested" > /usr/share/nginx/html/test/dir1/dir2/file3.txt
 
 # 暴露80端口
 EXPOSE 80

+ 2 - 2
tests/nginx/nginx-test.conf

@@ -1,10 +1,10 @@
 server {
     listen 80;
-    server_name localhost;
+    server_name 0.0.0.0;
     autoindex on;
 
     location / {
-        root   /usr/share/nginx/html;
+        root   /usr/share/nginx/html/test;
         index  index.html index.htm;
     }