Commit 8568e930 authored by Geoff Simmons's avatar Geoff Simmons

Record payloads are byte slices.

parent 8713019a
......@@ -194,7 +194,7 @@ func (c *Cursor) Record() Record {
rec := Record{
Tag: c.cursor.rec.tag(),
VXID: uint(c.cursor.rec.vxid()),
Payload: string(c.cursor.rec.payload()),
Payload: Payload(c.cursor.rec.payload()),
}
switch {
case c.cursor.rec.backend():
......
......@@ -301,6 +301,18 @@ func (tag Tag) Nonprintable() bool {
return C.nonprintable(uint32(tag)) != 0
}
// Payload is the type of the message contained in a Record -- the
// specific data for the record.
//
// A Payload is just a byte slice, so it is easily converted to a
// string (and otherwise manipulated).
type Payload []byte
// String returns a payload as a string.
func (p Payload) String() string {
return string(p)
}
// A Record in the Varnish log, corresponding to a line of output from
// the varnishlog utility. Instances of this type are returned for log
// reads, possibly aggregated into transactions (the Tx type), and
......@@ -328,10 +340,11 @@ type Record struct {
// payload appears after the second column of default
// varnishlog output.
//
// Unprintable bytes in the payload are rendered with the "%q"
// verb for package fmt: "\xXX", where XX is the hex value of
// the byte.
Payload string
// If Nonprintable() is true for the tag in this record, then
// the payload may contain nonprintable characters. Otherwise
// it contains only printable ASCII characters (which is the
// case for most records).
Payload Payload
}
// A Tx for "transaction" is a collection of related log records,
......
......@@ -178,9 +178,9 @@ func checkRecord(t *testing.T, rec Record, expRec testRec) {
t.Errorf("rec payload length expected=%v got=%v",
len(expRec.payload), len(rec.Payload))
}
if rec.Payload != expRec.payload {
if string(rec.Payload) != expRec.payload {
t.Errorf("rec payload expected='%v' got='%v'", expRec.payload,
rec.Payload)
string(rec.Payload))
}
}
......@@ -252,9 +252,9 @@ func checkBereq(t *testing.T, tx Tx, req http.Request) {
if rec.Tag.String() != "BereqURL" {
continue
}
if rec.Payload != req.URL.Path {
if string(rec.Payload) != req.URL.Path {
t.Errorf("bereq URL want=%v got=%v", req.URL.Path,
rec.Payload)
string(rec.Payload))
}
break
}
......@@ -270,56 +270,56 @@ func checkReqResp(t *testing.T, tx Tx, req http.Request, resp http.Response) {
for _, rec := range tx.Records {
switch rec.Tag.String() {
case "ReqMethod":
if rec.Payload != req.Method {
if string(rec.Payload) != req.Method {
t.Errorf("request method want=%v got=%v",
req.Method, rec.Payload)
req.Method, string(rec.Payload))
}
case "ReqURL":
if rec.Payload != req.URL.Path {
if string(rec.Payload) != req.URL.Path {
t.Errorf("request URL want=%v got=%v",
req.URL.Path, rec.Payload)
req.URL.Path, string(rec.Payload))
}
case "ReqProtocol":
if rec.Payload != req.Proto {
if string(rec.Payload) != req.Proto {
t.Errorf("request protocol want=%v got=%v",
req.Proto, rec.Payload)
req.Proto, string(rec.Payload))
}
case "ReqHeader":
if !strings.HasPrefix(rec.Payload, "Host:") {
if !strings.HasPrefix(string(rec.Payload), "Host:") {
continue
}
host := rec.Payload[len("Host: "):]
host := string(rec.Payload)[len("Host: "):]
if host != req.Host {
t.Errorf("request Host want=%v got=%v",
req.Host, host)
}
case "RespProtocol":
if rec.Payload != resp.Proto {
if string(rec.Payload) != resp.Proto {
t.Errorf("response protocol want=%v got=%v",
resp.Proto, rec.Payload)
resp.Proto, string(rec.Payload))
}
case "RespStatus":
expStatus := strconv.FormatInt(int64(resp.StatusCode),
10)
if rec.Payload != expStatus {
if string(rec.Payload) != expStatus {
t.Errorf("response status want=%d got=%v",
resp.StatusCode, rec.Payload)
resp.StatusCode, string(rec.Payload))
}
case "RespReason":
expReason := resp.Status[4:]
if rec.Payload != expReason {
if string(rec.Payload) != expReason {
t.Errorf("response reason want=%v got=%v",
expReason, rec.Payload)
expReason, string(rec.Payload))
}
case "RespHeader":
colonIdx := strings.Index(rec.Payload, ": ")
colonIdx := strings.Index(string(rec.Payload), ": ")
if colonIdx < 0 {
t.Fatal("cannot parse response header:",
rec.Payload)
string(rec.Payload))
continue
}
hdr := rec.Payload[:colonIdx]
val := rec.Payload[colonIdx+2:]
hdr := string(rec.Payload)[:colonIdx]
val := string(rec.Payload)[colonIdx+2:]
respHdr.Set(hdr, val)
default:
continue
......
......@@ -36,11 +36,13 @@ package log
import "C"
import (
"bytes"
"errors"
"strconv"
"strings"
)
var spaceByte = []byte(" ")
// A Query provides the means to read aggregated transactions from the
// log. A Query must be created from a Cursor using the NewQuery
// function.
......@@ -140,14 +142,17 @@ func (q *Query) NextTxGroup() ([]Tx, Status) {
Records: []Record{rec},
}
if rec.Tag == Tag(C.SLT_Begin) {
begin := strings.Split(rec.Payload, " ")
if txtype, exists := str2type[begin[0]]; exists {
begin := bytes.Split(rec.Payload, spaceByte)
typeFromRec := string(begin[0])
if txtype, exists := str2type[typeFromRec]; exists {
tx.Type = txtype
}
if pvxid, err := strconv.Atoi(begin[1]); err != nil {
vxid := string(begin[1])
if pvxid, err := strconv.Atoi(vxid); err != nil {
tx.ParentVXID = uint32(pvxid)
}
if reason, exists := str2reason[begin[2]]; exists {
recReason := string(begin[2])
if reason, exists := str2reason[recReason]; exists {
tx.Reason = reason
}
}
......
......@@ -150,7 +150,8 @@ func checkRec(t *testing.T, rec Record, expRec expRec) {
if expRec.tag != recTagUndef && rec.Tag.String() != expRec.tag {
t.Errorf("record tag want=%v got=%s", expRec.tag, rec.Tag)
}
if expRec.payload != recPayloadUndef && rec.Payload != expRec.payload {
if expRec.payload != recPayloadUndef &&
string(rec.Payload) != expRec.payload {
t.Errorf("record payload want=%v got=%s", expRec.payload,
rec.Payload)
}
......@@ -203,7 +204,7 @@ func checkTx(t *testing.T, tx Tx, expTxLen expTxLen) {
t.Errorf("tx last record tag want=End got=%s",
tx.Records[lastIdx].Tag)
}
if tx.Records[lastIdx].Payload != "" {
if string(tx.Records[lastIdx].Payload) != "" {
t.Errorf("tx last record tag want=%q got=%q", "",
tx.Records[lastIdx].Payload)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment