Request log: write & < > as sent (closes #327) #329

Merged
clawbot merged 1 commits from issue-327-request-log-ampersand into next 2026-11-11 07:50:55 +01:00
2 changed files with 48 additions and 3 deletions

No files matched your search

+10 -3
View File
@@ -5,6 +5,7 @@
package requestlog
import (
"bytes"
"encoding/json"
"fmt"
"io"
@@ -252,14 +253,20 @@ func WriteRProxyLine(w io.Writer, line *RProxyLine) error {
return writeJSONLine(w, line)
}
// writeJSONLine writes line to w as one JSON line.
// writeJSONLine writes line to w as one JSON line. It writes "&", "<" and
// ">" as they are, so a query string reads as it was sent.
func writeJSONLine(w io.Writer, line any) error {
encoded, err := json.Marshal(line)
var encoded bytes.Buffer
encoder := json.NewEncoder(&encoded)
encoder.SetEscapeHTML(false)
err := encoder.Encode(line)
if err != nil {
return fmt.Errorf("encode the request log line: %w", err)
}
_, err = w.Write(append(encoded, '\n'))
_, err = w.Write(encoded.Bytes())
if err != nil {
return fmt.Errorf("write the request log line: %w", err)
}
+38
View File
@@ -67,6 +67,44 @@ func TestWriteWritesOneJSONLineMarkedRequest(t *testing.T) {
}
}
func TestRequestLinesHoldTheQueryAndRefererAsSent(t *testing.T) {
t.Parallel()
var out bytes.Buffer
err := requestlog.Write(&out, &requestlog.Line{
Query: "a=1&b=<2>",
Referer: "https://example.com/?x=1&y=<2>",
})
if err != nil {
t.Fatalf("write: %v", err)
}
err = requestlog.WriteRProxyLine(&out, &requestlog.RProxyLine{Query: "a=1&b=<2>"})
if err != nil {
t.Fatalf("write the rproxy line: %v", err)
}
lines := strings.Split(strings.TrimSuffix(out.String(), "\n"), "\n")
if len(lines) != 2 {
t.Fatalf("wrote %q, want two lines", out.String())
}
for _, line := range lines {
if !json.Valid([]byte(line)) {
t.Errorf("%s is not valid JSON", line)
}
if !strings.Contains(line, `"query":"a=1&b=<2>"`) {
t.Errorf("%s does not hold the query as sent", line)
}
}
if !strings.Contains(lines[0], `"referer":"https://example.com/?x=1&y=<2>"`) {
t.Errorf("%s does not hold the referer as sent", lines[0])
}
}
func TestWriteRProxyLineWritesOneJSONLineWithOnlyItsFields(t *testing.T) {
t.Parallel()