[PR #31728] fix: fix http node content decode #33374

Open
opened 2026-02-21 20:53:10 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langgenius/dify/pull/31728

State: open
Merged: No


Important

  1. Make sure you have read our contribution guidelines
  2. Ensure there is an associated issue and you have been assigned to it
  3. Use the correct syntax to link this PR: Fixes #<issue number>.

Summary

fix #31695

because cp949 and gbk structural overlap

  • The trailing byte range of GBK is quite broad: 0x40 - 0xFE (excluding 0x7F).
  • CP949 also has a very wide trailing byte range: 0x41 - 0xFE (excluding 0x7F).

so use the charset_normalizer may detect chinese as korean, the output will be wrong

when httpx response has charset, use the origin httpx response content, if it missing, use charset_normalizer to guess the encoding.

Candidate List and Orthogonal Evaluation
define a clear list of candidates with corresponding scoring functions, then perform "orthogonal evaluation" on them (scoring each independently before comparing), thereby avoiding reliance on any specific trial order.
Bonus Points for CP949

if encoding == "cp949" and score > 0:
    score += 3

This is an interesting heuristic adjustment. The logic is: "If the original detector believes it's CP949 and it passes the round-trip test (score > 0), we give it a slight preference, respecting the original detector's judgment." This helps maintain stability when both encodings are genuinely valid (an extremely rare occurrence). While the number 3 is an empirical value, it causes no harm since character-count differences are typically large.
Dynamic Threshold

threshold = max(2, min(8, text_length // 10))

This dynamic threshold is ingeniously designed. For very short text, it requires at least 2 matching characters; for longer text, it demands more matches, but caps the requirement at 8. This prevents incorrect judgments in long texts based solely on one or two accidental matches.

Screenshots

Before After
... ...

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran make lint and make type-check (backend) and cd web && npx lint-staged (frontend) to appease the lint gods
**Original Pull Request:** https://github.com/langgenius/dify/pull/31728 **State:** open **Merged:** No --- > [!IMPORTANT] > > 1. Make sure you have read our [contribution guidelines](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) > 1. Ensure there is an associated issue and you have been assigned to it > 1. Use the correct syntax to link this PR: `Fixes #<issue number>`. ## Summary fix #31695 because cp949 and gbk structural overlap - The trailing byte range of GBK is quite broad: 0x40 - 0xFE (excluding 0x7F). - CP949 also has a very wide trailing byte range: 0x41 - 0xFE (excluding 0x7F). so use the charset_normalizer may detect chinese as korean, the output will be wrong when httpx response has charset, use the origin httpx response content, if it missing, use charset_normalizer to guess the encoding. Candidate List and Orthogonal Evaluation define a clear list of candidates with corresponding scoring functions, then perform "orthogonal evaluation" on them (scoring each independently before comparing), thereby avoiding reliance on any specific trial order. Bonus Points for CP949 ``` if encoding == "cp949" and score > 0: score += 3 ``` This is an interesting heuristic adjustment. The logic is: "If the original detector believes it's CP949 and it passes the round-trip test (score > 0), we give it a slight preference, respecting the original detector's judgment." This helps maintain stability when both encodings are genuinely valid (an extremely rare occurrence). While the number 3 is an empirical value, it causes no harm since character-count differences are typically large. Dynamic Threshold ``` threshold = max(2, min(8, text_length // 10)) ``` This dynamic threshold is ingeniously designed. For very short text, it requires at least 2 matching characters; for longer text, it demands more matches, but caps the requirement at 8. This prevents incorrect judgments in long texts based solely on one or two accidental matches. ## Screenshots | Before | After | |--------|-------| | ... | ... | ## Checklist - [ ] This change requires a documentation update, included: [Dify Document](https://github.com/langgenius/dify-docs) - [x] I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!) - [x] I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change. - [x] I've updated the documentation accordingly. - [x] I ran `make lint` and `make type-check` (backend) and `cd web && npx lint-staged` (frontend) to appease the lint gods
yindo added the pull-request label 2026-02-21 20:53:10 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#33374