Skip to content

Commit

Permalink
guard debug statements in http module
Browse files Browse the repository at this point in the history
guard debug statements so no additional memory allocation happen for supressed
debugging output.
  • Loading branch information
urso committed Dec 8, 2015
1 parent c252fc2 commit 9e16878
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 30 deletions.
66 changes: 52 additions & 14 deletions packetbeat/protos/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ type HTTP struct {
results publisher.Client
}

var (
isDebug = false
isDetailed = false
)

func (http *HTTP) initDefaults() {
http.SendRequest = false
http.SendResponse = false
Expand Down Expand Up @@ -138,6 +143,9 @@ func (http *HTTP) Init(testMode bool, results publisher.Client) error {
}
}

isDebug = logp.IsDebug("http")
isDetailed = logp.IsDebug("httpdetailed")

http.results = results

return nil
Expand All @@ -154,7 +162,10 @@ func (http *HTTP) messageGap(s *stream, nbytes int) (ok bool, complete bool) {
// we know we cannot recover from these
return false, false
case stateBody:
debugf("gap in body: %d", nbytes)
if isDebug {
debugf("gap in body: %d", nbytes)
}

if m.IsRequest {
m.Notes = append(m.Notes, "Packet loss while capturing the request")
} else {
Expand Down Expand Up @@ -256,7 +267,9 @@ func (http *HTTP) doParse(
dir uint8,
) *httpConnectionData {

detailedf("Payload received: [%s]", pkt.Payload)
if isDetailed {
detailedf("Payload received: [%s]", pkt.Payload)
}

st := conn.Streams[dir]
if st == nil {
Expand All @@ -266,7 +279,9 @@ func (http *HTTP) doParse(
// concatenate bytes
st.data = append(st.data, pkt.Payload...)
if len(st.data) > tcp.TCP_MAX_DATA_IN_STREAM {
debugf("Stream data too large, dropping TCP stream")
if isDebug {
debugf("Stream data too large, dropping TCP stream")
}
conn.Streams[dir] = nil
return conn
}
Expand Down Expand Up @@ -355,7 +370,9 @@ func (http *HTTP) GapInStream(tcptuple *common.TcpTuple, dir uint8,
}

ok, complete := http.messageGap(stream, nbytes)
detailedf("messageGap returned ok=%v complete=%v", ok, complete)
if isDetailed {
detailedf("messageGap returned ok=%v complete=%v", ok, complete)
}
if !ok {
// on errors, drop stream
conn.Streams[dir] = nil
Expand Down Expand Up @@ -384,10 +401,14 @@ func (http *HTTP) handleHTTP(
http.hideHeaders(m)

if m.IsRequest {
debugf("Received request with tuple: %s", m.TCPTuple)
if isDebug {
debugf("Received request with tuple: %s", m.TCPTuple)
}
conn.requests.append(m)
} else {
debugf("Received response with tuple: %s", m.TCPTuple)
if isDebug {
debugf("Received response with tuple: %s", m.TCPTuple)
}
conn.responses.append(m)
http.correlate(conn)
}
Expand All @@ -409,7 +430,9 @@ func (http *HTTP) correlate(conn *httpConnectionData) {
resp := conn.responses.pop()
trans := http.newTransaction(requ, resp)

debugf("HTTP transaction completed")
if isDebug {
debugf("HTTP transaction completed")
}
http.publishTransaction(trans)
}
}
Expand Down Expand Up @@ -546,7 +569,9 @@ func (http *HTTP) cutMessageBody(m *message) []byte {
if len(m.chunkedBody) > 0 {
cutMsg = append(cutMsg, m.chunkedBody...)
} else {
debugf("Body to include: [%s]", m.Raw[m.bodyOffset:])
if isDebug {
debugf("Body to include: [%s]", m.Raw[m.bodyOffset:])
}
cutMsg = append(cutMsg, m.Raw[m.bodyOffset:]...)
}
}
Expand All @@ -558,12 +583,16 @@ func (http *HTTP) shouldIncludeInBody(contenttype []byte) bool {
includedBodies := config.ConfigSingleton.Protocols.Http.Include_body_for
for _, include := range includedBodies {
if bytes.Contains(contenttype, []byte(include)) {
debugf("Should Include Body = true Content-Type %s include_body %s",
contenttype, include)
if isDebug {
debugf("Should Include Body = true Content-Type %s include_body %s",
contenttype, include)
}
return true
}
debugf("Should Include Body = false Content-Type %s include_body %s",
contenttype, include)
if isDebug {
debugf("Should Include Body = false Content-Type %s include_body %s",
contenttype, include)
}
}
return false
}
Expand All @@ -584,7 +613,10 @@ func (http *HTTP) hideHeaders(m *message) {
authHeaderEndX := m.bodyOffset

for authHeaderStartX < m.bodyOffset {
debugf("looking for authorization from %d to %d", authHeaderStartX, authHeaderEndX)
if isDebug {
debugf("looking for authorization from %d to %d",
authHeaderStartX, authHeaderEndX)
}

startOfHeader := bytes.Index(msg[authHeaderStartX:m.bodyOffset], authText)
if startOfHeader >= 0 {
Expand All @@ -598,7 +630,9 @@ func (http *HTTP) hideHeaders(m *message) {
authHeaderEndX = m.bodyOffset
}

debugf("Redact authorization from %d to %d", authHeaderStartX, authHeaderEndX)
if isDebug {
debugf("Redact authorization from %d to %d", authHeaderStartX, authHeaderEndX)
}

for i := authHeaderStartX + len(authText); i < authHeaderEndX; i++ {
msg[i] = byte('*')
Expand Down Expand Up @@ -659,6 +693,10 @@ func (http *HTTP) extractParameters(m *message, msg []byte) (path string, params
}
params = paramsMap.Encode()

if isDetailed {
detailedf("Parameters: %s", params)
}

return
}

Expand Down
71 changes: 55 additions & 16 deletions packetbeat/protos/http/http_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ type parserConfig struct {
var (
transferEncodingChunked = []byte("chunked")

constCRLF = []byte("\r\n")

constClose = []byte("close")
constKeepAlive = []byte("keep-alive")

Expand Down Expand Up @@ -129,7 +131,9 @@ func (*parser) parseHTTPLine(s *stream, m *message) (cont, ok, complete bool) {
var err error
fline := s.data[s.parseOffset:i]
if len(fline) < 8 {
debugf("First line too small")
if isDebug {
debugf("First line too small")
}
return false, false, false
}
if bytes.Equal(fline[0:5], []byte("HTTP/")) {
Expand All @@ -141,11 +145,17 @@ func (*parser) parseHTTPLine(s *stream, m *message) (cont, ok, complete bool) {
logp.Warn("Failed to understand HTTP response status: %s", fline[9:])
return false, false, false
}

if isDebug {
debugf("HTTP status_code=%d, status_phrase=%s", m.StatusCode, m.StatusPhrase)
}
} else {
// REQUEST
slices := bytes.Fields(fline)
if len(slices) != 3 {
debugf("Couldn't understand HTTP request: %s", fline)
if isDebug {
debugf("Couldn't understand HTTP request: %s", fline)
}
return false, false, false
}

Expand All @@ -156,17 +166,24 @@ func (*parser) parseHTTPLine(s *stream, m *message) (cont, ok, complete bool) {
m.IsRequest = true
version = slices[2][5:]
} else {
debugf("Couldn't understand HTTP version: %s", fline)
if isDebug {
debugf("Couldn't understand HTTP version: %s", fline)
}
return false, false, false
}
}

m.version.major, m.version.minor, err = parseVersion(version)
if err != nil {
debugf("Failed to understand HTTP version: %v", version)
if isDebug {
debugf("Failed to understand HTTP version: %v", version)
}
m.version.major = 1
m.version.minor = 0
}
if isDebug {
debugf("HTTP version %d.%d", m.version.major, m.version.minor)
}

// ok so far
s.parseOffset = i + 2
Expand All @@ -177,6 +194,10 @@ func (*parser) parseHTTPLine(s *stream, m *message) (cont, ok, complete bool) {
}

func parseResponseStatus(s []byte) (uint16, []byte, error) {
if isDebug {
debugf("parseResponseStatus: %s", s)
}

p := bytes.IndexByte(s, ' ')
if p == -1 {
return 0, nil, errors.New("Not beeing able to identify status code")
Expand Down Expand Up @@ -215,7 +236,9 @@ func (parser *parser) parseHeaders(s *stream, m *message) (cont, ok, complete bo
if !m.IsRequest && ((100 <= m.StatusCode && m.StatusCode < 200) || m.StatusCode == 204 || m.StatusCode == 304) {
//response with a 1xx, 204 , or 304 status code is always terminated
// by the first empty line after the header fields
debugf("Terminate response, status code %d", m.StatusCode)
if isDebug {
debugf("Terminate response, status code %d", m.StatusCode)
}
m.end = s.parseOffset
m.Size = uint64(m.end - m.start)
return false, true, true
Expand All @@ -224,20 +247,26 @@ func (parser *parser) parseHeaders(s *stream, m *message) (cont, ok, complete bo
if bytes.Equal(m.TransferEncoding, transferEncodingChunked) {
// support for HTTP/1.1 Chunked transfer
// Transfer-Encoding overrides the Content-Length
debugf("Read chunked body")
if isDebug {
debugf("Read chunked body")
}
s.parseState = stateBodyChunkedStart
return true, true, true
}

if m.ContentLength == 0 && (m.IsRequest || m.hasContentLength) {
debugf("Empty content length, ignore body")
if isDebug {
debugf("Empty content length, ignore body")
}
// Ignore body for request that contains a message body but not a Content-Length
m.end = s.parseOffset
m.Size = uint64(m.end - m.start)
return false, true, true
}

debugf("Read body")
if isDebug {
debugf("Read body")
}
s.parseState = stateBody
} else {
ok, hfcomplete, offset := parser.parseHeader(m, s.data[s.parseOffset:])
Expand Down Expand Up @@ -265,12 +294,14 @@ func (parser *parser) parseHeader(m *message, data []byte) (bool, bool, int) {
config := parser.config

// enabled if required. Allocs for parameters slow down parser big times
//detailedf("Data: %s", data)
//detailedf("Header: %s", data[:i])
if isDetailed {
detailedf("Data: %s", data)
detailedf("Header: %s", data[:i])
}

// skip folding line
for p := i + 1; p < len(data); {
q := bytes.Index(data[p:], []byte("\r\n"))
q := bytes.Index(data[p:], constCRLF)
if q == -1 {
// Assuming incomplete
return true, false, 0
Expand All @@ -282,7 +313,9 @@ func (parser *parser) parseHeader(m *message, data []byte) (bool, bool, int) {
var headerNameBuf [140]byte
headerName := toLower(headerNameBuf[:], data[:i])
headerVal := trim(data[i+1 : p])
//debugf("Header: '%s' Value: '%s'\n", headerName, headerVal)
if isDebug {
debugf("Header: '%s' Value: '%s'\n", data[:i], headerVal)
}

// Headers we need for parsing. Make sure we always
// capture their value
Expand Down Expand Up @@ -327,12 +360,16 @@ func (parser *parser) parseHeader(m *message, data []byte) (bool, bool, int) {
}

func (*parser) parseBody(s *stream, m *message) (ok, complete bool) {
debugf("eat body: %d", s.parseOffset)
if isDebug {
debugf("eat body: %d", s.parseOffset)
}
if !m.hasContentLength && (bytes.Equal(m.connection, constClose) ||
(isVersion(m.version, 1, 0) && !bytes.Equal(m.connection, constKeepAlive))) {

// HTTP/1.0 no content length. Add until the end of the connection
debugf("close connection, %d", len(s.data)-s.parseOffset)
if isDebug {
debugf("close connection, %d", len(s.data)-s.parseOffset)
}
s.bodyReceived += (len(s.data) - s.parseOffset)
m.ContentLength += (len(s.data) - s.parseOffset)
s.parseOffset = len(s.data)
Expand All @@ -345,14 +382,16 @@ func (*parser) parseBody(s *stream, m *message) (ok, complete bool) {
} else {
s.bodyReceived += (len(s.data) - s.parseOffset)
s.parseOffset = len(s.data)
debugf("bodyReceived: %d", s.bodyReceived)
if isDebug {
debugf("bodyReceived: %d", s.bodyReceived)
}
return true, false
}
}

func (*parser) parseBodyChunkedStart(s *stream, m *message) (cont, ok, complete bool) {
// read hexa length
i := bytes.Index(s.data[s.parseOffset:], []byte("\r\n"))
i := bytes.Index(s.data[s.parseOffset:], constCRLF)
if i == -1 {
return false, true, false
}
Expand Down

0 comments on commit 9e16878

Please sign in to comment.