decode reads a body applying its Content-Transfer-Encoding (base64 / quoted-printable / identity).
(body io.Reader, cte string)
| 186 | // decode reads a body applying its Content-Transfer-Encoding (base64 / |
| 187 | // quoted-printable / identity). |
| 188 | func decode(body io.Reader, cte string) string { |
| 189 | switch strings.ToLower(strings.TrimSpace(cte)) { |
| 190 | case "quoted-printable": |
| 191 | b, _ := io.ReadAll(quotedprintable.NewReader(body)) |
| 192 | return string(b) |
| 193 | case "base64": |
| 194 | raw, _ := io.ReadAll(body) |
| 195 | // base64 bodies are line-wrapped; strip all whitespace then decode. |
| 196 | clean := strings.Map(func(r rune) rune { |
| 197 | if r == '\r' || r == '\n' || r == ' ' || r == '\t' { |
| 198 | return -1 |
| 199 | } |
| 200 | return r |
| 201 | }, string(raw)) |
| 202 | dec, err := base64.StdEncoding.DecodeString(clean) |
| 203 | if err != nil { |
| 204 | return string(raw) |
| 205 | } |
| 206 | return string(dec) |
| 207 | default: |
| 208 | b, _ := io.ReadAll(body) |
| 209 | return string(b) |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | // htmlToText renders HTML to plain text: drops script/style, inserts newlines |
| 214 | // at block boundaries, and decodes entities (via the tokenizer). |