Add apiSendTx via POST request
This commit is contained in:
parent
e9f5dfdc54
commit
77c64e97b6
@ -9,6 +9,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -191,7 +192,8 @@ func getFunctionName(i interface{}) string {
|
|||||||
|
|
||||||
func (s *PublicServer) jsonHandler(handler func(r *http.Request) (interface{}, error)) func(w http.ResponseWriter, r *http.Request) {
|
func (s *PublicServer) jsonHandler(handler func(r *http.Request) (interface{}, error)) func(w http.ResponseWriter, r *http.Request) {
|
||||||
type jsonError struct {
|
type jsonError struct {
|
||||||
Error string `json:"error"`
|
Text string `json:"error"`
|
||||||
|
HTTPStatus int `json:"-"`
|
||||||
}
|
}
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var data interface{}
|
var data interface{}
|
||||||
@ -200,33 +202,37 @@ func (s *PublicServer) jsonHandler(handler func(r *http.Request) (interface{}, e
|
|||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
glog.Error(getFunctionName(handler), " recovered from panic: ", e)
|
glog.Error(getFunctionName(handler), " recovered from panic: ", e)
|
||||||
if s.debug {
|
if s.debug {
|
||||||
data = jsonError{fmt.Sprint("Internal server error: recovered from panic ", e)}
|
data = jsonError{fmt.Sprint("Internal server error: recovered from panic ", e), http.StatusInternalServerError}
|
||||||
} else {
|
} else {
|
||||||
data = jsonError{"Internal server error"}
|
data = jsonError{"Internal server error", http.StatusInternalServerError}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
if _, isError := data.(jsonError); isError {
|
if e, isError := data.(jsonError); isError {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(e.HTTPStatus)
|
||||||
}
|
}
|
||||||
json.NewEncoder(w).Encode(data)
|
json.NewEncoder(w).Encode(data)
|
||||||
}()
|
}()
|
||||||
data, err = handler(r)
|
data, err = handler(r)
|
||||||
if err != nil || data == nil {
|
if err != nil || data == nil {
|
||||||
if apiErr, ok := err.(*api.ApiError); ok {
|
if apiErr, ok := err.(*api.ApiError); ok {
|
||||||
data = jsonError{apiErr.Error()}
|
if apiErr.Public {
|
||||||
|
data = jsonError{apiErr.Error(), http.StatusBadRequest}
|
||||||
|
} else {
|
||||||
|
data = jsonError{apiErr.Error(), http.StatusInternalServerError}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error(getFunctionName(handler), " error: ", err)
|
glog.Error(getFunctionName(handler), " error: ", err)
|
||||||
}
|
}
|
||||||
if s.debug {
|
if s.debug {
|
||||||
if data != nil {
|
if data != nil {
|
||||||
data = jsonError{fmt.Sprintf("Internal server error: %v, data %+v", err, data)}
|
data = jsonError{fmt.Sprintf("Internal server error: %v, data %+v", err, data), http.StatusInternalServerError}
|
||||||
} else {
|
} else {
|
||||||
data = jsonError{fmt.Sprintf("Internal server error: %v", err)}
|
data = jsonError{fmt.Sprintf("Internal server error: %v", err), http.StatusInternalServerError}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
data = jsonError{"Internal server error"}
|
data = jsonError{"Internal server error", http.StatusInternalServerError}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -700,15 +706,25 @@ type resultSendTransaction struct {
|
|||||||
func (s *PublicServer) apiSendTx(r *http.Request) (interface{}, error) {
|
func (s *PublicServer) apiSendTx(r *http.Request) (interface{}, error) {
|
||||||
var err error
|
var err error
|
||||||
var res resultSendTransaction
|
var res resultSendTransaction
|
||||||
|
var hex string
|
||||||
s.metrics.ExplorerViews.With(common.Labels{"action": "api-sendtx"}).Inc()
|
s.metrics.ExplorerViews.With(common.Labels{"action": "api-sendtx"}).Inc()
|
||||||
if i := strings.LastIndexByte(r.URL.Path, '/'); i > 0 {
|
if r.Method == http.MethodPost {
|
||||||
hex := r.URL.Path[i+1:]
|
data, err := ioutil.ReadAll(r.Body)
|
||||||
if len(hex) > 0 {
|
if err != nil {
|
||||||
if len(hex) > 0 {
|
return nil, api.NewApiError("Missing tx blob", true)
|
||||||
res.Result, err = s.chain.SendRawTransaction(hex)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
hex = string(data)
|
||||||
|
} else {
|
||||||
|
if i := strings.LastIndexByte(r.URL.Path, '/'); i > 0 {
|
||||||
|
hex = r.URL.Path[i+1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(hex) > 0 {
|
||||||
|
res.Result, err = s.chain.SendRawTransaction(hex)
|
||||||
|
if err != nil {
|
||||||
|
return nil, api.NewApiError(err.Error(), true)
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
}
|
}
|
||||||
return nil, api.NewApiError("Missing tx blob", true)
|
return nil, api.NewApiError("Missing tx blob", true)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -109,7 +109,7 @@ func newGetRequest(u string) *http.Request {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPostRequest(u string, formdata ...string) *http.Request {
|
func newPostFormRequest(u string, formdata ...string) *http.Request {
|
||||||
form := url.Values{}
|
form := url.Values{}
|
||||||
for i := 0; i < len(formdata)-1; i += 2 {
|
for i := 0; i < len(formdata)-1; i += 2 {
|
||||||
form.Add(formdata[i], formdata[i+1])
|
form.Add(formdata[i], formdata[i+1])
|
||||||
@ -122,6 +122,15 @@ func newPostRequest(u string, formdata ...string) *http.Request {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newPostRequest(u string, body string) *http.Request {
|
||||||
|
r, err := http.NewRequest("POST", u, strings.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
glog.Fatal(err)
|
||||||
|
}
|
||||||
|
r.Header.Add("Content-Type", "application/octet-stream")
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
func httpTests(t *testing.T, ts *httptest.Server) {
|
func httpTests(t *testing.T, ts *httptest.Server) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@ -331,7 +340,7 @@ func httpTests(t *testing.T, ts *httptest.Server) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "explorerSendTx POST",
|
name: "explorerSendTx POST",
|
||||||
r: newPostRequest(ts.URL+"/sendtx", "hex", "12341234"),
|
r: newPostFormRequest(ts.URL+"/sendtx", "hex", "12341234"),
|
||||||
status: http.StatusOK,
|
status: http.StatusOK,
|
||||||
contentType: "text/html; charset=utf-8",
|
contentType: "text/html; charset=utf-8",
|
||||||
body: []string{
|
body: []string{
|
||||||
@ -375,7 +384,7 @@ func httpTests(t *testing.T, ts *httptest.Server) {
|
|||||||
{
|
{
|
||||||
name: "apiTx - not found",
|
name: "apiTx - not found",
|
||||||
r: newGetRequest(ts.URL + "/api/tx/1232e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07"),
|
r: newGetRequest(ts.URL + "/api/tx/1232e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07"),
|
||||||
status: http.StatusInternalServerError,
|
status: http.StatusBadRequest,
|
||||||
contentType: "application/json; charset=utf-8",
|
contentType: "application/json; charset=utf-8",
|
||||||
body: []string{
|
body: []string{
|
||||||
`{"error":"Tx not found, Not found"}`,
|
`{"error":"Tx not found, Not found"}`,
|
||||||
@ -401,13 +410,31 @@ func httpTests(t *testing.T, ts *httptest.Server) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "apiSendTx",
|
name: "apiSendTx",
|
||||||
r: newGetRequest(ts.URL + "/api/sendtx/123456"),
|
r: newGetRequest(ts.URL + "/api/sendtx/1234567890"),
|
||||||
|
status: http.StatusBadRequest,
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
body: []string{
|
||||||
|
`{"error":"Invalid data"}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "apiSendTx POST",
|
||||||
|
r: newPostRequest(ts.URL+"/api/sendtx/", "123456"),
|
||||||
status: http.StatusOK,
|
status: http.StatusOK,
|
||||||
contentType: "application/json; charset=utf-8",
|
contentType: "application/json; charset=utf-8",
|
||||||
body: []string{
|
body: []string{
|
||||||
`{"result":"9876"}`,
|
`{"result":"9876"}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "apiSendTx POST empty",
|
||||||
|
r: newPostRequest(ts.URL+"/api/sendtx", ""),
|
||||||
|
status: http.StatusBadRequest,
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
body: []string{
|
||||||
|
`{"error":"Missing tx blob"}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "apiEstimateFee",
|
name: "apiEstimateFee",
|
||||||
r: newGetRequest(ts.URL + "/api/estimatefee/123?conservative=false"),
|
r: newGetRequest(ts.URL + "/api/estimatefee/123?conservative=false"),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user