{"record":{"id":"f8e99647a034d71d","repo":"docmirror/dev-sidecar","slug":"pac-txt-pax-txt","errorCode":null,"errorMessage":"下载远程 pac.txt 文件成功，但内容为空或内容太短，判断为无效的 pax.txt 文件:","messagePattern":"下载远程 pac\\.txt 文件成功，但内容为空或内容太短，判断为无效的 pax\\.txt 文件:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/mitmproxy/src/lib/proxy/middleware/overwall.js","lineNumber":101,"sourceCode":"          log.info(`'${pacFilePath}' 文件的修改时间已更新为其最近更新时间 '${dateUtil.format(lastModifiedTime, false)}'`)\n        }\n      })\n    })\n  }\n}\n\n// 异步下载 pac.txt ，避免影响代理服务的启动速度\nasync function downloadPacAsync (pacConfig) {\n  const remotePacFileUrl = pacConfig.pacFileUpdateUrl\n  log.info('开始下载远程 pac.txt 文件:', remotePacFileUrl)\n  request(remotePacFileUrl, (error, response, body) => {\n    if (error) {\n      log.error(`下载远程 pac.txt 文件失败: ${remotePacFileUrl}, error:`, error, ', response:', response, ', body:', body)\n      return\n    }\n    if (response && response.statusCode === 200) {\n      if (body == null || body.length < 100) {\n        log.warn('下载远程 pac.txt 文件成功，但内容为空或内容太短，判断为无效的 pax.txt 文件:', remotePacFileUrl, ', body:', body)\n        return\n      } else {\n        log.info('下载远程 pac.txt 文件成功:', remotePacFileUrl)\n      }\n\n      // 尝试解析Base64（注：https://gitlab.com/gfwlist/gfwlist/raw/master/gfwlist.txt 下载下来的是Base64格式）\n      let pacTxt = body\n      if (!pacTxt.includes('!---------------------EOF')) {\n        try {\n          pacTxt = Buffer.from(pacTxt, 'base64').toString('utf8')\n          // log.debug('解析 base64 后的 pax:', pacTxt)\n        } catch {\n          log.error(`远程 pac.txt 文件内容即不是base64格式，也不是要求的格式，url: ${remotePacFileUrl}，body: ${body}`)\n          return\n        }\n      }\n\n      // 保存到本地","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/docmirror/dev-sidecar/blob/7710cd56cce760c708f30b01d2d4056eb8c402d5/packages/mitmproxy/src/lib/proxy/middleware/overwall.js#L83-L119","documentation":"The overwall plugin downloads a remote pac.txt (gfwlist-style) file to build its proxy rules. If the download succeeds with HTTP 200 but the body is null or shorter than 100 bytes, the content is judged invalid (e.g. an error page, redirect stub, or CAPTCHA body), a warning is logged, and the pac file is not updated — the previous rules remain in effect.","triggerScenarios":"downloadPacAsync fetches remotePacFileUrl, receives statusCode 200, but the body is empty or <100 bytes — typically a captive portal, anti-bot page, or misconfigured mirror returning a tiny 200 response.","commonSituations":"The remote pac URL is dead/renamed and the host returns a soft-200 stub; hotlink protection or CDN challenge pages; network environments (airports, hotels) intercepting HTTP(S) with portal responses; self-hosted pac file not uploaded correctly.","solutions":["Check remotePacFileUrl in a browser/curl — if it no longer serves the list, update the pac URL in overwall config to a valid mirror.","Bypass any captive portal / complete network login, then trigger the download again.","Host the pac.txt yourself (commit gfwlist to your own repo/server) and point config at that stable URL.","Rely on the previously cached pac file meanwhile — the plugin keeps the old rules when a download is invalid."],"exampleFix":"// before\n\"overwall\": { \"pacFileUrl\": \"http://old.mirror.example/pac.txt\" }\n// after\n\"overwall\": { \"pacFileUrl\": \"https://raw.gitmirror.com/gfwlist/gfwlist/master/gfwlist.txt\" }","handlingStrategy":"retry","validationCode":"const res = await fetch(pacUrl)\nconst body = await res.text()\nif (res.ok && body && body.length >= 100) applyPac(body)\nelse scheduleRetry(alternateUrl)","typeGuard":null,"tryCatchPattern":"try { await downloadPacAsync() } catch (e) { loadCachedPac(); scheduleRetry() }","preventionTips":["Host pac.txt on a stable URL you control","Verify the pac URL with curl before configuring it","Complete captive-portal logins before triggering downloads","Keep a cached copy of the last valid pac file"],"tags":["pac","download","overwall","network","proxy"],"backgroundTag":"empty-download-body","analyzedSha":"7710cd56cce760c708f30b01d2d4056eb8c402d5","analyzedAt":"2026-08-31T22:07:07.234Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}