diff --git a/pkg/containerwatcher/v2/tracers/httpparse.go b/pkg/containerwatcher/v2/tracers/httpparse.go index 5602912471..ed80e6fb38 100644 --- a/pkg/containerwatcher/v2/tracers/httpparse.go +++ b/pkg/containerwatcher/v2/tracers/httpparse.go @@ -78,43 +78,58 @@ func GetPacketDirection(syscall string) (consts.NetworkDirection, error) { } func ParseHttpRequest(data []byte) (*http.Request, error) { - bufReader := bufio.NewReader(bytes.NewReader(data)) + // Find header/body boundary + headerEnd := bytes.Index(data, []byte("\r\n\r\n")) + if headerEnd == -1 { + headerEnd = bytes.Index(data, []byte("\n\n")) + if headerEnd == -1 { + return fallbackReadRequest(data) + } + headerEnd += 2 + } else { + headerEnd += 4 + } + // Parse headers only + bufReader := bufio.NewReader(bytes.NewReader(data[:headerEnd])) req, err := http.ReadRequest(bufReader) if err != nil { return fallbackReadRequest(data) } - body, err := io.ReadAll(req.Body) - if err != nil { - return nil, err - } - - req.Body.Close() - - req.Body = io.NopCloser(bytes.NewReader(body)) + // Set body directly without re-reading + bodyData := data[headerEnd:] + req.ContentLength = int64(len(bodyData)) + req.Body = io.NopCloser(bytes.NewReader(bodyData)) return req, nil } func ParseHttpResponse(data []byte, req *http.Request) (*http.Response, error) { - resp, err := readResponse(data, req) - if err != nil { - resp, err = fallbackReadResponse(data, req) - if err != nil { - return nil, err + // Find header/body boundary + headerEnd := bytes.Index(data, []byte("\r\n\r\n")) + if headerEnd == -1 { + headerEnd = bytes.Index(data, []byte("\n\n")) + if headerEnd == -1 { + return fallbackReadResponse(data, req) } + headerEnd += 2 + } else { + headerEnd += 4 } - body, err := io.ReadAll(resp.Body) - if err != nil && err != io.ErrUnexpectedEOF { - return nil, err + // Parse headers only + bufReader := bufio.NewReader(bytes.NewReader(data[:headerEnd])) + resp, err := http.ReadResponse(bufReader, req) + if err != nil { + return fallbackReadResponse(data, req) } + // Set body directly without re-reading + bodyData := data[headerEnd:] resp.Body.Close() - - resp.Body = io.NopCloser(bytes.NewReader(body)) - resp.ContentLength = int64(len(body)) + resp.Body = io.NopCloser(bytes.NewReader(bodyData)) + resp.ContentLength = int64(len(bodyData)) resp.TransferEncoding = nil resp.Header.Del("Transfer-Encoding") resp.Header.Del("Content-Length") diff --git a/pkg/rulemanager/cel/cel.go b/pkg/rulemanager/cel/cel.go index 36a5ed1708..7cc507d980 100644 --- a/pkg/rulemanager/cel/cel.go +++ b/pkg/rulemanager/cel/cel.go @@ -68,7 +68,7 @@ func NewCEL(objectCache objectcache.ObjectCache, cfg config.Config) (*CEL, error } c.evalContextPool.New = func() interface{} { - return make(map[string]any, 1) + return make(map[string]any, 2) } return c, nil @@ -117,8 +117,11 @@ func (c *CEL) getOrCreateProgram(expression string) (cel.Program, error) { } func (c *CEL) EvaluateRule(event *events.EnrichedEvent, expressions []typesv1.RuleExpression) (bool, error) { + obj, _ := xcel.NewObject(event.Event.(utils.CelEvent)) // FIXME put safety check here + eventType := event.Event.GetEventType() + input := map[string]any{"event": obj, "eventType": string(eventType)} + for _, expression := range expressions { - eventType := event.Event.GetEventType() if expression.EventType != eventType { continue } @@ -127,9 +130,7 @@ func (c *CEL) EvaluateRule(event *events.EnrichedEvent, expressions []typesv1.Ru if err != nil { return false, err } - - obj, _ := xcel.NewObject(event.Event.(utils.CelEvent)) // FIXME put safety check here - out, _, err := program.Eval(map[string]any{"event": obj, "eventType": string(eventType)}) + out, _, err := program.Eval(input) if err != nil { return false, err } diff --git a/pkg/rulemanager/ruleadapters/adapters/common.go b/pkg/rulemanager/ruleadapters/adapters/common.go index 4d22228212..e485d28a79 100644 --- a/pkg/rulemanager/ruleadapters/adapters/common.go +++ b/pkg/rulemanager/ruleadapters/adapters/common.go @@ -23,7 +23,9 @@ func ConvertToMap(e utils.EnrichEvent) map[string]interface{} { //k8s["node"] = e.K8s.Node k8s["namespace"] = e.GetNamespace() k8s["podName"] = e.GetPod() - k8s["podLabels"] = e.GetPodLabels() + + //k8s["podLabels"] = e.GetPodLabels() + k8s["containerName"] = e.GetContainer() k8s["hostNetwork"] = e.GetHostNetwork() diff --git a/pkg/rulemanager/ruleadapters/adapters/pool.go b/pkg/rulemanager/ruleadapters/adapters/pool.go index 778cf46e5a..8d2200d0b4 100644 --- a/pkg/rulemanager/ruleadapters/adapters/pool.go +++ b/pkg/rulemanager/ruleadapters/adapters/pool.go @@ -7,7 +7,7 @@ import "sync" // for the number of keys in your event maps. var mapPool = sync.Pool{ New: func() interface{} { - return make(map[string]interface{}, 32) + return make(map[string]interface{}, 5) }, } diff --git a/pkg/rulemanager/rulepolicy.go b/pkg/rulemanager/rulepolicy.go index eef804a449..9a58943b00 100644 --- a/pkg/rulemanager/rulepolicy.go +++ b/pkg/rulemanager/rulepolicy.go @@ -43,17 +43,20 @@ func RuleAppliesToContext(rule *typesv1.Rule, contextInfo contextdetection.Conte currentContext = contextInfo.Context() } - var contextTags []string + var hasContextTags bool for _, tag := range rule.Tags { if ctx, found := strings.CutPrefix(tag, "context:"); found { - contextTags = append(contextTags, ctx) + if ctx == string(currentContext) { + return true + } + hasContextTags = true } } - if len(contextTags) > 0 { - return slices.Contains(contextTags, string(currentContext)) + // No context specified in tags: default to kubernetes only (backward compatible) + if !hasContextTags { + return currentContext == contextdetection.Kubernetes } - // No context specified in tags: default to kubernetes only (backward compatible) - return currentContext == contextdetection.Kubernetes + return false } diff --git a/pkg/utils/labels.go b/pkg/utils/labels.go index acccdfd91c..ab4c9ac704 100644 --- a/pkg/utils/labels.go +++ b/pkg/utils/labels.go @@ -8,35 +8,22 @@ import ( ) func parseStringToMap(s string) map[string]string { - result := make(map[string]string) - - // 1. Split the string by the comma delimiter to get key-value pairs pairs := strings.Split(s, ",") + result := make(map[string]string, len(pairs)/2) for _, pair := range pairs { - // Trim any leading/trailing whitespace from the pair pair = strings.TrimSpace(pair) if pair == "" { - continue // Skip empty pairs that could result from multiple commas + continue } - // 2. Split each pair by the equals sign delimiter. - // We use SplitN(pair, "=", 2) to ensure that only the first - // equals sign is treated as the delimiter, allowing values to - // contain equals signs (though not the case in the example). parts := strings.SplitN(pair, "=", 2) - if len(parts) != 2 { - // Handle malformed pairs (e.g., "key" or "key=value=extra") logger.L().Debug("Malformed key-value pair", helpers.String("pair", pair)) continue } - // Trim whitespace from key and value and add to the map - key := strings.TrimSpace(parts[0]) - value := strings.TrimSpace(parts[1]) - - result[key] = value + result[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1]) } return result