//download image from town func (t *Townparser) downloadImage(url string, name string) error { defer func() { if err := recover(); err != nil { log.Info("%s recovered from panic", TAG) return } }() if url == "0" { return nil } exist, err := exists("templates/static/images/" + name + ".jpg") if err != nil { log.Error("%s %s", TAG, err.Error()) } if !exist { resp, err := t.Tc.Get(url) if err != nil { log.Error("%s image download failed, name: %v, url: %v", TAG, name, url) log.Error("%s %s", TAG, err.Error()) return err } defer resp.Body.Close() if strings.Contains(url, "jpg") || strings.Contains(url, "jpeg") { img, _ := jpeg.Decode(resp.Body) m := resize.Resize(300, 0, img, resize.Lanczos2Lut) out, err := os.Create("templates/static/images/" + name + ".jpg") if err != nil { log.Error("%s %s", TAG, err.Error()) return nil } // write new image to file jpeg.Encode(out, m, nil) out.Close() } else if strings.Contains(url, "png") { img, err := png.Decode(resp.Body) if err != nil { log.Error("%s %s", TAG, err.Error()) } m := resize.Resize(300, 0, img, resize.Lanczos2Lut) out, err := os.Create("templates/static/images/" + name + ".png") if err != nil { log.Error("%s %s", TAG, err.Error()) return nil } // write new image to file jpeg.Encode(out, m, nil) out.Close() } } time.Sleep(200 * time.Millisecond) return nil }
//http get to the given ressource func (t *Townclient) Get(sUrl string) (*http.Response, error) { if strings.Contains(sUrl, "jpg") || strings.Contains(sUrl, "png") || strings.Contains(sUrl, "gif") || strings.Contains(sUrl, "jpeg") { } else { log.Info("%s[GET] url: %v", TAG, sUrl) } client := &http.Client{} req, err := http.NewRequest("GET", sUrl, nil) if err != nil { log.Error("%s couldn't create Request to: %v", TAG, sUrl) return nil, err } t.addHeader(req) if t.cookies != nil { for _, cookie := range t.cookies { req.AddCookie(cookie) } } time1 := time.Now() t.dumpRequest(req, "town_get_req_"+strconv.Itoa(time1.Nanosecond())) //connect to sUrl resp, err := client.Do(req) if err != nil { log.Error("%s couldn't connect to: %v", TAG, sUrl) return nil, err } t.dumpResponse(resp, "town_get_resp_"+strconv.Itoa(time1.Nanosecond())) return resp, nil }
func ReadConfigs() error { if err := autoflag.Load(gofigure.DefaultLoader, &Config); err != nil { logging.Error("Error loading configs: %v", err) return err } logging.Info("Read configs: %#v", &Config) for k, m := range Config.APIConfigs { if conf, found := Config.apiconfs[k]; found && conf != nil { b, err := yaml.Marshal(m) if err == nil { if err := yaml.Unmarshal(b, conf); err != nil { logging.Error("Error reading config for API %s: %s", k, err) } else { logging.Debug("Unmarshaled API config for %s: %#v", k, conf) } } else { logging.Error("Error marshalling config for API %s: %s", k, err) } } else { logging.Warning("API Section %s in config file not registered with server", k) } } return nil }
func (t *Townmanager) Start() { t.page = 1 t.end = false tc := &Townclient{} tc.User = t.User tc.Password = t.Password err := t.init(tc) log.Info("%s init finished, starting to parse...", TAG) if err != nil { log.Error("%s init failed", TAG) log.Error("%s %s", TAG, err.Error()) return } tp := &Townparser{Url: t.url, Tc: tc} count, err := tp.ParsePageCount() if err != nil { log.Error("%s %s", TAG, err.Error()) return } t.maxpage = count log.Info("%s crawling approximately %v pages", TAG, t.maxpage) t.saveReleases(tp.Rel) i := 1 for { if i == 1 { err = tp.ParseReleases(false) if err != nil { log.Error("%s %s", TAG, err.Error()) break } } else { tp = nil tp = &Townparser{Url: t.url + "&pp=25&page=" + strconv.Itoa(i), Tc: tc} err = tp.ParseReleases(true) if err != nil { log.Error("%s %s", TAG, err.Error()) break } } log.Info("%s crawled page %v/%v", TAG, i, t.maxpage) t.saveReleases(tp.Rel) time.Sleep(5 * time.Second) i++ if i == t.maxpage+1 { break } if t.end { log.Info("%s found old end point", TAG) break } } log.Info("%s parser closing", TAG) }
func (r *Runner) Start() { go func() { timeout := time.Second * 1 for { select { case <-time.After(timeout): if !r.checkTown() { timeout = time.Minute * 5 log.Info("town: trying login again in %v minute", timeout) } else { tm := town.Townmanager{User: r.Server.Config2.TownName, Password: r.Server.Config2.TownPassword, DB: r.Server.RelDB} go tm.Start() dur, err := time.ParseDuration(r.Server.Config2.Timeout) if err != nil { log.Error(err.Error()) } c := time.Tick(dur) for _ = range c { log.Info("tick start town") go tm.Start() } } } break } return }() go func() { timeout := time.Second * 2 for { select { case <-time.After(timeout): if !r.checkTown() { timeout = time.Minute * 5 log.Info("ghost: trying to login again in %v minute", timeout) } else { gm := ghost.Ghostmanager{User: r.Server.Config2.GhostName, Password: r.Server.Config2.GhostPassword, DB: r.Server.RelDB} go gm.Start() dur, err := time.ParseDuration(r.Server.Config2.Timeout) if err != nil { log.Error(err.Error()) } c := time.Tick(dur) for _ = range c { log.Info("tick start ghost") go gm.Start() } } } break } return }() }
func (g *Ghostmanager) Start() { g.end = false gc := &Ghostclient{} gc.User = g.User gc.Password = g.Password err := g.init(gc) log.Info("%s init finished, starting to parse...", TAG) if err != nil { log.Error("%s init failed", TAG) log.Error("%s %s", TAG, err.Error()) return } tp := &Ghostparser{Url: g.url, Gc: gc} i := 1 for { if i == 1 { err = tp.ParseReleases() if err != nil { log.Error("%s %s", TAG, err.Error()) break } g.maxpage = tp.Count log.Info("%s crawling approximately %v pages", TAG, g.maxpage) } else { tp = nil tp = &Ghostparser{Url: g.url + "&page=" + strconv.Itoa(i), Gc: gc} err = tp.ParseReleases() if err != nil { log.Error("%s %s", TAG, err.Error()) break } } g.saveReleases(tp.Rel) log.Info("%s crawled page %v/%v", TAG, i, g.maxpage) time.Sleep(5 * time.Second) i++ if i == g.maxpage+1 { break } if g.end { log.Info("%s found old end point", TAG) break } } log.Info("%s closing", TAG) }
func GetLogs(server *Server, parms martini.Params) string { offset, _ := strconv.Atoi(parms["offset"]) var all []mydb.Log _, err := server.LogDB.Select(&all, "select * from log ORDER BY id DESC LIMIT 50 OFFSET ?", offset) if err != nil { log.Error(err.Error()) } by, err := json.Marshal(all) if err != nil { log.Error(err.Error()) } return string(by) }
// Parse the user input into a request handler struct, with input validation func parseInput(r *http.Request, input interface{}, validator *RequestValidator) error { schemaDecoder.IgnoreUnknownKeys(true) if err := r.ParseForm(); err != nil { return InvalidRequestError("Error parsing request data: %s", err) } // We do not map and validate input to non-struct handlers if reflect.TypeOf(input).Kind() != reflect.Func { if err := schemaDecoder.Decode(input, r.Form); err != nil { return InvalidRequestError("Error decoding schema: %s", err) } // Validate the input based on the API spec if err := validator.Validate(input, r); err != nil { logging.Error("Error validating http.Request!: %s", err) return NewError(err) } } return nil }
func (rv *RequestValidator) Validate(request interface{}, r *http.Request) error { val := reflect.ValueOf(request) if val.Kind() == reflect.Ptr { val = val.Elem() } //go over all the validators for _, v := range rv.fieldValidators { // find the field in the struct. we assume it's there since we build the validators on start time field := val.FieldByName(v.GetKey()) // if the arg is optional and not set, we set the default if v.IsOptional() && (!field.IsValid() || r.FormValue(v.GetParamName()) == "") { def, ok := v.GetDefault() if ok { logging.Info("Default value for %s: %v", v.GetKey(), def) field.Set(reflect.ValueOf(def).Convert(field.Type())) } } // now we validate! e := v.Validate(field, r) if e != nil { logging.Error("Could not validate field %s: %s", v.GetParamName(), e) return e } } return nil }
func (t *Townclient) getSValue() (sValue string) { log.Info("%s getting sValue for town login", TAG) sValue = "" var doc *goquery.Document var e error log.Info("%s[GET] url: %v", TAG, ROOT) if doc, e = goquery.NewDocument(ROOT); e != nil { log.Error("%s %s", TAG, e.Error()) return } doc.Find("input").Each(func(i int, s *goquery.Selection) { attr, exists := s.Attr("name") if exists == true { if attr == "s" { bla, exists := s.Attr("value") if exists == true { sValue = bla } } } }) log.Info("%s sValue: %v", TAG, sValue) return sValue }
func SetRating(server *Server, parms martini.Params) string { checksum := parms["checksum"] score, _ := strconv.Atoi(parms["score"]) rating, err := server.RelDB.SelectInt("select rating from release where checksum=?", checksum) if err != nil { log.Error(err.Error()) } oldrating := rating rating += int64(score) log.Info("changing score for %s from %v to %v", checksum, oldrating, rating) _, err = server.RelDB.Exec("update release set rating=? where checksum=?", rating, checksum) if err != nil { log.Error(err.Error()) } return fmt.Sprintf("%v %v", checksum, score) }
func LinkFollow(w http.ResponseWriter, r *http.Request, server *Server, parms martini.Params) { checksum := parms["checksum"] hits, err := server.RelDB.SelectInt("select hits from release where checksum=?", checksum) if err != nil { log.Error(err.Error()) } oldhits := hits hits += 1 log.Info("increasing hits for %s from %v to %v", checksum, oldhits, hits) _, err = server.RelDB.Exec("update release set hits=? where checksum=?", hits, checksum) if err != nil { log.Error(err.Error()) } url, err := server.RelDB.SelectStr("select url from release where checksum=?", checksum) http.Redirect(w, r, url, http.StatusTemporaryRedirect) }
func (j *JWTAuthenticator) EncodeToken(data interface{}) (string, error) { token := jwt.New(jwt.SigningMethodHS256) token.Claims["data"] = data sstr, err := token.SignedString(j.key) if err != nil { logging.Error("Error signing token: %s", err) } return sstr, err }
func (g *Ghostparser) getBoardId(str string) int { regex, err := regexp.Compile("boardid=.+&") if err != nil { log.Error("%s %s", TAG, err.Error()) return -1 } str = regex.FindString(str) str = strings.Replace(str, "&", "", -1) astr := strings.Split(str, "=") if len(astr) < 2 { return -1 } i, err := strconv.Atoi(astr[1]) if err != nil { log.Error("%s %s", TAG, err.Error()) return -1 } return i }
// configure registers the API's routes on a router. If the passed router is nil, we create a new one and return it. // The nil mode is used when an API is run in stand-alone mode. func (a *API) configure(router *httprouter.Router) *httprouter.Router { if router == nil { router = httprouter.New() } for i, route := range a.Routes { if err := route.parseInfo(route.Path); err != nil { logging.Error("Error parsing info for %s: %s", route.Path, err) } a.Routes[i] = route h := a.handler(route) pth := a.FullPath(route.Path) if route.Methods&GET == GET { logging.Info("Registering GET handler %v to path %s", h, pth) router.Handle("GET", pth, h) } if route.Methods&POST == POST { logging.Info("Registering POST handler %v to path %s", h, pth) router.Handle("POST", pth, h) } } chain := buildChain(a.SwaggerMiddleware...) if chain == nil { chain = buildChain(a.swaggerHandler()) } else { chain.append(a.swaggerHandler()) } // Server the API documentation swagger router.GET(a.FullPath("/swagger"), a.middlewareHandler(chain, nil, nil)) chain = buildChain(a.TestMiddleware...) if chain == nil { chain = buildChain(a.testHandler()) } else { chain.append(a.testHandler()) } router.GET(path.Join("/test", a.root(), ":category"), a.middlewareHandler(chain, nil, nil)) // Redirect /$api/$version/console => /console?url=/$api/$version/swagger uiPath := fmt.Sprintf("/console?url=%s", url.QueryEscape(a.FullPath("/swagger"))) router.Handler("GET", a.FullPath("/console"), http.RedirectHandler(uiPath, 301)) return router }
func (a *API) middlewareHandler(chain *step, security SecurityScheme, renderer Renderer) func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { // allow overriding the API's default renderer with a per-route one if renderer == nil { renderer = a.Renderer } return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { req := NewRequest(r) if !a.AllowInsecure && !req.Secure { // local requests bypass security if req.RemoteIP != "127.0.0.1" { http.Error(w, insecureAccessMessage, http.StatusForbidden) return } } r.ParseForm() // Copy values from the router params to the request params for _, v := range p { r.Form.Set(v.Key, v.Value) } var ret interface{} var err error if security != nil { if err = security.Validate(req); err != nil { logging.Warning("Error validating security scheme: %s", err) if e, ok := err.(*internalError); ok { e.Code = ErrUnauthorized err = e } } } if err == nil { ret, err = chain.handle(w, req) } if err != Hijacked { if err = renderer.Render(ret, err, w, req); err != nil { logging.Error("Error rendering response: %s", err) } } else { logging.Debug("Not rendering hijacked request %s", r.RequestURI) } } }
func (g *Ghostmanager) saveReleases(releases []Release) { for _, rel := range releases { err := g.DB.Insert(&town.Release{Name: rel.Name, Checksum: rel.Checksum, Rating: rel.Rating, Hits: rel.Hits, Time: rel.Time, Url: rel.Url, Tag: rel.Tag}) if err != nil { switch err.(type) { case *sqlite3.Error: if err.(*sqlite3.Error).Code() == 2067 { g.end = true break } else { log.Error("%s %s", TAG, err.Error()) } default: log.Error("%s %s", TAG, err.Error()) } } else { log.Info("%s saved %v", TAG, rel.Name) } } }
func (t *Townmanager) saveReleases(releases []Release) { for _, rel := range releases { err := t.DB.Insert(&rel) if err != nil { switch err.(type) { case *sqlite3.Error: if err.(*sqlite3.Error).Code() == 2067 { t.end = true break } else { log.Error("%s %s", TAG, err.Error()) } default: log.Error("%s %s", TAG, err.Error()) } } else { log.Info("%s saved %v", TAG, rel.Name) } } }
//http get to the given ressource func (g *Ghostclient) Get(sUrl string) (*http.Response, error) { if strings.Contains(sUrl, "jpg") || strings.Contains(sUrl, "png") || strings.Contains(sUrl, "gif") { } else { log.Info("%s[GET] url: %v", TAG, sUrl) } client := &http.Client{} req, err := http.NewRequest("GET", sUrl, nil) if err != nil { log.Error("%s couldn't create Request to: %v", TAG, sUrl) return nil, err } req.Header.Add("Accept", "text/html, application/xhtml+xml, */*") req.Header.Add("Referer", "http://ghost-of-usenet.org/index.php") req.Header.Add("Accept-Language", "de-DE") req.Header.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)") req.Header.Add("Accept-Encoding", "gzip, deflate") req.Header.Add("Host", "ghost-of-usenet.org") req.Header.Add("Connection", "Keep-Alive") if g.cookies != nil { for _, cookie := range g.cookies { req.AddCookie(cookie) } } time1 := time.Now() g.dumpRequest(req, "ghost_get_req_"+strconv.Itoa(time1.Nanosecond())) //connect to sUrl resp, err := client.Do(req) if err != nil { log.Error("%s couldn't connect to: %v", TAG, sUrl) return nil, err } g.dumpResponse(resp, "ghost_get_resp_"+strconv.Itoa(time1.Nanosecond())) return resp, nil }
//serialize an error string inside an object func writeError(w http.ResponseWriter, message string) { //WriteError is called from recovery, so it must be panic proof defer func() { e := recover() if e != nil { logging.Error("Could not write error response! %s", e) } }() http.Error(w, message, http.StatusInternalServerError) }
func (t *Townmanager) init(tc *Townclient) error { //login to get cookies err := tc.Login() if err != nil { log.Error("%s %s", TAG, err.Error()) return err } time.Sleep(1000 * time.Millisecond) url, err := tc.GetDailyUrl() if err != nil { log.Error("%s %s", TAG, err.Error()) return err } t.url = url time.Sleep(200 * time.Millisecond) return nil }
func (g *Ghostmanager) init(gc *Ghostclient) error { //login to get cookies err := gc.Login() if err != nil { log.Error("%s %s", TAG, err.Error()) return err } time.Sleep(1000 * time.Millisecond) url, err := gc.GetDailyUrl() if err != nil { log.Error("%s %s", TAG, err.Error()) return err } g.url = url time.Sleep(200 * time.Millisecond) return nil }
//parse the http resp from Townclient func (g *Ghostparser) ParseReleases() error { log.Info("%s parsing %v", TAG, g.Url) resp, err := g.Gc.Get(g.Url) if err != nil { log.Error("%s %s", TAG, err.Error()) return err } defer resp.Body.Close() respbody, err := html.Parse(resp.Body) doc := goquery.NewDocumentFromNode(respbody) var rel Release doc.Find("table").Each(func(a int, sa *goquery.Selection) { if a == 10 { //get the right table sa.Find("tr").Each(func(b int, sb *goquery.Selection) { sb.Find("td").Each(func(c int, sc *goquery.Selection) { if c == 2 { rel = Release{} g.getUrlAndTagAndName(&rel, sc) if rel.Name != "" { rel.Time = time.Now().Unix() rel.Checksum = g.encodeName(rel.Url) rel.checkQual() if rel.Name != "" { rel.Hits = 0 rel.Rating = 0 g.downloadImage(rel.Url, rel.Checksum) g.addRelease(rel) } } } }) }) } if g.Count == 0 { //get page count if a == 51 { sa.Find("a").Each(func(d int, sd *goquery.Selection) { if d == 3 { g.Count, err = strconv.Atoi(sd.Text()) } }) } } }) return nil }
// parseDefault takes the default string of a paramInfo and parses it according to the param's type func parseDefault(val string, t reflect.Kind) (interface{}, bool) { if val == "" { return nil, false } switch t { case reflect.Int, reflect.Int32, reflect.Int16, reflect.Int64: if i, err := parseInt(val); err == nil { return i, true } else { logging.Error("Error parsing int default '%s': %s", val, err) } case reflect.Float32, reflect.Float64: if f, err := parseFloat(val); err == nil { return f, true } else { logging.Error("Error parsing float default '%s': %s", val, err) } case reflect.String: return val, true case reflect.Bool: if b, err := parseBool(val); err == nil { return b, true } else { logging.Error("Error parsing bool default '%s': %s", val, err) } case reflect.Slice: if l, err := parseList(val); err == nil { return l, true } else { logging.Error("Error parsing string list '%s': %s", val, err) } } return nil, false }
func GetReleaseWithTagAndName(server *Server, parms martini.Params) string { offset := parms["offset"] tags := parms["tags"] name := parms["name"] command := "" if tags == "none" && name != "none" { command = "select * from release where name LIKE '%" + name + "%' ORDER BY time DESC LIMIT 200 OFFSET " + offset } else if name == "none" && tags != "none" { cb := &CMDBuilder{} command = cb.Tokenize(tags) command += " ORDER BY time DESC LIMIT 200 OFFSET " + offset } else if name != "none" && tags != "none" { cb := &CMDBuilder{} command = cb.Tokenize(tags) command += "AND name LIKE '%" + name + "%' ORDER BY time DESC LIMIT 200 OFFSET " + offset } var b []town.Release if command != "" { _, err := server.RelDB.Select(&b, command) if err != nil { log.Error(err.Error()) } } else { _, err := server.RelDB.Select(&b, "select * from release ORDER BY time DESC LIMIT 200 OFFSET ?", offset) if err != nil { log.Error(err.Error()) } } by, err := json.Marshal(b) if err != nil { log.Error(err.Error()) } return string(by) }
// return an httprouter compliant handler function for a route func (a *API) handler(route Route) func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { // extract the handler type to create a reflect based factory for it T := reflect.TypeOf(route.Handler) if T.Kind() == reflect.Ptr { T = T.Elem() } validator := NewRequestValidator(route.requestInfo) security := route.Security if security == nil { security = a.DefaultSecurityScheme } // Build the middleware chain for the API middleware and the rout middleware. // The route middleware comes after the API middleware chain := buildChain(append(a.Middleware, route.Middleware...)...) // add the handler itself as the final middleware handlerMW := MiddlewareFunc(func(w http.ResponseWriter, r *Request, next HandlerFunc) (interface{}, error) { var reqHandler RequestHandler if T.Kind() == reflect.Struct { // create a new request handler instance reqHandler = reflect.New(T).Interface().(RequestHandler) } else { reqHandler = route.Handler } //read params if err := parseInput(r.Request, reqHandler, validator); err != nil { logging.Error("Error reading input: %s", err) return nil, NewError(err) } return reqHandler.Handle(w, r) }) if chain == nil { chain = &step{ mw: handlerMW, } } else { chain.append(handlerMW) } return a.middlewareHandler(chain, security, route.Renderer) }
// Create new request validator for a request handler interface. // This function walks the struct tags of the handler's fields and extracts validation metadata. // // You should give it the reflect type of your request handler struct func NewRequestValidator(ri schema.RequestInfo) *RequestValidator { //if the user passes a pointer we walk the actual struct ret := &RequestValidator{ fieldValidators: make([]validator, 0), } //iterate over the fields and create a validator for each for _, pi := range ri.Params { var vali validator switch pi.Kind { // case reflect.Struct: // //for structs - we add validators recursively // validator := NewRequestValidator(field.Type) // if validator != nil && len(validator.fieldValidators) > 0 { // ret.fieldValidators = append(ret.fieldValidators, validator.fieldValidators...) // } // continue case reflect.String: vali = newStringValidator(pi) case reflect.Int, reflect.Int32, reflect.Int64: vali = newIntValidator(pi) case reflect.Float32, reflect.Float64: vali = newFloatValidator(pi) case reflect.Bool: vali = newBoolValidator(pi) default: logging.Error("I don't know how to validate %s", pi.Kind) continue } if vali != nil { logging.Debug("Adding validator %v to request validator %v", vali, ri) ret.fieldValidators = append(ret.fieldValidators, vali) } } return ret }
// ErrorString converts an error code to a user "friendly" string func httpError(err error) (re int, rm string) { if err == nil { return http.StatusOK, http.StatusText(http.StatusOK) } incidentId := uuid.New() if err != Hijacked { logging.Error("[%s] Error processing request: %s", incidentId, err) } statusFunc := func(i int) (int, string) { return i, fmt.Sprintf("[%s] %s", incidentId, http.StatusText(i)) } if e, ok := err.(*internalError); !ok { return statusFunc(http.StatusInternalServerError) } else { switch e.Code { case Ok: return http.StatusOK, "OK" case ErrHijacked: return http.StatusOK, "Request Hijacked By Handler" case ErrInvalidRequest: return statusFunc(http.StatusBadRequest) case ErrInvalidParam, ErrMissingParam: return http.StatusBadRequest, e.Message case ErrUnauthorized: return statusFunc(http.StatusUnauthorized) case ErrInsecureAccessDenied: return statusFunc(http.StatusForbidden) case ErrResourceUnavailable: return statusFunc(http.StatusServiceUnavailable) case ErrBackOff: return statusFunc(http.StatusServiceUnavailable) case ErrGeneralFailure: fallthrough default: return statusFunc(http.StatusInternalServerError) } } }
// invokeTest runs a tester and prints the output func (t *testRunner) invokeTest(path string, tc Tester) *testResult { if t.shouldRun(tc) { var result testResult if tc == nil || t.shouldRun(tc) { result = t.runTest(tc, path) logging.Info("Test result for %s: %#v", path, result) if err := t.formatter.format(result); err != nil { logging.Error("Error running formatter: %s", err) } return &result } } return nil }
// Deny denies traffic from the given CIDRs (e.g. 127.0.0.0/8 for local addresses) func (f *IPRangeFilter) Deny(cidrs ...string) *IPRangeFilter { f.denied = make([]*net.IPNet, 0, len(cidrs)) for _, addr := range cidrs { if ip := net.ParseIP(addr); ip != nil { addr = addr + "/32" } _, ipnet, err := net.ParseCIDR(addr) if err != nil { logging.Error("Error parsing CIDR: %s", err) continue } f.denied = append(f.denied, ipnet) } return f }