fix(cookie): support Netscape cookies.txt and auto-refresh XSRF token - #88
Open
usmanovbf wants to merge 17 commits into
Open
fix(cookie): support Netscape cookies.txt and auto-refresh XSRF token#88usmanovbf wants to merge 17 commits into
usmanovbf wants to merge 17 commits into
Conversation
added 17 commits
August 25, 2026 00:21
- Parse Netscape-format cookie files (tab-separated cookies.txt) instead of sending raw file contents as the Cookie header - Extract SNlM0e XSRF token from the app page at startup when cookies are configured; required by StreamGenerate for authenticated requests - On HTTP 400/405, refresh BL and XSRF token mid-retry and rebuild the request so long-running servers survive token rotation - Sync modular package (refresh_bl_and_xsrf) with single-file script
- Google changed the upstream error envelope from 'BardErrorInfo [code]' to JSPB 'application.BardErrorInfo",[code]'; the old regex missed it, so rejected requests returned HTTP 200 with content:null instead of an error - Map known codes to human-readable hints (1060 = IP temporarily blocked / unsupported region, 1037 = usage limit, 1013 = transient) - Drop the 200-char line-length and 50-char payload heuristics that silently skipped valid short wrb.fr payloads - Streaming SSE responses now end with a finish chunk on error so clients do not hang on dropped streams - Add tests/test_upstream_errors.py covering both error formats and the short-line regression
StreamGenerate streaming paths retried BardErrorInfo rejections three times pointlessly - an IP block (1060) or quota rejection (1037) does not clear within a retry loop. Raise immediately instead; connection and transient errors keep their retry behaviour. 1060 responses now return in ~1s instead of after the full retry cycle.
Malformed JSON fell through the generic handler and produced HTTP 500; clients cannot distinguish their own bad request from a server fault. Matches the modular package, which already answers 400 invalid JSON.
Live-server test that a failing generate_stream (BardErrorInfo 1060) yields the partial content, an [error] finish chunk and [DONE], so clients terminate instead of hanging on a dropped stream.
Feed server.generate() a Russian answer and assert the full OpenAI completion shape survives JSON encoding end to end.
mtime-only caching can miss a same-second rewrite on filesystems with 1s timestamp resolution; (mtime, size) catches content changes in one write.
Anonymous StreamGenerate probe; prints blocked/UNBLOCKED and exits nonzero while the IP is blocked. Useful to tell 'Google blocked this IP' apart from a proxy regression before debugging code.
The modular package gained an extra-fields mechanism (inner[31]/inner[80] payload overrides for the enhanced Pro variant) that the single-file script never received, leaving the two builds listing different models (8 vs 9). Thread extra_fields through resolve/generate/stream paths and widen the payload array to 102 slots, matching the package.
The fail-fast guard stopped retrying every BardErrorInfo, but 1013 is documented as transient and clears on retry; only hard rejections (1060 IP block, 1037 quota) skip the retry loop.
Retrying an IP rate limit amplifies it. Surface 429 immediately with guidance so clients back off, matching the fail-fast behavior used for hard BardErrorInfo rejections.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
cookies.txtdirectly inload_cookie()(single-file and modular) - no manual conversionSNlM0e) from the app page at startup and auto-refresh BL + XSRF on HTTP 400/405 retries, so cookie sessions survive token rotation without a restartBardErrorInfo",[code]error envelope (old format still matched) and surface known codes as clear messages instead of silentcontent: nullwrb.frpayloads[DONE]on upstream failure, so clients never hangextra-fields model mechanism (gemini-3.1-pro-enhanced) to the single-file build - both builds now list the same 9 modelsprobe_upstream.py(one-shot reachability check) and README/README_CN updatesProblem
Running with a Netscape cookie file failed twice over:
load_cookie()only understood JSON{"cookie": ...}or a rawk=v; k2=v2string, so the whole tab-separated file was sent upstream as theCookieheader ->Invalid header value.at=SNlM0efrom the app page). The code could send it but never fetched it -> HTTP 400 with anxsrferror body.content: nullinstead of an error.Testing
python -m unittest discover -s tests), including new coverage for both error formats, short payloads, SSE error finish chunks and the mocked success path[error]finish chunk for streams)xsrf_tokenmid-session: both builds auto-recovered in ~4s