From 9e16878cd81f33aef7a81cfadecfdf6f8484cc6d Mon Sep 17 00:00:00 2001 From: urso Date: Tue, 8 Dec 2015 01:04:32 +0100 Subject: [PATCH] guard debug statements in http module guard debug statements so no additional memory allocation happen for supressed debugging output. --- packetbeat/protos/http/http.go | 66 +++++++++++++++++++------ packetbeat/protos/http/http_parser.go | 71 +++++++++++++++++++++------ 2 files changed, 107 insertions(+), 30 deletions(-) diff --git a/packetbeat/protos/http/http.go b/packetbeat/protos/http/http.go index 4687be37d90..dd727dcec21 100644 --- a/packetbeat/protos/http/http.go +++ b/packetbeat/protos/http/http.go @@ -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 @@ -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 @@ -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 { @@ -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 { @@ -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 } @@ -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 @@ -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) } @@ -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) } } @@ -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:]...) } } @@ -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 } @@ -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 { @@ -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('*') @@ -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 } diff --git a/packetbeat/protos/http/http_parser.go b/packetbeat/protos/http/http_parser.go index 55383f0b843..0276e1f2b54 100644 --- a/packetbeat/protos/http/http_parser.go +++ b/packetbeat/protos/http/http_parser.go @@ -72,6 +72,8 @@ type parserConfig struct { var ( transferEncodingChunked = []byte("chunked") + constCRLF = []byte("\r\n") + constClose = []byte("close") constKeepAlive = []byte("keep-alive") @@ -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/")) { @@ -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 } @@ -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 @@ -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") @@ -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 @@ -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:]) @@ -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 @@ -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 @@ -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) @@ -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 }