routes.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package main
  2. import (
  3. "html"
  4. "io"
  5. "log"
  6. "strings"
  7. "time"
  8. "github.com/gin-gonic/gin"
  9. )
  10. func rateLimit(c *gin.Context) {
  11. ip := c.ClientIP()
  12. value := ips.Add(ip, 1)
  13. log.Printf("ip: %s, count: %f\n", ip, value)
  14. if value > 300 {
  15. if int(value)%200 == 0 {
  16. log.Println("ip blocked")
  17. }
  18. c.AbortWithStatus(503)
  19. }
  20. }
  21. func index(c *gin.Context) {
  22. c.Redirect(301, "/room/hn")
  23. }
  24. func roomGET(c *gin.Context) {
  25. roomid := c.ParamValue("roomid")
  26. nick := c.FormValue("nick")
  27. if len(nick) < 2 {
  28. nick = ""
  29. }
  30. if len(nick) > 13 {
  31. nick = nick[0:12] + "..."
  32. }
  33. c.HTML(200, "room_login.templ.html", gin.H{
  34. "roomid": roomid,
  35. "nick": nick,
  36. "timestamp": time.Now().Unix(),
  37. })
  38. }
  39. func roomPOST(c *gin.Context) {
  40. roomid := c.ParamValue("roomid")
  41. nick := c.FormValue("nick")
  42. message := c.PostFormValue("message")
  43. message = strings.TrimSpace(message)
  44. validMessage := len(message) > 1 && len(message) < 200
  45. validNick := len(nick) > 1 && len(nick) < 14
  46. if !validMessage || !validNick {
  47. c.JSON(400, gin.H{
  48. "status": "failed",
  49. "error": "the message or nickname is too long",
  50. })
  51. return
  52. }
  53. post := gin.H{
  54. "nick": html.EscapeString(nick),
  55. "message": html.EscapeString(message),
  56. }
  57. messages.Add("inbound", 1)
  58. room(roomid).Submit(post)
  59. c.JSON(200, post)
  60. }
  61. func streamRoom(c *gin.Context) {
  62. roomid := c.ParamValue("roomid")
  63. listener := openListener(roomid)
  64. ticker := time.NewTicker(1 * time.Second)
  65. users.Add("connected", 1)
  66. defer func() {
  67. closeListener(roomid, listener)
  68. ticker.Stop()
  69. users.Add("disconnected", 1)
  70. }()
  71. c.Stream(func(w io.Writer) bool {
  72. select {
  73. case msg := <-listener:
  74. messages.Add("outbound", 1)
  75. c.SSEvent("message", msg)
  76. case <-ticker.C:
  77. c.SSEvent("stats", Stats())
  78. }
  79. return true
  80. })
  81. }