arnaucube
arnaucube/go-dvotePublic Self-hosted repository
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-process/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 == "check" {
 83		if len(c.ProofData) < 1 {
 84			resp.Error = true
 85			resp.Response = "proofData not provided"
 86			reply(&resp, w)
 87			return
 88		}
 89		var validProof bool
 90		validProof, err = T.CheckProof([]byte(c.ClaimData), c.ProofData)
 91		if validProof {
 92			resp.Response = "valid"
 93		} else {
 94			resp.Response = "invalid"
 95		}
 96	}
 97
 98	if err != nil {
 99		resp.Error = true
100		resp.Response = fmt.Sprint(err)
101		log.Print(err)
102		reply(&resp, w)
103		return
104	}
105
106	reply(&resp, w)
107}
108
109func Listen(port int, proto string) {
110	srv := &http.Server{
111		Addr: fmt.Sprintf(":%d", port),
112	 	ReadHeaderTimeout: 4 * time.Second,
113		ReadTimeout: 4 * time.Second,
114		WriteTimeout: 4 * time.Second,
115		IdleTimeout: 3 * time.Second,
116	}
117
118	http.HandleFunc("/addClaim", func(w http.ResponseWriter, r *http.Request) {
119    		claimHandler(w, r, "add")})
120	http.HandleFunc("/genProof", func(w http.ResponseWriter, r *http.Request) {
121    		claimHandler(w, r, "gen")})
122	http.HandleFunc("/checkProof", func(w http.ResponseWriter, r *http.Request) {
123    		claimHandler(w, r, "check")})
124
125	if proto == "https" {
126	  log.Print("Starting server in https mode")
127	  if err := srv.ListenAndServeTLS("server.crt", "server.key"); err != nil {
128	    panic(err)
129	  }
130	}
131	if proto == "http" {
132	  log.Print("Starting server in http mode")
133	  srv.SetKeepAlivesEnabled(false)
134	  if err := srv.ListenAndServe(); err != nil {
135	    panic(err)
136	  }
137	}
138}