//makeRecord builds and returns record with attached file. //if nobody render null_article page. func (t *threadCGI) makeRecord(at *attached, suffix string, ca *thread.Cache) (*record.Record, error) { body := make(map[string]string) for _, name := range []string{"body", "base_stamp", "base_id", "name", "mail"} { if value := t.Req.FormValue(name); value != "" { body[name] = util.Escape(value) } } if at != nil { body["attach"] = at.Data body["suffix"] = strings.TrimSpace(suffix) } if len(body) == 0 { t.Header(t.M["null_article"], "", nil, true) t.Footer(nil) return nil, errors.New("null article") } stamp := time.Now().Unix() if t.Req.FormValue("error") != "" { stamp = t.errorTime() } rec := record.New(ca.Datfile, "", 0) passwd := t.Req.FormValue("passwd") rec.Build(stamp, body, passwd) return rec, nil }
//printAttach renders the content of attach file and makes thumnail if needed and possible. func (t *threadCGI) printAttach(datfile, id string, stamp int64, thumbnailSize, suffix string) { ca := thread.NewCache(datfile) switch { case ca.HasRecord(): case t.CheckGetCache(): download.GetCache(true, ca) default: t.Print404(ca, "") return } rec := record.New(ca.Datfile, id, stamp) if !rec.Exists() { t.Print404(ca, "") return } if err := rec.Load(); err != nil { t.Print404(ca, "") return } if rec.GetBodyValue("suffix", "") != suffix { t.Print404(ca, "") return } t.renderAttach(rec, suffix, stamp, thumbnailSize) }
//CheckData makes a record from res and checks its records meets condisions of args. //adds the rec to cache if meets conditions. //if spam or big data, remove the rec from disk. //returns spam/getting error. func (c *Cache) CheckData(tx *bolt.Tx, res string, stamp int64, id string, begin, end int64) error { r := record.New(c.Datfile, "", 0) if errr := r.Parse(res); errr != nil { return cfg.ErrGet } exist, err := db.HasKey(tx, "record", r.Head.ToKey()) if err != nil { log.Println(err) } if exist { return nil } if !r.Meets(begin, end) { return cfg.ErrGet } deleted := false if len(r.Recstr()) > cfg.RecordLimit<<10 || r.IsSpam() { log.Printf("warning:%s/%s:too large or spam record", r.Datfile, r.Idstr()) deleted = true } err = r.SyncTX(tx, deleted) if err != nil { return err } if deleted { return cfg.ErrSpam } return nil }
//doUpdate adds remote node to searchlist and lookuptable with datfile specified in url. //if stamp is in range of defaultUpdateRange adds to updateque. func doUpdate(w http.ResponseWriter, r *http.Request) { s, err := new(w, r) if err != nil { log.Println(err) log.Println("failed to create cgi struct") return } reg := regexp.MustCompile(`^update/(\w+)/(\d+)/(\w+)/([^\+]*)(\+.*)`) m := reg.FindStringSubmatch(s.Path()) if m == nil { log.Println("illegal url") return } datfile, stamp, id, hostport, path := m[1], m[2], m[3], m[4], m[5] host, portstr, err := net.SplitHostPort(hostport) if err != nil { log.Println(err) return } port, err := strconv.Atoi(portstr) if err != nil { log.Println(err) return } host = s.remoteIP(host) if host == "" { log.Println("host is null") return } n, err := node.MakeNode(host, path, port) if err != nil || !n.IsAllowed() { log.Println("detects spam") return } manager.AppendToTable(datfile, n) nstamp, err := strconv.ParseInt(stamp, 10, 64) if err != nil { log.Println(err) return } if !recentlist.IsInUpdateRange(nstamp) { return } rec := record.New(datfile, id, nstamp) go updateque.UpdateNodes(rec, n) fmt.Fprintln(w, "OK") }
//postComment creates a record from args and adds it to thread.Cache. //also adds tag if not tag!="" func (m *mchCGI) postComment(threadKey, name, mail, body, passwd, tag string) error { stamp := time.Now().Unix() recbody := make(map[string]string) recbody["body"] = html.EscapeString(body) recbody["name"] = html.EscapeString(name) recbody["mail"] = html.EscapeString(mail) c := thread.NewCache(threadKey) rec := record.New(c.Datfile, "", 0) rec.Build(stamp, recbody, passwd) if rec.IsSpam() { return errSpamM } rec.Sync() if tag != "" { user.Set(c.Datfile, []string{tag}) } go updateque.UpdateNodes(rec, nil) return nil }