amir1376 / amir1376/ab-download-manager-browser-integration
【Feature Request】Support more download method
- 主要言語
- TypeScript
- スター
- 236
- フォーク
- 41
- 平均マージ
- 1日 17時間
- マージ済み PR(30日)
- 1
説明
### Some helpful info as follow from AI:
Now let me get the key utility files to understand the current approach:Now let me provide a comprehensive English comparison:
## Why [motrix-next-extension](https://github.com/AnInsomniacy/motrix-next-extension) Can Identify Downloads That ab-download-manager Cannot
### **1. Multi-Layer Link Detection Strategy**
#### **ab-download-manager's Limitations:**
- Only intercepts `main_frame` or `sub_frame` type requests (lines 148-149)
- Only supports GET method (line 154)
- Only accepts HTTP status codes 200-299 (line 163)
- **Requires recognizable file extension** (line 209)
- Requires `Content-Type` to NOT start with `text/` (line 79)
#### **motrix-next-extension's Advantages:**
- Implements a **5-stage modular filtering pipeline**
- Supports **multiple protocols**: `magnet://`, `ed2k://`, `thunder://` (external protocol interception)
- Handles **presigned cloud URLs** (AWS S3, Aliyun OSS, Quark, 115, Baidu formats)
- Parses **Content-Disposition query parameters** for hidden filenames
- Uses **glob pattern matching** for site-specific rules
### **2. Intelligent Filename Extraction**
**ab-download-manager's Basic Approach:**
```typescript
// URLUtils.ts - very basic extraction
export function getFileFromUrl(url: string): string | null {
try {
return new URL(url, "http://dummy.base")
.pathname.split("/").pop() ?? null
} catch (error) {
return null;
}
}
// Only extracts pathname basename
// Fails on: URLs without extensions, query-param filenames, encoded names
```
**motrix-next-extension's Advanced Approach:**
```typescript
// shared/url.ts - comprehensive extraction
export function extractFilenameFromUrl(url: string): string | null {
// Priority 1: response-content-disposition query param (cloud drives)
// Priority 2: content-disposition query param (alternative)
// Priority 3: URL pathname basename (must contain file extension)
// Handles RFC 2047 MIME encoded-words
// Example: =?UTF-8?B?5L2g5LiW6Ieq5o6l?= → actual filename
}
// Weak filename detection
function isWeakBrowserFilename(url: string, filename: string): boolean {
// Rejects generic names: 'download', 'unresolved-filename'
// Rejects pure numbers without extension
// Validates against URL path hints
}
```
### **3. URL Redirect Tracking**
**ab-download-manager:**
- ❌ Records requests but doesn't fully track redirect chains
**motrix-next-extension:**
- ✅ Tracks `initialRequest.url` → `finalRequest.url` mapping
- ✅ Compares both URLs when extracting filename
- ✅ Handles cases where filename changes after redirects
### **4. Site-Specific Rule Matching**
**ab-download-manager:**
- Simple URL blacklist: exact string or wildcard
**motrix-next-extension:**
- **Glob patterns**: `*.lanzou*.com`, `*.cdn.example.com`
- **Per-site actions**: `always-intercept`, `always-skip`, `use-global`
- **Multi-hostname matching**: checks `tabUrl`, `url`, `finalUrl`
```typescript
// SiteRuleStage - intelligent pattern matching
private collectHostnames(ctx: FilterContext): string[] {
const seen = new Set();
const hostnames: string[] = [];
// Check all relevant URLs, deduplicate
for (const rawUrl of [ctx.tabUrl, ctx.url, ctx.finalUrl]) {
const h = this.extractHostname(rawUrl);
if (h && !seen.has(h)) {
seen.add(h);
hostnames.push(h);
}
}
return hostnames;
}
for (const rule of rules) {
const isMatch = picomatch(rule.pattern); // Glob pattern
if (hostnames.some((h) => isMatch(h))) {
// Apply rule action
}
}
```
### **5. Special Content Type Handling**
**ab-download-manager:**
```typescript
// Rejects anything starting with "text/"
protected isWebPageComponents(responseHeaders: Headers) {
const contentType = getContentType(responseHeaders)
if (contentType?.toLowerCase().startsWith("text/")) {
return true // Reject
}
return false
}
```
**motrix-next-extension:**
```typescript
// More nuanced: checks MIME type classification
export class DocumentMimeStage implements FilterStage {
readonly name = 'document-mime';
evaluate(ctx: FilterContext, config: DownloadSettings): FilterVerdict | null {
// Only rejects known document types (application/pdf, text/*, etc.)
// Allows edge cases handled by filename metadata
}
}
```
### **6. Filename Metadata Caching**
**ab-download-manager:**
- Extracts filename only at interception time
**motrix-next-extension:**
```typescript
// Stores Content-Disposition headers for later use
rememberContentDisposition(url: string, header: string): void {
const filename = extractFilenameFromContentDisposition(header);
if (!filename || !isUsableFilename(filename)) return;
this.byUrl.set(canonicalUrl(url), {
filename: normalizeFilename(filename),
source: 'content-disposition',
createdAt: this.now(),
});
}
// Later retrieves with smart fallback
async resolve(item, waitMs = 300): Promise {
// Polls cache for up to 300ms
// Falls back to URL extraction if cache misses
}
```
### **Real-World Examples Where Detection Fails:**
| Scenario | ab-download-manager | motrix-next-extension |
|----------|-------------------|----------------------|
| `https://cdn.quark.cn/hash123?response-content-disposition=filename*=UTF-8''%E6%96%87%E4%BB%B6` | ❌ No extension in URL | ✅ Parses query param |
| `https://storage.example.com/download?token=xyz` (file served without extension) | ❌ No extension found | ✅ Falls back to Content-Disposition header |
| Redirect: `https://example.com/file.zip` → `https://cdn.akamai.com/a1b2c3d` | ⚠️ May miss filename change | ✅ Tracks both URLs |
| POST method downloads | ❌ Blocked (GET-only) | ✅ Supported with content metadata |
| `magnet://xt=urn:btih:...` | ❌ Not HTTP protocol | ✅ Content script intercepts |
| HTML5 `` | ❌ Blob protocol filtered | ⚠️ Captured with metadata extraction |
### **Key Architectural Differences:**
| Aspect | ab-download-manager | motrix-next-extension |
|--------|-------------------|----------------------|
| Filter Design | Single-pass chain | 5-stage modular pipeline |
| Filename Sources | URL + Content-Disposition header | URL + param + header + metadata cache |
| Protocol Support | HTTP/HTTPS only | HTTP/HTTPS/FTP + magnet/ed2k/thunder |
| Site Rules | String patterns | Glob patterns (picomatch) |
| Encoding Support | Basic | RFC 2047 MIME words, UTF-8, etc. |
| Duplicate Detection | None | URL + filename + size multi-dimensional |
| Extensibility | Limited | Plugin-based filter stages |
### **Recommendation for Improvement:**
To enhance ab-download-manager's detection, consider implementing:
1. **Add presigned URL handling** in `URLUtils.ts`:
```typescript
function extractFilenameFromUrl(url: string): string | null {
const parsed = new URL(url);
// Check response-content-disposition param first
const cdParam = parsed.searchParams.get('response-content-disposition');
if (cdParam) {
return extractFromContentDisposition(cdParam);
}
// Fall back to pathname
return extractPathname(parsed);
}
```
2. **Enhance `shouldHandleRequestForDirectDownload`** to support redirect tracking
3. **Add RFC 2047 MIME decoding** for special characters in filenames
4. **Implement glob pattern matching** for site rules using libraries like `picomatch`
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
評価
この issue はまだ評価されていません。