{"record":{"id":"8e6380c7585ff911","repo":"tonhowtf/omniget","slug":"http-fetcher","errorCode":null,"errorMessage":"HTTP {}","messagePattern":"HTTP \\{\\}","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/http_fetcher.rs","lineNumber":971,"sourceCode":"    let mut req = client.get(url);\n    if let Some(h) = headers {\n        req = req.headers(headers_without_range(h));\n    }\n    req = req.header(\n        reqwest::header::RANGE,\n        format!(\"bytes={}-{}\", range_start, end),\n    );\n\n    let resp = tokio::time::timeout(cfg.connect_timeout, req.send())\n        .await\n        .map_err(|_| anyhow!(\"connect timeout\"))??;\n\n    let status = resp.status();\n    if status != reqwest::StatusCode::PARTIAL_CONTENT {\n        if status.is_success() {\n            return Err(anyhow!(\"server did not honor Range (HTTP 200)\"));\n        }\n        return Err(anyhow!(\"HTTP {}\", status));\n    }\n\n    // A 206 alone is not proof the server gave us the slice we asked for. If it\n    // answers a different offset and we write the body at ours anyway, the file\n    // still ends up the right size and is silently corrupt — the one failure\n    // mode a segmented download cannot detect later.\n    if let Some(start) = content_range_start(resp.headers()) {\n        if start != range_start {\n            return Err(anyhow!(\n                \"server answered range at byte {} but {} was requested\",\n                start,\n                range_start\n            ));\n        }\n    }\n\n    if let Some(ct) = resp.headers().get(reqwest::header::CONTENT_TYPE) {\n        if let Ok(s) = ct.to_str() {","sourceCodeStart":953,"sourceCodeEnd":989,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/http_fetcher.rs#L953-L989","documentation":"download_segment only accepts HTTP 206 Partial Content when fetching a byte range. If the server replies 200 (ignoring the Range header) or any non-206 status, it refuses to write the body, because writing a full body at a segment offset would silently corrupt the assembled file.","triggerScenarios":"A worker segment request gets HTTP 200 because the server ignored the Range header, or gets 403/404/416/5xx for the ranged GET issued by download_segment.","commonSituations":"Servers/proxies without range support (some CDNs, CGI scripts, PHP handlers) answering 200; wrong or expired presigned URL returning 403; file removed returning 404; rate-limited or overloaded origin returning 5xx.","solutions":["Verify the server/CDN supports Range requests (curl -H 'Range: bytes=0-99' -I and expect 206 with Accept-Ranges: bytes)","Check the URL is still valid and authorized (403/404 usually means expired token or deleted object)","Remove or reconfigure proxies/middlewares that strip the Range header","Fall back to a single-stream (non-segmented) download for this host"],"exampleFix":"// server ignores Range: bytes=100-199 -> 200 with full body\n// fix: confirm range support before segmenting\ncurl -sI -H \"Range: bytes=0-99\" https://example.com/file.bin  # expect HTTP/1.1 206 Partial Content","handlingStrategy":"retry","validationCode":"// probe range support before segmented download\nlet resp = client.head(url).send().await?;\nlet range_ok = resp.headers().get(\"accept-ranges\").map(|v| v == \"bytes\").unwrap_or(false);\nif !range_ok { use_single_stream_download(); }","typeGuard":"fn is_partial_content(status: reqwest::StatusCode) -> bool { status == reqwest::StatusCode::PARTIAL_CONTENT }","tryCatchPattern":"match download_segment(...).await {\n    Err(e) if e.to_string().contains(\"HTTP 200\") || e.to_string().starts_with(\"HTTP \") => {\n        log::warn!(\"range not honored, falling back to single stream\");\n        single_stream_download().await?;\n    }\n    Err(e) => return Err(e),\n    Ok(()) => {}\n}","preventionTips":["Check Accept-Ranges and a probe Range request before segmenting","Keep URLs/tokens fresh; refresh auth before long downloads","Test downloads through the same proxies/CDNs users will use","Provide a non-segmented fallback path"],"tags":["http","range-requests","download"],"backgroundTag":"unexpected-http-status","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}