Add apiSendTx via POST request

This commit is contained in:
Martin Boehm 2018-10-25 19:40:07 +02:00
parent e9f5dfdc54
commit 77c64e97b6
2 changed files with 63 additions and 20 deletions

View File

@ -9,6 +9,7 @@ import (
"encoding/json"
"fmt"
"html/template"
"io/ioutil"
"math/big"
"net/http"
"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) {
type jsonError struct {
Error string `json:"error"`
Text string `json:"error"`
HTTPStatus int `json:"-"`
}
return func(w http.ResponseWriter, r *http.Request) {
var data interface{}
@ -200,33 +202,37 @@ func (s *PublicServer) jsonHandler(handler func(r *http.Request) (interface{}, e
if e := recover(); e != nil {
glog.Error(getFunctionName(handler), " recovered from panic: ", e)
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 {
data = jsonError{"Internal server error"}
data = jsonError{"Internal server error", http.StatusInternalServerError}
}
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
if _, isError := data.(jsonError); isError {
w.WriteHeader(http.StatusInternalServerError)
if e, isError := data.(jsonError); isError {
w.WriteHeader(e.HTTPStatus)
}
json.NewEncoder(w).Encode(data)
}()
data, err = handler(r)
if err != nil || data == nil {
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 {
if err != nil {
glog.Error(getFunctionName(handler), " error: ", err)
}
if s.debug {
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 {
data = jsonError{fmt.Sprintf("Internal server error: %v", err)}
data = jsonError{fmt.Sprintf("Internal server error: %v", err), http.StatusInternalServerError}
}
} 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) {
var err error
var res resultSendTransaction
var hex string
s.metrics.ExplorerViews.With(common.Labels{"action": "api-sendtx"}).Inc()
if i := strings.LastIndexByte(r.URL.Path, '/'); i > 0 {
hex := r.URL.Path[i+1:]
if len(hex) > 0 {
if len(hex) > 0 {
res.Result, err = s.chain.SendRawTransaction(hex)
return res, err
}
if r.Method == http.MethodPost {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil, api.NewApiError("Missing tx blob", true)
}
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)
}

View File

@ -109,7 +109,7 @@ func newGetRequest(u string) *http.Request {
return r
}
func newPostRequest(u string, formdata ...string) *http.Request {
func newPostFormRequest(u string, formdata ...string) *http.Request {
form := url.Values{}
for i := 0; i < len(formdata)-1; i += 2 {
form.Add(formdata[i], formdata[i+1])
@ -122,6 +122,15 @@ func newPostRequest(u string, formdata ...string) *http.Request {
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) {
tests := []struct {
name string
@ -331,7 +340,7 @@ func httpTests(t *testing.T, ts *httptest.Server) {
},
{
name: "explorerSendTx POST",
r: newPostRequest(ts.URL+"/sendtx", "hex", "12341234"),
r: newPostFormRequest(ts.URL+"/sendtx", "hex", "12341234"),
status: http.StatusOK,
contentType: "text/html; charset=utf-8",
body: []string{
@ -375,7 +384,7 @@ func httpTests(t *testing.T, ts *httptest.Server) {
{
name: "apiTx - not found",
r: newGetRequest(ts.URL + "/api/tx/1232e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07"),
status: http.StatusInternalServerError,
status: http.StatusBadRequest,
contentType: "application/json; charset=utf-8",
body: []string{
`{"error":"Tx not found, Not found"}`,
@ -401,13 +410,31 @@ func httpTests(t *testing.T, ts *httptest.Server) {
},
{
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,
contentType: "application/json; charset=utf-8",
body: []string{
`{"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",
r: newGetRequest(ts.URL + "/api/estimatefee/123?conservative=false"),