package main import ( "crypto/sha1" "encoding/hex" "fmt" "io/ioutil" "math/rand" "net/http" . "template" simplejson "github.com/go-simplejson" ) //const ( // CREATEADDR = "/coinproxy/createaddr" // TRANSINFO = "/coinproxy/query/transinfo" // COINBALANCE = "/coinproxy/coinbalance" // SENDCOINS = "/coinproxy/sendcoins" //) var handler = map[string]func(w http.ResponseWriter, r *http.Request, js *simplejson.Json, body []byte) int{ CREATEADDR: commonFunc, TRANSINFO: commonFunc, COINBALANCE: commonFunc, SENDCOINS: commonFunc, CHAINHEIGHT: commonFunc, LISTUNSPENT: commonFunc, RAWTRANSFER: commonFunc, } func commonHandler(w http.ResponseWriter, r *http.Request) { var ret = 0 defer func() { if ret != 0 { errresp := fmt.Sprintf(`{"errcode":%v,"msg":"%v"}`, ret, GetErrMsg(ret, nil)) w.Write([]byte(errresp)) log.Error("send resp:%v", errresp) return } }() path := r.URL.Path defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) if err != nil { ret = INNER_ERR log.Error("err:%s", err.Error()) return } log.Debug("read body:%v", string(body)) js, err := simplejson.NewJson(body) if err != nil { ret = FORMAT_ERR log.Error("err:%s", err.Error()) return } timestamp := js.Get("timestamp").MustString() signature := js.Get("signature").MustString() var ok bool if ret, ok = checkPermission(timestamp, signature, []byte(path)); !ok { log.Error("check signature err") return } if _, ok := handler[path]; !ok { w.WriteHeader(404) ret = NO_AUTH log.Error("no path,invalid path:%v", path) return } log.Debug("path:%v", path) ret = handler[path](w, r, js, body) return } func commonFunc(w http.ResponseWriter, r *http.Request, js *simplejson.Json, body []byte) int { cointype := js.Get("cointype").MustString() taskH := NewtaskHandler() task := &taskInfo{ cointype: cointype, jshandler: js, urlpath: r.URL.Path, resp: taskH, } chanindex := rand.Int31n(100) % int32(CPUNUM) taskChan[chanindex] <- task resp, err := taskH.waitProcessData() if err != nil { return TIME_OUT } w.Write(resp) log.Debug("resp write:%v", string(resp)) return OK } func checkSignature(body []byte, timestamp, signature string) bool { sha1Contain := sha1.New() byteSha1 := append(body, append([]byte(timestamp), []byte("coinsapi^&#@(*33")...)...) sha1Contain.Write(byteSha1) localSig := hex.EncodeToString(sha1Contain.Sum(nil)) log.Debug("caculate local signature:%v", localSig) return signature == localSig } func checkPermission(timestamp, signature string, body []byte) (int, bool) { if string(body) != SENDCOINS { return OK, true } if checkSignature(body, timestamp, signature) == false { return NO_AUTH, false } return OK, true } ////获取入币交易信息 //func transInfo(w http.ResponseWriter, r *http.Request) { // var ret = 0 // defer func() { // if ret != 0 { // errresp := fmt.Sprintf(`{"errcode":%v,"msg":"%v"}`, ret, GetErrMsg(ret, nil)) // w.Write([]byte(errresp)) // return // } // }() // defer r.Body.Close() // body, err := ioutil.ReadAll(r.Body) // if err != nil { // ret = INNER_ERR // log.Error("err:%s", err.Error()) // return // } // log.Debug("read body:%v", string(body)) // js, err := simplejson.NewJson(body) // if err != nil { // ret = FORMAT_ERR // log.Error("err:%s", err.Error()) // return // } // timestamp := js.Get("timestamp").MustString() // signature := js.Get("signature").MustString() // cointype := js.Get("cointype").MustString() // var ok bool // if ret, ok = checkPermission(timestamp, signature, "post", body); !ok { // //return // } // taskH := NewtaskHandler() // task := &taskInfo{ // cointype: cointype, // jshandler: js, // urlpath: r.URL.Path, // resp: taskH, // } // chanindex := rand.Int31n(100) % int32(CPUNUM) // taskChan[chanindex] <- task // resp, err := taskH.waitProcessData() // if err != nil { // ret = TIME_OUT // return // } // w.Write(resp) // ret = OK // log.Debug("resp write:%v", string(resp)) // return //} //func createAddr(w http.ResponseWriter, r *http.Request) { // var ret = 0 // defer func() { // if ret != 0 { // errresp := fmt.Sprintf(`{"errcode":%v,"msg":"%v"}`, ret, GetErrMsg(ret, nil)) // w.Write([]byte(errresp)) // return // } // }() // defer r.Body.Close() // body, err := ioutil.ReadAll(r.Body) // if err != nil { // ret = INNER_ERR // log.Error("err:%s", err.Error()) // return // } // js, err := simplejson.NewJson(body) // if err != nil { // ret = FORMAT_ERR // log.Error("err:%s", err.Error()) // return // } // timestamp := js.Get("timestamp").MustString() // signature := js.Get("signature").MustString() // cointype := js.Get("cointype").MustString() // var ok bool // if ret, ok = checkPermission(timestamp, signature, "post", body); !ok { // //return // //TODO // } // taskH := NewtaskHandler() // task := &taskInfo{ // cointype: cointype, // jshandler: js, // urlpath: r.URL.Path, // resp: taskH, // } // chanindex := rand.Int31n(100) % int32(CPUNUM) // taskChan[chanindex] <- task // resp, err := taskH.waitProcessData() // if err != nil { // ret = TIME_OUT // return // } // w.Write(resp) // ret = OK // return //}