Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
916d248147 | ||
|
bc59fcb886 | ||
7ea55fb466 |
2
go.mod
2
go.mod
@ -2,4 +2,4 @@ module go.unistack.org/micro-client-http/v4
|
|||||||
|
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require go.unistack.org/micro/v4 v4.0.6
|
require go.unistack.org/micro/v4 v4.0.18
|
||||||
|
2
go.sum
2
go.sum
@ -2,3 +2,5 @@ go.unistack.org/micro/v4 v4.0.1 h1:xo1IxbVfgh8i0eY0VeYa3cbb13u5n/Mxnp3FOgWD4Jo=
|
|||||||
go.unistack.org/micro/v4 v4.0.1/go.mod h1:p/J5UcSJjfHsWGT31uKoghQ5rUQZzQJBAFy+Z4+ZVMs=
|
go.unistack.org/micro/v4 v4.0.1/go.mod h1:p/J5UcSJjfHsWGT31uKoghQ5rUQZzQJBAFy+Z4+ZVMs=
|
||||||
go.unistack.org/micro/v4 v4.0.6 h1:YFWvTh3VwyOd6NHYTQcf47n2TF5+p/EhpnbuBQX3qhk=
|
go.unistack.org/micro/v4 v4.0.6 h1:YFWvTh3VwyOd6NHYTQcf47n2TF5+p/EhpnbuBQX3qhk=
|
||||||
go.unistack.org/micro/v4 v4.0.6/go.mod h1:bVEYTlPi0EsdgZZt311bIroDg9ict7ky3C87dSCCAGk=
|
go.unistack.org/micro/v4 v4.0.6/go.mod h1:bVEYTlPi0EsdgZZt311bIroDg9ict7ky3C87dSCCAGk=
|
||||||
|
go.unistack.org/micro/v4 v4.0.18 h1:b7WFwem8Nz1xBrRg5FeLnm9CE5gJseHyf9j0BhkiXW0=
|
||||||
|
go.unistack.org/micro/v4 v4.0.18/go.mod h1:5+da5r835gP0WnNZbYUJDCvWpJ9Xc3IEGyp62e8o8R4=
|
||||||
|
8
http.go
8
http.go
@ -139,7 +139,7 @@ func newRequest(ctx context.Context, log logger.Logger, addr string, req client.
|
|||||||
if opts.Context != nil {
|
if opts.Context != nil {
|
||||||
if md, ok := opts.Context.Value(metadataKey{}).(metadata.Metadata); ok {
|
if md, ok := opts.Context.Value(metadataKey{}).(metadata.Metadata); ok {
|
||||||
for k, v := range md {
|
for k, v := range md {
|
||||||
header.Set(k, v)
|
header[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,13 +148,13 @@ func newRequest(ctx context.Context, log logger.Logger, addr string, req client.
|
|||||||
}
|
}
|
||||||
if opts.RequestMetadata != nil {
|
if opts.RequestMetadata != nil {
|
||||||
for k, v := range opts.RequestMetadata {
|
for k, v := range opts.RequestMetadata {
|
||||||
header.Set(k, v)
|
header[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if md, ok := metadata.FromOutgoingContext(ctx); ok {
|
if md, ok := metadata.FromOutgoingContext(ctx); ok {
|
||||||
for k, v := range md {
|
for k, v := range md {
|
||||||
header.Set(k, v)
|
header[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ func newRequest(ctx context.Context, log logger.Logger, addr string, req client.
|
|||||||
}
|
}
|
||||||
|
|
||||||
if log.V(logger.DebugLevel) {
|
if log.V(logger.DebugLevel) {
|
||||||
log.Debugf(ctx, "request %s to %s with headers %v body %s", method, u.String(), hreq.Header, b)
|
log.Debug(ctx, fmt.Sprintf("request %s to %s with headers %v body %s", method, u.String(), hreq.Header, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
return hreq, nil
|
return hreq, nil
|
||||||
|
@ -134,14 +134,14 @@ func (h *httpStream) parseRsp(ctx context.Context, log logger.Logger, hrsp *http
|
|||||||
buf, err = io.ReadAll(hrsp.Body)
|
buf, err = io.ReadAll(hrsp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if log.V(logger.ErrorLevel) {
|
if log.V(logger.ErrorLevel) {
|
||||||
log.Errorf(ctx, "failed to read body: %v", err)
|
log.Error(ctx, "failed to read body", err)
|
||||||
}
|
}
|
||||||
return errors.InternalServerError("go.micro.client", string(buf))
|
return errors.InternalServerError("go.micro.client", string(buf))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if log.V(logger.DebugLevel) {
|
if log.V(logger.DebugLevel) {
|
||||||
log.Debugf(ctx, "response %s with %v", buf, hrsp.Header)
|
log.Debug(ctx, fmt.Sprintf("response %s with %v", buf, hrsp.Header))
|
||||||
}
|
}
|
||||||
|
|
||||||
if hrsp.StatusCode < 400 {
|
if hrsp.StatusCode < 400 {
|
||||||
|
16
util.go
16
util.go
@ -217,13 +217,21 @@ func newPathRequest(path string, method string, body string, msg interface{}, ta
|
|||||||
_, _ = b.WriteString(values.Encode())
|
_, _ = b.WriteString(values.Encode())
|
||||||
}
|
}
|
||||||
|
|
||||||
if rutil.IsZero(nmsg) {
|
if rutil.IsZero(nmsg) && !isEmptyStruct(nmsg) {
|
||||||
return b.String(), nil, nil
|
return b.String(), nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.String(), nmsg, nil
|
return b.String(), nmsg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isEmptyStruct(v interface{}) bool {
|
||||||
|
val := reflect.ValueOf(v)
|
||||||
|
if val.Kind() == reflect.Ptr {
|
||||||
|
val = val.Elem()
|
||||||
|
}
|
||||||
|
return val.Kind() == reflect.Struct && val.NumField() == 0
|
||||||
|
}
|
||||||
|
|
||||||
func newTemplate(path string) ([]string, error) {
|
func newTemplate(path string) ([]string, error) {
|
||||||
if len(path) == 0 || path[0] != '/' {
|
if len(path) == 0 || path[0] != '/' {
|
||||||
return nil, fmt.Errorf("path must starts with /")
|
return nil, fmt.Errorf("path must starts with /")
|
||||||
@ -274,7 +282,7 @@ func (h *httpClient) parseRsp(ctx context.Context, hrsp *http.Response, rsp inte
|
|||||||
buf, err = io.ReadAll(hrsp.Body)
|
buf, err = io.ReadAll(hrsp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if h.opts.Logger.V(logger.ErrorLevel) {
|
if h.opts.Logger.V(logger.ErrorLevel) {
|
||||||
h.opts.Logger.Errorf(ctx, "failed to read body: %v", err)
|
h.opts.Logger.Error(ctx, "failed to read body", err)
|
||||||
}
|
}
|
||||||
return errors.InternalServerError("go.micro.client", string(buf))
|
return errors.InternalServerError("go.micro.client", string(buf))
|
||||||
}
|
}
|
||||||
@ -283,13 +291,13 @@ func (h *httpClient) parseRsp(ctx context.Context, hrsp *http.Response, rsp inte
|
|||||||
cf, cerr := h.newCodec(ct)
|
cf, cerr := h.newCodec(ct)
|
||||||
if cerr != nil {
|
if cerr != nil {
|
||||||
if h.opts.Logger.V(logger.DebugLevel) {
|
if h.opts.Logger.V(logger.DebugLevel) {
|
||||||
h.opts.Logger.Debugf(ctx, "response with %v unknown content-type %s %s", hrsp.Header, ct, buf)
|
h.opts.Logger.Debug(ctx, fmt.Sprintf("response with %v unknown content-type %s %s", hrsp.Header, ct, buf))
|
||||||
}
|
}
|
||||||
return errors.InternalServerError("go.micro.client", cerr.Error())
|
return errors.InternalServerError("go.micro.client", cerr.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.opts.Logger.V(logger.DebugLevel) {
|
if h.opts.Logger.V(logger.DebugLevel) {
|
||||||
h.opts.Logger.Debugf(ctx, "response %s with %v", buf, hrsp.Header)
|
h.opts.Logger.Debug(ctx, fmt.Sprintf("response %s with %v", buf, hrsp.Header))
|
||||||
}
|
}
|
||||||
|
|
||||||
// succeseful response
|
// succeseful response
|
||||||
|
32
util_test.go
32
util_test.go
@ -59,6 +59,38 @@ func TestNewPathRequest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewPathRequestWithEmptyBody(t *testing.T) {
|
||||||
|
val := struct{}{}
|
||||||
|
cases := []string{
|
||||||
|
"",
|
||||||
|
"*",
|
||||||
|
"{}",
|
||||||
|
"nil",
|
||||||
|
`{"type": "invalid"}`,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, body := range cases {
|
||||||
|
for _, m := range []string{"POST", "PUT", "PATCH", "GET", "DELETE"} {
|
||||||
|
path, nmsg, err := newPathRequest("/v1/test", m, body, val, []string{"protobuf", "json"}, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if nmsg == nil {
|
||||||
|
t.Fatalf("invalid path: nil nmsg")
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
vals := u.Query()
|
||||||
|
if len(vals) != 0 {
|
||||||
|
t.Fatalf("invalid path: %v nmsg: %v", path, nmsg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNewPathVarRequest(t *testing.T) {
|
func TestNewPathVarRequest(t *testing.T) {
|
||||||
type Message struct {
|
type Message struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
Loading…
Reference in New Issue
Block a user