When gateway/WAF/CDN middleware implements keyword matching, avoid pure substring matching causing normal response content to be misjudged.
Core Problem
Misjudgment of Pure Substring Matching
// ❌ 误判:纯子串匹配,长正文中的正常用词也会命中
var pseudoSuccessPatterns = []string{
"cloudflare",
"502 bad gateway",
"bad gateway",
"reconnecting",
"upstream error",
}
When the business response body contains theliteral valueof these keywords (for example, the article topic is exactly "Cloudflare"), pure substring matching will trigger a misjudgment, resulting in:
- Normal responses being treated as false-success errors
- Triggering site switching / upstream degradation
- Incorrectly marking models/nodes as unavailable
Key fact: a keyword appearing in a long body ≠ the response has a problem.
Solution: Strong/Weak Feature Splitting + Layered Determination
Split keywords into two groups by risk characteristics, and combine with HTTP metadata for layered determination:
Layered Determination Principles (Recommended)
Before using body keyword matching, first exclude the vast majority of normal responses through HTTP metadata:
| Determination Layer | Check Item | Priority |
|---|---|---|
| 1. HTTP status | 2xx=normal, 5xx/429/some403=error |
Highest |
| 2. Content-Type | text/event-stream keep streaming processing, application/json check schema |
↑ |
| 3. Response schema / error fields | In JSON, error.code / error.message / success:false etc. |
↑ |
| 4. Body keyword matching | Strong/weak features, only asheuristic evidence, not as the sole fact | Lowest |
Body keywords are only heuristic evidence: normal user content may contain the literal values of technical terms (such as Cloudflare, 502, bad gateway); a keyword hit does not necessarily mean the response is erroneous, and must be comprehensively judged in combination with status/schema.
Strong Features (hit at any length)
Complete error statements or HTML error page features.These patterns are extremely long and have special content, and are almost impossible to appear in normal user content, and can be hit at any length:
| Feature | Description |
|---|---|
exceeded retry limit, last status: 429 too many requests |
Complete 429 error sentence |
must be enabled in your dashboard first |
Complete dashboard guidance sentence |
unexpected status 502 bad gateway: error code: 502 |
Complete 502 error sentence (including UUID) |
<html / <title>5 / cf-ray: |
HTML error page feature |
var pseudoSuccessChatStrongPatterns = []string{
"exceeded retry limit, last status: 429 too many requests",
"must be enabled in your dashboard first",
"unexpected status 502 bad gateway: error code: 502",
"reconnecting...",
"<html",
"<title>5",
"cf-ray:",
}
Weak Features (only hit in ≤512-byte content)
Word-level or phrase-level keywords.Only a hit in extremely short content (≤512 bytes) is judged as an error, to avoid misjudging technical terms in long bodies:
| Feature | Description |
|---|---|
429 too many requests |
Short version 429 |
502 bad gateway / bad gateway |
Short version 502 |
upstream error / upstream connect error |
Upstream error |
just a moment |
CDN challenge |
cloudflare |
CDN brand name |
must be enabled in your dashboard first |
Short version guidance sentence |
var pseudoSuccessChatWeakPatterns = []string{
"429 too many requests",
"502 bad gateway",
"bad gateway",
"upstream error",
"upstream connect error",
"just a moment",
"cloudflare",
"must be enabled in your dashboard first",
}
Determination Logic
func containsPseudoSuccessInChatResponse(content string) bool {
// 先检查 HTTP status 和响应 schema(应有上层调用保证)
// 正文关键词仅作为启发式证据
// 强特征:任何长度命中
for _, p := range pseudoSuccessChatStrongPatterns {
if strings.Contains(strings.ToLower(content), p) {
return true
}
}
// 弱特征:仅 ≤512 字节命中
if len(content) > 512 {
return false
}
low := strings.ToLower(content)
for _, p := range pseudoSuccessChatWeakPatterns {
if strings.Contains(low, p) {
return true
}
}
return false
}
Matching Strategies for Different Scenarios
| Scenario | Strategy | Reason |
|---|---|---|
| Chat response body(long text) | Strong features at any length + weak features only when hit in ≤512 bytes | The body may contain literal technical terms |
| Error message(short text) | Full match, no length limit needed | The error message itself is very short and does not contain normal user content |
| Streaming response chunk(chunked) | Implement with reference to the HTTP streaming classification target | Wait for the complete chunk before matching, or split by content format before matching |
Implicit defect determination
When implementing keyword matching, self-check with the following questions:
- Is the matched keyword likely to appear in normal user content??
- If it appears, is it handled according tobody lengthwith tiering?
- When the same keyword appears in a short error message vs. a long normal article, is the determination logic different?
- Is there regression test coverage for thelong-body false positivescenario?
Self-test cases:
| Content | Length | Correct determination | Description |
|---|---|---|---|
"exceeded retry limit, last status: 429 too many requests" |
Short | Error | Strong feature hit |
"Cloudflare(文章主题)..." + 4657-character body |
Long | Normal | Weak feature + extra long → no hit |
"502 Bad Gateway"(pure error) |
Short | Error | Weak feature + short → hit |
"502 Bad Gateway: 配置 Nginx 反向代理时..." + complete blog |
Long | Normal | Weak feature + extra long → no hit, no strong feature |
Boundaries with related skills
| skill | Relationship |
|---|---|
external-system-debugging |
This skill'supstream: When facing abnormal CDN/WAF gateway behavior, first use the external system methodology to capture real data, then come back to check whether the matching logic implementation is correct |
api-design-safety |
This skill focuses onthe security matching implementation of proxy middleware, not the design specification of the API itself |
ops-safety |
This skill does not involve operations security, dangerous commands, etc. |
Rule provenance
> 📋 本回复遵循:`api-proxy-safety` - [章节]