package pkg import ( "errors" "strconv" "strings" ) type FastHTTPProfile struct { ProfileCommon ClientCloseTimeout int `json:"client_close_timeout"` ConnpoolIDleTimeoutOverride int `json:"connpool_idle_timeout_override"` ConnpoolMaxReuse int `json:"connpool_max_reuse"` ConnpoolMaxSize int `json:"connpoll_max_size"` ConnpoolMinSize int `json:"connpoll_min_size"` ConnpoolReplenish string `json:"connpool_replenish"` ConnpoolStep int `json:"connpool_step"` ForceHTTP10Response string `json:"force_http_10_response"` HardwareSYNCookie string `json:"hardware_syn_cookie"` HeaderInsert string `json:"header_insert"` HTTP11CloseWorkarounds string `json:"http_11_close_workarounds"` IdleTimeout int `json:"idle_timeout"` InsertXForwardedFor string `json:"insert_x_forwarded_for"` Layer7 string `json:"layer_7"` MaxHeaderSize int `json:"max_header_size"` MaxRequests int `json:"max_requests"` MSSOverride int `json:"mss_override"` ReceiveWindowSize int `json:"receive_window_size"` ResetOnTimeout string `json:"reset_on_timeout"` ServerCloseTimeout int `json:"server_close_timeout"` ServerSack string `json:"server_sack"` ServerTimestamp string `json:"server_timestamp"` UncleanShutdown string `json:"unclean_shutdown"` } func ParseFastHTTPProfile(raw string) (*FastHTTPProfile, error) { p := new(FastHTTPProfile) split := strings.Split(raw, "\n") if !strings.Contains(split[0], "ltm profile fasthttp") { return nil, errors.New("not a fasthttp profile") } p.ProfileCommon = parseCommon(raw) for _, line := range split { f := strings.Fields(line) switch strings.ToLower(f[0]) { case "client-close-timeout": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.ClientCloseTimeout = i case "connpool-idle-timeout-override": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.ConnpoolIDleTimeoutOverride = i case "connpool-max-reuse": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.ConnpoolMaxReuse = i case "connpool-max-size": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.ConnpoolMaxSize = i case "connpool-min-size": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.ConnpoolMinSize = i case "connpool-replenish": p.ConnpoolReplenish = f[1] case "connpool-step": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.ConnpoolStep = i case "force-http-10-response": p.ForceHTTP10Response = f[1] case "hardware-syn-cookie": p.HardwareSYNCookie = f[1] case "header-insert": p.HeaderInsert = strings.Join(f[1:], " ") case "http-11-close-workarounds": p.HTTP11CloseWorkarounds = f[1] case "idle-timeout": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.IdleTimeout = i case "insert-xforwarded-for": p.InsertXForwardedFor = f[1] case "layer-7": p.Layer7 = strings.Join(f[1:], " ") case "max-header-size": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.MaxHeaderSize = i case "max-requests": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.MaxRequests = i case "mss-override": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.MSSOverride = i case "receive-window-size": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.ReceiveWindowSize = i case "reset-on-timeout": p.ResetOnTimeout = f[1] case "server-close-timeout": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.ServerCloseTimeout = i case "server-sack": p.ServerSack = f[1] case "server-timestamp": p.ServerTimestamp = f[1] case "unclean-shutdown": p.UncleanShutdown = f[1] } } return p, nil }