Repository navigation
Conversation
Reddit rejects anonymous comments JSON requests with an HTML 403, including encoded-slash paths. Fetch post metadata through by_id and transform the Android PostComments forest into the Listing shape used by the renderer. Keep sorting, focused comment context, nested replies, and cursor pagination. Escape rich text and reject unsafe URL schemes; report upstream HTTP/API failures without treating them as JSON syntax errors. Cache successful thread responses for 30 seconds and keep existing OAuth and post access checks. Adapt the converter and RTJSON renderer from polak14's a63460b implementation, without the unrelated dependency updates or Shreddit scraper fallback. Validation: nine GraphQL converter/request tests, cargo fmt and strict clippy; live anonymous GraphQL requests from the affected container validate sorts, focused comments, and cursor pagination. Co-authored-by: polak14 <76823966+polak14@users.noreply.github.com>
Reddit returns DEPENDENCY_FAILURE when PostComments combines an after cursor with focusedCommentContext. A cursor already identifies its subtree, so only send focused context for the initial permalink request. Cover this with request-variable tests and verify the failing nested cursor against the live API.
|
just tested this out from a fresh checkout of your fork and built locally via |
Reddit rejects anonymous comments JSON requests with an HTML 403, including encoded-slash paths. Fetch post metadata through by_id and transform the Android PostComments forest into the Listing shape used by the renderer. Keep sorting, focused comment context, nested replies, and cursor pagination. Escape rich text and reject unsafe URL schemes; report upstream HTTP/API failures without treating them as JSON syntax errors. Cache successful thread responses for 30 seconds and keep existing OAuth and post access checks. Adapt the converter and RTJSON renderer from polak14's a63460b implementation, without the unrelated dependency updates or Shreddit scraper fallback. Validation: nine GraphQL converter/request tests, cargo fmt and strict clippy; live anonymous GraphQL requests from the affected container validate sorts, focused comments, and cursor pagination. Co-authored-by: polak14 <76823966+polak14@users.noreply.github.com> [highda: resolved conflicts with the Tor commit in src/lib.rs, src/post.rs and templates/post.html] (cherry picked from commit d8824fa in redlib-org#603)
Reddit returns DEPENDENCY_FAILURE when PostComments combines an after cursor with focusedCommentContext. A cursor already identifies its subtree, so only send focused context for the initial permalink request. Cover this with request-variable tests and verify the failing nested cursor against the live API. (cherry picked from commit 6cd8366 in redlib-org#603)
Establishing a cold onion circuit can take longer than the 5 s authentication budget, so token requests over Tor timed out and retried. Allow 90 s in onion mode and keep the retry delay at 5 s. [highda: only the src/oauth.rs part of "fix: restore Reddit comments and onion API requests"; this fork takes the .json suffix fix from LucifersCircle and comments from upstream PR redlib-org#603 instead of the Shreddit scraper] (cherry picked from commit a86b3e037059553d08311000d77bf5b4512ecb06 in https://git.ptr.moe/baalajimaestro/redlib) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YTnpudqPXqMbtNkNsqFK8x
|
@nomadlogic Thanks for testing. Could you confirm the branch and commit you built? The fork's default To test the PR branch from a fresh checkout: git clone --single-branch --branch fix/graphql-comments https://github.com/fxmfxmfx/redlib.git redlib-graphql
cd redlib-graphql
git rev-parse --short HEAD
cargo run --locked --releaseThis revision was tested on the affected instance with post pages, focused comments/context, top-level pagination, and nested reply pagination. If the 403 persists on |
thanks! i missed that that this wasn't in the main branch. just tested again using the correct branch and can confirm it's working on my end. |
|
Thanks. It works well. |
|
compose file to build and run it: (pulls 3.8Gb of rust garbage) |
…raphQL Reddit answers anonymous comments JSON requests with an HTML 403, the encoded-slash workaround in v0.40.0 included. Taken from redlib-org#603 (fxmfxmfx/redlib fix/graphql-comments at 6cd8366) ahead of an upstream merge.
Comments are back on thread pages without a Reddit login. **Why:** since 2026-10-23 Reddit 403s the thread JSON routes for app-only tokens, and it has closed self-service API apps (Responsible Builder Policy), so logging in is not available. The Android app's persisted `PostComments` GraphQL query on gql-fed still answers our anonymous token: verified 2026-10-25 from the NAS (134 and 198 comments on two threads). **What** (a port of upstream PR redlib-org#603; converter and RTJSON renderer adapted from polak14's a63460b, attribution kept): - `gql_comments.rs` / `rtjson.rs`: pure request builder, comment-forest → JSON-API Listing converter, and the richtext renderer (`content.html` is always empty for this query). Only http(s) and local links survive `url_attr`. - `client::gql`: one pipeline with `fetch_json` (`fetch_reddit`), same JSON cache. GraphQL `errors` become an Err, so they are never cached. gql-fed meters the token on its own budget (599 vs 99), so its headers never overwrite the session's REST counter (tested). - `thread.rs`: the post from `/by_id/` plus the comments, concurrent when the sort is known. A comments failure logs a warn and renders the post alone with the notice. - `comments.rs`: comment building moved out of `post.rs`, which keeps its fan-out at 9. "More replies" links carry the cursor, depth-10 continuations read "Continue this thread", and a "More comments" link follows the first 200. - Maintenance point: `POST_COMMENTS_HASH`. When Reddit retires it, threads fall back to post-only and the log names the GraphQL error. Tests: 116 (+19 new), synthetic fixtures only; the converter was also checked against a captured real response (134 comments, 2 continuations). Docs: decisions.md, fork.md (new section; redlib-org#603 marked ported), AGENTS.md. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
fix: restore post comments through Reddit GraphQL
…/graphql-comments redlib 0.40.0 and restore post comments through Reddit GraphQL
|
Thanks! This fixed the issue on my local container, too. Apprecaite your efforts. |
…t (0.43.2) (#54) The first review of upstream's **open PRs** (commits are unchanged at `ba116c1`), and the review process now covers them: `make upstream-review` lists open upstream PRs updated after `.upstream-pr-rev`. Record: `docs/fork.md` "Reviews"; decision in `docs/decisions.md`. ## Ported | Upstream | Bug here | Fix | |---|---|---| | redlib-org#506 CMAF video | live: 29 of 30 recent v.redd.it posts rendered `<video src="">` | `/vid/<id>/{dash,cmaf}/<size>`; the old `/vid/<id>/<size>` stays for pages sw.js cached | | redlib-org#560 profile share links | `/u/<name>/s/<id>` answered "Nothing here" | one `post::share_redirect` for `/r/`, `/u/`, `/user/`; `canonical_target` now only follows a resolved `/comments/` path (an echoed share link would loop) | | redlib-org#521 default post sort | `REDLIB_DEFAULT_POST_SORT` ignored until settings saved | `subreddit::listing_sort`, also used by the RSS feed (the PR missed it) | | redlib-org#603 retry | a GraphQL 200 with `errors` (field timeout) hid comments | retried once; never for `PersistedQueryNotFound` | | redlib-org#568 (intent) | footer "Code" linked upstream | this fork at the running sha (`instance_info::source_url`) | | redlib-org#396 | `/commits.atom`, `/instances.json` could panic | removed; nothing used them | ## Found while checking against live threads - Taken-down comments (`authorInfo: null`) linked `u/[unknown]` → `[deleted]`. - Reddit's `isInitiallyCollapsed` was ignored → `collapsed` (admin takedowns, low score). - AMA `qa` sort was served but missing from the sort menu (showed "Confidence") → `Q&A` option. - Checked fine: giphy (an `external-preview.redd.it` image), emotes (plain text), comment media (images only). ## Skipped redlib-org#599 (HTML scrape, worse on every axis), redlib-org#549, redlib-org#542, redlib-org#520, redlib-org#194, redlib-org#413, redlib-org#596, redlib-org#561, redlib-org#577, and feature/build PRs. Reasons in `docs/fork.md`. ## Verification Local instance vs reddit.box: CMAF posts render `/vid/…/cmaf/…` → 206 video/mp4; DASH and the legacy route proxy; footer link; `qa` selected on two AMAs; three real `/r/…/s/…` links redirect; `/u/foo/s/abcdefgh` reaches the share handler; a CryptoCurrency daily shows 0 `[unknown]` (2 on reddit.box) and Reddit-collapsed comments closed. ci-quick, ci-unit (118), ci-metrics (coverage 47.8 → 48.72, tightened). Not in this PR: 19 new RUSTSEC advisories (13 in zstd crates, 0 high/critical) appeared in the advisory DB; a dependency PR follows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Since 2026-10-28 Reddit answers every anonymous JSON API request (listings, about, by_id, users, search) and /svc/shreddit/ with a 403 "blocked by network security" page. client::json now answers those paths from the Android app's persisted GraphQL operations (gql_feed.rs), converted to the old JSON, so handlers and templates stay unchanged: - Feeds: SubredditFeedElements, PopularFeedElements, AllFeedSdui; combined feeds (r/a+b, the subscriptions front page) merge per-subreddit feeds. - Posts: PostsByIds; videos from packaged MP4s with sound, proxied at /packaged/ and /packaged-external/. - Subreddit info (ban/private/gated/quarantine reasons), user info, posts and comments, post and subreddit search, wiki pages and duplicates. - GraphQL's own rate limit (600 per token) drives the token rollover. Comments take the fixes of redlib-org#603 (adapted from our a63460b): strict post paths, comment sort mapping and the post's suggested sort, ?context=N, no focused thread with a cursor, safer link URLs, escaped text when richtext is missing, comment ID checks and a request timeout. The same input checks apply to the new paths. The shreddit scraper fallback is gone.
Since 2026-10-28 Reddit answers every anonymous JSON API request (listings, about, by_id, users, search) and /svc/shreddit/ with a 403 "blocked by network security" page. client::json now answers those paths from the Android app's persisted GraphQL operations (gql_feed.rs), converted to the old JSON, so handlers and templates stay unchanged: - Feeds: SubredditFeedElements, PopularFeedElements, AllFeedSdui; combined feeds (r/a+b, the subscriptions front page) merge per-subreddit feeds. - Posts: PostsByIds; videos from packaged MP4s with sound, proxied at /packaged/ and /packaged-external/. - Subreddit info (ban/private/gated/quarantine reasons), user info, posts and comments, post and subreddit search, wiki pages and duplicates. - GraphQL's own rate limit (600 per token) drives the token rollover. Comments take the fixes of redlib-org#603 (adapted from our a63460b): strict post paths, comment sort mapping and the post's suggested sort, ?context=N, no focused thread with a cursor, safer link URLs, escaped text when richtext is missing, comment ID checks and a request timeout. The same input checks apply to the new paths. The shreddit scraper fallback is gone.
|
Update: Redlib is currently unusable because Reddit is blocking anonymous JSON API requests, so pages and listings no longer load. This PR only addresses comments and is no longer sufficient to restore Redlib on its own. polak14’s broader GraphQL patch aims to restore the affected endpoints and incorporates the comment fixes from this PR. |
FYI you can just switch to another TLS fingerprint, it'll work again (hi reddit employees 👋) |
Reddit's edge now answers most anonymous API requests with a 403 "blocked by network security" HTML page, which surfaced as "Failed to parse page JSON data: expected value at line 1 column 1" (redlib-org#608). - client: replace the Chrome145/Firefox147 TLS emulations, which Reddit now blocks outright, with OkHttp 4.9, Firefox Android 135 and Chrome 131 profiles that still get JSON. Shreddit fragments use Chrome 131/Windows. Log the chosen emulation. - client: when Reddit returns a non-JSON 403, start a new OAuth session (token and device ID) so a flagged session doesn't break the instance until restart. - user: /user/{name}/about.json is blocked, so build the profile from the user's hover card fragment (name, avatar, karma, cake day) and the profile subreddit's /r/u_{name}/about.json (title, description, banner, NSFW flag). Missing accounts are detected from the hover card. User post/comment listings still work through the JSON API (redlib-org#607). Comments come from the shreddit HTML loader merged from redlib-org#599. Fixes redlib-org#608 Refs redlib-org#607, redlib-org#598, redlib-org#600, redlib-org#602, redlib-org#599, redlib-org#603 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reddit's edge now answers most anonymous API requests with a 403 "blocked by network security" HTML page, which surfaced as "Failed to parse page JSON data: expected value at line 1 column 1" (redlib-org#608). - client: replace the Chrome145/Firefox147 TLS emulations, which Reddit now blocks outright, with OkHttp 4.9, Firefox Android 135 and Chrome 131 profiles that still get JSON. Shreddit fragments use Chrome 131/Windows. Log the chosen emulation. - client: when Reddit returns a non-JSON 403, start a new OAuth session (token and device ID) so a flagged session doesn't break the instance until restart. - user: /user/{name}/about.json is blocked, so build the profile from the user's hover card fragment (name, avatar, karma, cake day) and the profile subreddit's /r/u_{name}/about.json (title, description, banner, NSFW flag). Missing accounts are detected from the hover card. User post/comment listings still work through the JSON API (redlib-org#607). Comments come from the shreddit HTML loader merged from redlib-org#599. Fixes redlib-org#608 Refs redlib-org#607, redlib-org#598, redlib-org#600, redlib-org#602, redlib-org#599, redlib-org#603 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since 2026-10-28 Reddit answers every anonymous JSON API request (listings, about, by_id, users, search) and /svc/shreddit/ with a 403 "blocked by network security" page. client::json now answers those paths from the Android app's persisted GraphQL operations (gql_feed.rs), converted to the old JSON, so handlers and templates stay unchanged: - Feeds: SubredditFeedElements, PopularFeedElements, AllFeedSdui; combined feeds (r/a+b, the subscriptions front page) merge per-subreddit feeds. - Posts: PostsByIds; videos from packaged MP4s with sound, proxied at /packaged/ and /packaged-external/. - Subreddit info (ban/private/gated/quarantine reasons), user info, posts and comments, post and subreddit search, wiki pages and duplicates. - GraphQL's own rate limit (600 per token) drives the token rollover. Comments take the fixes of redlib-org#603 (adapted from our a63460b): strict post paths, comment sort mapping and the post's suggested sort, ?context=N, no focused thread with a cursor, safer link URLs, escaped text when richtext is missing, comment ID checks and a request timeout. The same input checks apply to the new paths. The shreddit scraper fallback is gone.
Reddit now returns 403 for thread pages requested with anonymous tokens, including the %2f workaround. Port upstream PR redlib-org#603 (redlib-org/redlib): the post still comes from /by_id, and comments from the PostComments query the Android app uses, converted to the usual listing shape. Adjustments: dates parsed with `time` instead of adding chrono, a smaller cache (32 threads) for the Pi, the existing inline "More replies" links kept, and a "More comments" link for the next page of top-level comments. The JSON endpoint is still used when a script app is configured. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Reddit now responds to anonymous comments JSON requests with an HTML 403, including the encoded-slash workaround. This makes every post page fail with “Failed to parse page JSON data”, while subreddit listings still work.
This change fetches post metadata through
/by_idand loads comments using Android'sPostCommentspersisted GraphQL operation with the existing anonymous OAuth client. The converter preserves the two-Listing shape consumed bypost.rs, including rich text, flair, moderation flags, scores, replies, and focused comment context. Cursor links paginate both top-level comments and nested replies without an account or new configuration.The converter and RTJSON renderer are adapted from polak14's implementation, with attribution retained. This patch keeps the current dependencies and Rust version, omits the Shreddit scraper fallback, and adds strict path/sort/cursor handling, safe HTML URLs, explicit HTTP/API errors, and focused-context pruning. In particular, nested cursors must not be combined with
focusedCommentContext: Reddit returnsDEPENDENCY_FAILUREfor that combination.Validation:
cargo fmt --all -- --check,cargo clippy --locked --all-targets -- -D warnings, and release build passed./r/gonwildfetching test with a Reddit transport error; 47 tests passed in that run.Limits: each GraphQL request returns up to 200 comments at 10 levels of depth; continuation links load further comments/replies. Reddit's persisted operation hash and API behavior are external dependencies.
Related: #591, #602.