缓存命中改写信封时补 UnmarshalJSON,避免 results 被抹空;零结果不进 300s 缓存。模版层对 SearXNG hits 做广告标记丢弃与同域限额 1 条,减轻 1688 霸屏。 Co-authored-by: Cursor <cursoragent@cursor.com>
78 lines
1.8 KiB
Go
78 lines
1.8 KiB
Go
// Package contract 内部 JSON 序列化辅助(与契约逻辑分离,保持 contract.go 职责单一)。
|
||
package contract
|
||
|
||
import "encoding/json"
|
||
|
||
// jsonMarshal 统一带缩进关闭的紧凑序列化(HTML 转义开启与标准库默认一致)。
|
||
func jsonMarshal(v any) ([]byte, error) {
|
||
return json.Marshal(v)
|
||
}
|
||
|
||
// UnmarshalJSON 从平铺 wire 还原 Data。缺此方法时 encoding/json 只填顶层字段,
|
||
// Data 恒为 nil;再 Marshal 会丢掉 results/markdown(gateway 缓存命中改写即踩中)。
|
||
func (e *Envelope) UnmarshalJSON(b []byte) error {
|
||
var top envelopeTop
|
||
if err := json.Unmarshal(b, &top); err != nil {
|
||
return err
|
||
}
|
||
e.OK = top.OK
|
||
e.Kind = top.Kind
|
||
e.RequestID = top.RequestID
|
||
e.TookMs = top.TookMs
|
||
e.Usage = top.Usage
|
||
e.Provenance = top.Provenance
|
||
e.Error = top.Error
|
||
switch top.Kind {
|
||
case "search":
|
||
var w searchWire
|
||
if err := json.Unmarshal(b, &w); err != nil {
|
||
return err
|
||
}
|
||
p := &SearchPayload{Query: w.Query, Answer: w.Answer, Results: w.Results}
|
||
p.EnsureEmptySlice()
|
||
e.Data = p
|
||
case "read":
|
||
var w readWire
|
||
if err := json.Unmarshal(b, &w); err != nil {
|
||
return err
|
||
}
|
||
p := readPayloadFromWire(w)
|
||
p.EnsureEmptySlice()
|
||
e.Data = p
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func readPayloadFromWire(w readWire) *ReadPayload {
|
||
p := &ReadPayload{
|
||
Description: w.Description,
|
||
HTML: w.HTML,
|
||
ScreenshotURL: w.ScreenshotURL,
|
||
Extracted: w.Extracted,
|
||
Links: w.Links,
|
||
Images: w.Images,
|
||
Warnings: w.Warnings,
|
||
}
|
||
if w.URL != nil {
|
||
p.URL = *w.URL
|
||
}
|
||
if w.FinalURL != nil {
|
||
p.FinalURL = *w.FinalURL
|
||
}
|
||
if w.Title != nil {
|
||
p.Title = *w.Title
|
||
}
|
||
if w.Markdown != nil {
|
||
p.Markdown = *w.Markdown
|
||
}
|
||
if w.Truncated != nil {
|
||
p.Truncated = *w.Truncated
|
||
}
|
||
if w.CharCount != nil {
|
||
p.CharCount = *w.CharCount
|
||
}
|
||
if w.Metadata != nil {
|
||
p.Metadata = *w.Metadata
|
||
}
|
||
return p
|
||
}
|