mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
etcdhttp: use Form values over query parameters
This commit is contained in:
parent
7c03704b19
commit
52ddd389ff
@ -254,6 +254,9 @@ func genId() int64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseRequest converts a received http.Request to a server Request,
|
||||||
|
// performing validation of supplied fields as appropriate.
|
||||||
|
// If any validation fails, an empty Request and non-nil error is returned.
|
||||||
func parseRequest(r *http.Request, id int64) (etcdserverpb.Request, error) {
|
func parseRequest(r *http.Request, id int64) (etcdserverpb.Request, error) {
|
||||||
emptyReq := etcdserverpb.Request{}
|
emptyReq := etcdserverpb.Request{}
|
||||||
|
|
||||||
@ -264,7 +267,6 @@ func parseRequest(r *http.Request, id int64) (etcdserverpb.Request, error) {
|
|||||||
err.Error(),
|
err.Error(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
q := r.URL.Query()
|
|
||||||
|
|
||||||
if !strings.HasPrefix(r.URL.Path, keysPrefix) {
|
if !strings.HasPrefix(r.URL.Path, keysPrefix) {
|
||||||
return emptyReq, etcdErr.NewRequestError(
|
return emptyReq, etcdErr.NewRequestError(
|
||||||
@ -275,61 +277,49 @@ func parseRequest(r *http.Request, id int64) (etcdserverpb.Request, error) {
|
|||||||
p := r.URL.Path[len(keysPrefix):]
|
p := r.URL.Path[len(keysPrefix):]
|
||||||
|
|
||||||
var pIdx, wIdx, ttl uint64
|
var pIdx, wIdx, ttl uint64
|
||||||
if pIdxS := q.Get("prevIndex"); pIdxS != "" {
|
if pIdx, err = getUint64(r.Form, "prevIndex"); err != nil {
|
||||||
if pIdx, err = parseUint64(pIdxS); err != nil {
|
|
||||||
return emptyReq, etcdErr.NewRequestError(
|
return emptyReq, etcdErr.NewRequestError(
|
||||||
etcdErr.EcodeIndexNaN,
|
etcdErr.EcodeIndexNaN,
|
||||||
fmt.Sprintf("invalid value for prevIndex: %q", pIdxS),
|
fmt.Sprintf("invalid value for prevIndex"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
if wIdx, err = getUint64(r.Form, "waitIndex"); err != nil {
|
||||||
if wIdxS := q.Get("waitIndex"); wIdxS != "" {
|
|
||||||
if wIdx, err = parseUint64(wIdxS); err != nil {
|
|
||||||
return emptyReq, etcdErr.NewRequestError(
|
return emptyReq, etcdErr.NewRequestError(
|
||||||
etcdErr.EcodeIndexNaN,
|
etcdErr.EcodeIndexNaN,
|
||||||
fmt.Sprintf("invalid value for waitIndex: %q", wIdxS),
|
fmt.Sprintf("invalid value for waitIndex"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
if ttl, err = getUint64(r.Form, "ttl"); err != nil {
|
||||||
if ttlS := q.Get("ttl"); ttlS != "" {
|
|
||||||
if ttl, err = parseUint64(ttlS); err != nil {
|
|
||||||
return emptyReq, etcdErr.NewRequestError(
|
return emptyReq, etcdErr.NewRequestError(
|
||||||
etcdErr.EcodeTTLNaN,
|
etcdErr.EcodeTTLNaN,
|
||||||
fmt.Sprintf("invalid value for ttl: %q", ttlS),
|
`invalid value for "ttl"`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var rec, sort, wait bool
|
var rec, sort, wait bool
|
||||||
if recS := q.Get("recursive"); recS != "" {
|
if rec, err = getBool(r.Form, "recursive"); err != nil {
|
||||||
if rec, err = strconv.ParseBool(recS); err != nil {
|
|
||||||
return emptyReq, etcdErr.NewRequestError(
|
return emptyReq, etcdErr.NewRequestError(
|
||||||
etcdErr.EcodeInvalidField,
|
etcdErr.EcodeInvalidField,
|
||||||
fmt.Sprintf("invalid value for recursive: %q", recS),
|
`invalid value for "recursive"`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
if sort, err = getBool(r.Form, "sorted"); err != nil {
|
||||||
if sortS := q.Get("sorted"); sortS != "" {
|
|
||||||
if sort, err = strconv.ParseBool(sortS); err != nil {
|
|
||||||
return emptyReq, etcdErr.NewRequestError(
|
return emptyReq, etcdErr.NewRequestError(
|
||||||
etcdErr.EcodeInvalidField,
|
etcdErr.EcodeInvalidField,
|
||||||
fmt.Sprintf("invalid value for sorted: %q", sortS),
|
`invalid value for "sorted"`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
if wait, err = getBool(r.Form, "wait"); err != nil {
|
||||||
if waitS := q.Get("wait"); waitS != "" {
|
|
||||||
if wait, err = strconv.ParseBool(waitS); err != nil {
|
|
||||||
return emptyReq, etcdErr.NewRequestError(
|
return emptyReq, etcdErr.NewRequestError(
|
||||||
etcdErr.EcodeInvalidField,
|
etcdErr.EcodeInvalidField,
|
||||||
fmt.Sprintf("invalid value for wait: %q", waitS),
|
`invalid value for "wait"`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// prevExists is nullable, so leave it null if not specified
|
// prevExists is nullable, so leave it null if not specified
|
||||||
var pe *bool
|
var pe *bool
|
||||||
if _, ok := q["prevExists"]; ok {
|
if _, ok := r.Form["prevExists"]; ok {
|
||||||
bv, err := strconv.ParseBool(q.Get("prevExists"))
|
bv, err := getBool(r.Form, "prevExists")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return emptyReq, etcdErr.NewRequestError(
|
return emptyReq, etcdErr.NewRequestError(
|
||||||
etcdErr.EcodeInvalidField,
|
etcdErr.EcodeInvalidField,
|
||||||
@ -344,7 +334,7 @@ func parseRequest(r *http.Request, id int64) (etcdserverpb.Request, error) {
|
|||||||
Method: r.Method,
|
Method: r.Method,
|
||||||
Path: p,
|
Path: p,
|
||||||
Val: r.FormValue("value"),
|
Val: r.FormValue("value"),
|
||||||
PrevValue: q.Get("prevValue"),
|
PrevValue: r.FormValue("prevValue"),
|
||||||
PrevIndex: pIdx,
|
PrevIndex: pIdx,
|
||||||
PrevExists: pe,
|
PrevExists: pe,
|
||||||
Recursive: rec,
|
Recursive: rec,
|
||||||
@ -367,8 +357,26 @@ func parseRequest(r *http.Request, id int64) (etcdserverpb.Request, error) {
|
|||||||
return rr, nil
|
return rr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseUint64(s string) (uint64, error) {
|
// getUint64 extracts a uint64 by the given key from a Form. If the key does
|
||||||
return strconv.ParseUint(s, 10, 64)
|
// not exist in the form, 0 is returned. If the key exists but the value is
|
||||||
|
// badly formed, an error is returned. If multiple values are present only the
|
||||||
|
// first is considered.
|
||||||
|
func getUint64(form url.Values, key string) (i uint64, err error) {
|
||||||
|
if vals, ok := form[key]; ok {
|
||||||
|
i, err = strconv.ParseUint(vals[0], 10, 64)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// getBool extracts a bool by the given key from a Form. If the key does not
|
||||||
|
// exist in the form, false is returned. If the key exists but the value is
|
||||||
|
// badly formed, an error is returned. If multiple values are present only the
|
||||||
|
// first is considered.
|
||||||
|
func getBool(form url.Values, key string) (b bool, err error) {
|
||||||
|
if vals, ok := form[key]; ok {
|
||||||
|
b, err = strconv.ParseBool(vals[0])
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeError logs and writes the given Error to the ResponseWriter
|
// writeError logs and writes the given Error to the ResponseWriter
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -34,6 +35,18 @@ func mustNewRequest(t *testing.T, p string) *http.Request {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mustNewForm takes a set of Values and constructs a PUT *http.Request,
|
||||||
|
// with a URL constructed from appending the given path to the standard keysPrefix
|
||||||
|
func mustNewForm(t *testing.T, p string, vals url.Values) *http.Request {
|
||||||
|
u := mustNewURL(t, path.Join(keysPrefix, p))
|
||||||
|
req, err := http.NewRequest("PUT", u.String(), strings.NewReader(vals.Encode()))
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating new request: %v", err)
|
||||||
|
}
|
||||||
|
return req
|
||||||
|
}
|
||||||
|
|
||||||
func TestBadParseRequest(t *testing.T) {
|
func TestBadParseRequest(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
in *http.Request
|
in *http.Request
|
||||||
@ -56,56 +69,90 @@ func TestBadParseRequest(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// bad values for prevIndex, waitIndex, ttl
|
// bad values for prevIndex, waitIndex, ttl
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?prevIndex=foo"),
|
mustNewForm(t, "foo", url.Values{"prevIndex": []string{"garbage"}}),
|
||||||
etcdErr.EcodeIndexNaN,
|
etcdErr.EcodeIndexNaN,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?prevIndex=1.5"),
|
mustNewForm(t, "foo", url.Values{"prevIndex": []string{"1.5"}}),
|
||||||
etcdErr.EcodeIndexNaN,
|
etcdErr.EcodeIndexNaN,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?prevIndex=-1"),
|
mustNewForm(t, "foo", url.Values{"prevIndex": []string{"-1"}}),
|
||||||
etcdErr.EcodeIndexNaN,
|
etcdErr.EcodeIndexNaN,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?waitIndex=garbage"),
|
mustNewForm(t, "foo", url.Values{"waitIndex": []string{"garbage"}}),
|
||||||
etcdErr.EcodeIndexNaN,
|
etcdErr.EcodeIndexNaN,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?waitIndex=??"),
|
mustNewForm(t, "foo", url.Values{"waitIndex": []string{"??"}}),
|
||||||
etcdErr.EcodeIndexNaN,
|
etcdErr.EcodeIndexNaN,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?ttl=-1"),
|
mustNewForm(t, "foo", url.Values{"ttl": []string{"-1"}}),
|
||||||
etcdErr.EcodeTTLNaN,
|
etcdErr.EcodeTTLNaN,
|
||||||
},
|
},
|
||||||
// bad values for recursive, sorted, wait
|
// bad values for recursive, sorted, wait, prevExists
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?recursive=hahaha"),
|
mustNewForm(t, "foo", url.Values{"recursive": []string{"hahaha"}}),
|
||||||
etcdErr.EcodeInvalidField,
|
etcdErr.EcodeInvalidField,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?recursive=1234"),
|
mustNewForm(t, "foo", url.Values{"recursive": []string{"1234"}}),
|
||||||
etcdErr.EcodeInvalidField,
|
etcdErr.EcodeInvalidField,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?recursive=?"),
|
mustNewForm(t, "foo", url.Values{"recursive": []string{"?"}}),
|
||||||
etcdErr.EcodeInvalidField,
|
etcdErr.EcodeInvalidField,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?sorted=hahaha"),
|
mustNewForm(t, "foo", url.Values{"sorted": []string{"?"}}),
|
||||||
etcdErr.EcodeInvalidField,
|
etcdErr.EcodeInvalidField,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?sorted=!!"),
|
mustNewForm(t, "foo", url.Values{"sorted": []string{"x"}}),
|
||||||
etcdErr.EcodeInvalidField,
|
etcdErr.EcodeInvalidField,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?wait=notreally"),
|
mustNewForm(t, "foo", url.Values{"wait": []string{"?!"}}),
|
||||||
etcdErr.EcodeInvalidField,
|
etcdErr.EcodeInvalidField,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mustNewRequest(t, "?wait=what!"),
|
mustNewForm(t, "foo", url.Values{"wait": []string{"yes"}}),
|
||||||
|
etcdErr.EcodeInvalidField,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mustNewForm(t, "foo", url.Values{"prevExists": []string{"yes"}}),
|
||||||
|
etcdErr.EcodeInvalidField,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mustNewForm(t, "foo", url.Values{"prevExists": []string{"#2"}}),
|
||||||
|
etcdErr.EcodeInvalidField,
|
||||||
|
},
|
||||||
|
// query values are considered
|
||||||
|
{
|
||||||
|
mustNewRequest(t, "foo?prevExists=wrong"),
|
||||||
|
etcdErr.EcodeInvalidField,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mustNewRequest(t, "foo?ttl=wrong"),
|
||||||
|
etcdErr.EcodeTTLNaN,
|
||||||
|
},
|
||||||
|
// but body takes precedence if both are specified
|
||||||
|
{
|
||||||
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo?ttl=12",
|
||||||
|
url.Values{"ttl": []string{"garbage"}},
|
||||||
|
),
|
||||||
|
etcdErr.EcodeTTLNaN,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo?prevExists=false",
|
||||||
|
url.Values{"prevExists": []string{"yes"}},
|
||||||
|
),
|
||||||
etcdErr.EcodeInvalidField,
|
etcdErr.EcodeInvalidField,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -122,6 +169,7 @@ func TestBadParseRequest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
if ee.ErrorCode != tt.wcode {
|
if ee.ErrorCode != tt.wcode {
|
||||||
t.Errorf("#%d: code=%d, want %v", i, ee.ErrorCode, tt.wcode)
|
t.Errorf("#%d: code=%d, want %v", i, ee.ErrorCode, tt.wcode)
|
||||||
|
t.Logf("cause: %#v", ee.Cause)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(got, etcdserverpb.Request{}) {
|
if !reflect.DeepEqual(got, etcdserverpb.Request{}) {
|
||||||
t.Errorf("#%d: unexpected non-empty Request: %#v", i, got)
|
t.Errorf("#%d: unexpected non-empty Request: %#v", i, got)
|
||||||
@ -144,67 +192,152 @@ func TestGoodParseRequest(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
// value specified
|
// value specified
|
||||||
mustNewRequest(t, "foo?value=some_value"),
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo",
|
||||||
|
url.Values{"value": []string{"some_value"}},
|
||||||
|
),
|
||||||
etcdserverpb.Request{
|
etcdserverpb.Request{
|
||||||
Id: 1234,
|
Id: 1234,
|
||||||
|
Method: "PUT",
|
||||||
Val: "some_value",
|
Val: "some_value",
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// prevIndex specified
|
// prevIndex specified
|
||||||
mustNewRequest(t, "foo?prevIndex=98765"),
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo",
|
||||||
|
url.Values{"prevIndex": []string{"98765"}},
|
||||||
|
),
|
||||||
etcdserverpb.Request{
|
etcdserverpb.Request{
|
||||||
Id: 1234,
|
Id: 1234,
|
||||||
|
Method: "PUT",
|
||||||
PrevIndex: 98765,
|
PrevIndex: 98765,
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// recursive specified
|
// recursive specified
|
||||||
mustNewRequest(t, "foo?recursive=true"),
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo",
|
||||||
|
url.Values{"recursive": []string{"true"}},
|
||||||
|
),
|
||||||
etcdserverpb.Request{
|
etcdserverpb.Request{
|
||||||
Id: 1234,
|
Id: 1234,
|
||||||
|
Method: "PUT",
|
||||||
Recursive: true,
|
Recursive: true,
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// sorted specified
|
// sorted specified
|
||||||
mustNewRequest(t, "foo?sorted=true"),
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo",
|
||||||
|
url.Values{"sorted": []string{"true"}},
|
||||||
|
),
|
||||||
etcdserverpb.Request{
|
etcdserverpb.Request{
|
||||||
Id: 1234,
|
Id: 1234,
|
||||||
|
Method: "PUT",
|
||||||
Sorted: true,
|
Sorted: true,
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// wait specified
|
// wait specified
|
||||||
mustNewRequest(t, "foo?wait=true"),
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo",
|
||||||
|
url.Values{"wait": []string{"true"}},
|
||||||
|
),
|
||||||
etcdserverpb.Request{
|
etcdserverpb.Request{
|
||||||
Id: 1234,
|
Id: 1234,
|
||||||
|
Method: "PUT",
|
||||||
Wait: true,
|
Wait: true,
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// prevExists should be non-null if specified
|
// prevExists should be non-null if specified
|
||||||
mustNewRequest(t, "foo?prevExists=true"),
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo",
|
||||||
|
url.Values{"prevExists": []string{"true"}},
|
||||||
|
),
|
||||||
etcdserverpb.Request{
|
etcdserverpb.Request{
|
||||||
Id: 1234,
|
Id: 1234,
|
||||||
|
Method: "PUT",
|
||||||
PrevExists: boolp(true),
|
PrevExists: boolp(true),
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// prevExists should be non-null if specified
|
// prevExists should be non-null if specified
|
||||||
mustNewRequest(t, "foo?prevExists=false"),
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo",
|
||||||
|
url.Values{"prevExists": []string{"false"}},
|
||||||
|
),
|
||||||
etcdserverpb.Request{
|
etcdserverpb.Request{
|
||||||
Id: 1234,
|
Id: 1234,
|
||||||
|
Method: "PUT",
|
||||||
PrevExists: boolp(false),
|
PrevExists: boolp(false),
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// mix various fields
|
||||||
|
{
|
||||||
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo",
|
||||||
|
url.Values{
|
||||||
|
"value": []string{"some value"},
|
||||||
|
"prevExists": []string{"true"},
|
||||||
|
"prevValue": []string{"previous value"},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
etcdserverpb.Request{
|
||||||
|
Id: 1234,
|
||||||
|
Method: "PUT",
|
||||||
|
PrevExists: boolp(true),
|
||||||
|
PrevValue: "previous value",
|
||||||
|
Val: "some value",
|
||||||
|
Path: "/foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// query parameters should be used if given
|
||||||
|
{
|
||||||
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo?prevValue=woof",
|
||||||
|
url.Values{},
|
||||||
|
),
|
||||||
|
etcdserverpb.Request{
|
||||||
|
Id: 1234,
|
||||||
|
Method: "PUT",
|
||||||
|
PrevValue: "woof",
|
||||||
|
Path: "/foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// but form values should take precedence over query parameters
|
||||||
|
{
|
||||||
|
mustNewForm(
|
||||||
|
t,
|
||||||
|
"foo?prevValue=woof",
|
||||||
|
url.Values{
|
||||||
|
"prevValue": []string{"miaow"},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
etcdserverpb.Request{
|
||||||
|
Id: 1234,
|
||||||
|
Method: "PUT",
|
||||||
|
PrevValue: "miaow",
|
||||||
|
Path: "/foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
@ -213,7 +346,7 @@ func TestGoodParseRequest(t *testing.T) {
|
|||||||
t.Errorf("#%d: err = %v, want %v", i, err, nil)
|
t.Errorf("#%d: err = %v, want %v", i, err, nil)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(got, tt.w) {
|
if !reflect.DeepEqual(got, tt.w) {
|
||||||
t.Errorf("#%d: bad request: got %#v, want %#v", i, got, tt.w)
|
t.Errorf("#%d: request=%#v, want %#v", i, got, tt.w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user