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