package main import ( "encoding/json" "errors" "time" ) var PongSecret = "felixfixit" func init() { router.GET("/api/students/:sid/ping", apiHandler(studentHandler(isPinging))) router.GET("/api/students/:sid/pong", apiHandler(studentHandler(func (student Student, body []byte) (interface{}, error) { return student.lastPongs() }))) router.POST("/api/students/:sid/pong", apiHandler(studentHandler(stdPong), sslOnly)) } func isPinging(student Student, body []byte) (interface{}, error) { if pongs, err := student.lastPongs(); err != nil { return nil, err } else if len(pongs) <= 0 { return false, nil } else { return time.Now().Before(pongs[0].Add(time.Second * 90)), nil } } func (s Student) lastPongs() (pongs []time.Time, err error) { if rows, errr := DBQuery("SELECT time FROM student_pong WHERE id_student = ? ORDER BY time DESC", s.Id); errr != nil { return nil, errr } else { defer rows.Close() for rows.Next() { var t time.Time if err = rows.Scan(&t); err != nil { return } pongs = append(pongs, t) } if err = rows.Err(); err != nil { return } return } } func stdPong(student Student, body []byte) (interface{}, error) { var gt givenToken if err := json.Unmarshal(body, >); err != nil { return nil, err } if gt.Token != PongSecret { return nil, errors.New("This is not the expected token.") } if res, err := DBExec("INSERT INTO student_pong (id_student, time) VALUES (?, ?)", student.Id, time.Now()); err != nil { return false, err } else if _, err := res.LastInsertId(); err != nil { return false, err } else { return true, err } }