package pkg import ( "errors" "strconv" "strings" ) type SpdyProfile struct { ProfileCommon ActivationMode string `json:"activation_mode"` // tls CompressionLevel int `json:"compression_level"` // 5 CompressionWindowSize int `json:"compression_window_size"` // 8 ConcurrentStreamsPerConnection int `json:"concurrent_streams_per_connection"` // 10 ConnectionIdleTimeout int `json:"connection_idle_timeout"` // 300 FrameSize int `json:"frame_size"` // 2048 InsertHeader string `json:"insert_header"` // disabled InsertHeaderName string `json:"insert_header_name"` // X_SPDY PriorityHandling string `json:"priority_handling"` // strict ProtocolVersions []string `json:"protocol_versions"` // { spdy3.1 spdy3 spdy2 http1.1 } ReceiveWindow int `json:"receive_window"` // 32 WriteSize int `json:"write_size"` // 16384 } func ParseSPDY(raw string) (*SpdyProfile, error) { p := new(SpdyProfile) split := strings.Split(raw, "\n") if !strings.Contains(split[0], "ltm profile spdy") { return nil, errors.New("not a spdy profile") } p.ProfileCommon = parseCommon(raw) for _, line := range split { f := strings.Fields(line) switch strings.ToLower(f[0]) { case "activation-mode": p.ActivationMode = strings.Join(f[1:], " ") case "compression-level": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.CompressionLevel = i case "compression-window-size": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.CompressionWindowSize = i case "concurrent-streams-per-connection": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.ConcurrentStreamsPerConnection = i case "connection-idle-timeout": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.ConnectionIdleTimeout = i case "frame-size": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.FrameSize = i case "insert-header": p.InsertHeader = strings.Join(f[1:], " ") case "insert-header-name": p.InsertHeaderName = strings.Join(f[1:], " ") case "priority-handling": p.PriorityHandling = strings.Join(f[1:], " ") case "protocol-versions": if f[1] != "none" { p.ProtocolVersions = f[2 : len(f)-1] } case "receive-window": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.ReceiveWindow = i case "write-size": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.WriteSize = i } } return p, nil }