You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.0 KiB

  1. package processHttp
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "time"
  7. "log"
  8. "github.com/vocdoni/dvote-census/tree"
  9. )
  10. var T tree.Tree
  11. type Claim struct {
  12. ProcessID string `json:"processID"`
  13. ClaimData string `json:"claimData"`
  14. ProofData string `json:"proofData"`
  15. }
  16. type Result struct {
  17. Error bool `json:"error"`
  18. Response string `json:"response"`
  19. }
  20. func reply(resp *Result, w http.ResponseWriter) {
  21. err := json.NewEncoder(w).Encode(resp)
  22. if err != nil {
  23. http.Error(w, err.Error(), 500)
  24. } else {
  25. w.Header().Set("content-type", "application/json")
  26. }
  27. }
  28. func checkRequest(w http.ResponseWriter,req *http.Request) bool {
  29. if req.Body == nil {
  30. http.Error(w, "Please send a request body", 400)
  31. return false
  32. }
  33. return true
  34. }
  35. func claimHandler(w http.ResponseWriter, req *http.Request, op string) {
  36. var c Claim
  37. var resp Result
  38. if ok := checkRequest(w, req); !ok { return }
  39. // Decode JSON
  40. err := json.NewDecoder(req.Body).Decode(&c)
  41. if err != nil {
  42. http.Error(w, err.Error(), 400)
  43. return
  44. }
  45. // Process data
  46. log.Printf("Received: %s,%s,%s ", c.ProcessID, c.ClaimData, c.ProofData)
  47. resp.Error = false
  48. resp.Response = ""
  49. if len(c.ProcessID) > 0 {
  50. T.Namespace = c.ProcessID
  51. } else {
  52. resp.Error = true
  53. resp.Response = "processID is not valid"
  54. reply(&resp, w)
  55. return
  56. }
  57. if len(c.ClaimData) < 0 {
  58. resp.Error = true
  59. resp.Response = "data not valid"
  60. reply(&resp, w)
  61. return
  62. }
  63. if op == "add" {
  64. err = T.AddClaim([]byte(c.ClaimData))
  65. }
  66. if op == "gen" {
  67. resp.Response, err = T.GenProof([]byte(c.ClaimData))
  68. }
  69. if op == "root" {
  70. resp.Response = T.GetRoot()
  71. }
  72. if op == "check" {
  73. if len(c.ProofData) < 1 {
  74. resp.Error = true
  75. resp.Response = "proofData not provided"
  76. reply(&resp, w)
  77. return
  78. }
  79. var validProof bool
  80. validProof, err = T.CheckProof([]byte(c.ClaimData), c.ProofData)
  81. if validProof {
  82. resp.Response = "valid"
  83. } else {
  84. resp.Response = "invalid"
  85. }
  86. }
  87. if err != nil {
  88. resp.Error = true
  89. resp.Response = fmt.Sprint(err)
  90. log.Print(err)
  91. reply(&resp, w)
  92. return
  93. }
  94. reply(&resp, w)
  95. }
  96. func Listen(port int, proto string) {
  97. srv := &http.Server{
  98. Addr: fmt.Sprintf(":%d", port),
  99. ReadHeaderTimeout: 4 * time.Second,
  100. ReadTimeout: 4 * time.Second,
  101. WriteTimeout: 4 * time.Second,
  102. IdleTimeout: 3 * time.Second,
  103. }
  104. http.HandleFunc("/addClaim", func(w http.ResponseWriter, r *http.Request) {
  105. claimHandler(w, r, "add")})
  106. http.HandleFunc("/genProof", func(w http.ResponseWriter, r *http.Request) {
  107. claimHandler(w, r, "gen")})
  108. http.HandleFunc("/checkProof", func(w http.ResponseWriter, r *http.Request) {
  109. claimHandler(w, r, "check")})
  110. http.HandleFunc("/getRoot", func(w http.ResponseWriter, r *http.Request) {
  111. claimHandler(w, r, "root")})
  112. if proto == "https" {
  113. log.Print("Starting server in https mode")
  114. if err := srv.ListenAndServeTLS("server.crt", "server.key"); err != nil {
  115. panic(err)
  116. }
  117. }
  118. if proto == "http" {
  119. log.Print("Starting server in http mode")
  120. srv.SetKeepAlivesEnabled(false)
  121. if err := srv.ListenAndServe(); err != nil {
  122. panic(err)
  123. }
  124. }
  125. }