parseFirewallLogLine parses a single firewall log line Format: timestamp client_ip:port domain dest_ip:port proto method status decision url user_agent Returns nil if the line is invalid or should be skipped
(line string)
| 194 | // Format: timestamp client_ip:port domain dest_ip:port proto method status decision url user_agent |
| 195 | // Returns nil if the line is invalid or should be skipped |
| 196 | func parseFirewallLogLine(line string) *FirewallLogEntry { |
| 197 | trimmed := strings.TrimSpace(line) |
| 198 | if trimmed == "" || strings.HasPrefix(trimmed, "#") { |
| 199 | return nil |
| 200 | } |
| 201 | |
| 202 | // Split by whitespace but preserve quoted strings |
| 203 | // This regex matches non-whitespace sequences or quoted strings |
| 204 | fields := firewallLogFieldSplitter.FindAllString(trimmed, -1) |
| 205 | |
| 206 | if len(fields) < 10 { |
| 207 | return nil |
| 208 | } |
| 209 | |
| 210 | // Only validate timestamp (essential for log format detection) |
| 211 | // This matches the JavaScript parser behavior which only validates timestamp |
| 212 | timestamp := fields[0] |
| 213 | if matched, _ := regexp.MatchString(`^\d+(\.\d+)?$`, timestamp); !matched { |
| 214 | return nil |
| 215 | } |
| 216 | |
| 217 | // Extract fields without validation (matches JavaScript parser) |
| 218 | clientIPPort := fields[1] |
| 219 | domain := fields[2] |
| 220 | destIPPort := fields[3] |
| 221 | status := fields[6] |
| 222 | decision := fields[7] |
| 223 | |
| 224 | // Remove quotes from user agent |
| 225 | userAgent := fields[9] |
| 226 | userAgent = strings.Trim(userAgent, `"`) |
| 227 | |
| 228 | return &FirewallLogEntry{ |
| 229 | Timestamp: timestamp, |
| 230 | ClientIPPort: clientIPPort, |
| 231 | Domain: domain, |
| 232 | DestIPPort: destIPPort, |
| 233 | Proto: fields[4], |
| 234 | Method: fields[5], |
| 235 | Status: status, |
| 236 | Decision: decision, |
| 237 | URL: fields[8], |
| 238 | UserAgent: userAgent, |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | // isRequestAllowed determines if a request was allowed based on decision and status |
| 243 | // This mirrors the logic from the JavaScript parser |
no outgoing calls