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-census/tree"
 10)
 11
 12var T tree.Tree
 13
 14type Claim struct {
 15	CensusID string `json:"censusID"`
 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.CensusID, c.ClaimData, c.ProofData)
 55	resp.Error = false
 56	resp.Response = ""
 57
 58	if len(c.CensusID) > 0 {
 59		T.Namespace = c.CensusID
 60	} else {
 61		resp.Error = true
 62		resp.Response = "CensusID 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}