doJSONRequest makes a JSON request to the remote Twirp service.
(ctx context.Context, client HTTPClient, hooks *twirp.ClientHooks, url string, in, out proto.Message)
| 974 | |
| 975 | // doJSONRequest makes a JSON request to the remote Twirp service. |
| 976 | func doJSONRequest(ctx context.Context, client HTTPClient, hooks *twirp.ClientHooks, url string, in, out proto.Message) (_ context.Context, err error) { |
| 977 | marshaler := &protojson.MarshalOptions{UseProtoNames: true} |
| 978 | reqBytes, err := marshaler.Marshal(in) |
| 979 | if err != nil { |
| 980 | return ctx, wrapInternal(err, "failed to marshal json request") |
| 981 | } |
| 982 | if err = ctx.Err(); err != nil { |
| 983 | return ctx, wrapInternal(err, "aborted because context was done") |
| 984 | } |
| 985 | |
| 986 | req, err := newRequest(ctx, url, bytes.NewReader(reqBytes), "application/json") |
| 987 | if err != nil { |
| 988 | return ctx, wrapInternal(err, "could not build request") |
| 989 | } |
| 990 | ctx, err = callClientRequestPrepared(ctx, hooks, req) |
| 991 | if err != nil { |
| 992 | return ctx, err |
| 993 | } |
| 994 | |
| 995 | req = req.WithContext(ctx) |
| 996 | resp, err := client.Do(req) |
| 997 | if err != nil { |
| 998 | return ctx, wrapInternal(err, "failed to do request") |
| 999 | } |
| 1000 | |
| 1001 | defer func() { |
| 1002 | cerr := resp.Body.Close() |
| 1003 | if err == nil && cerr != nil { |
| 1004 | err = wrapInternal(cerr, "failed to close response body") |
| 1005 | } |
| 1006 | }() |
| 1007 | |
| 1008 | if err = ctx.Err(); err != nil { |
| 1009 | return ctx, wrapInternal(err, "aborted because context was done") |
| 1010 | } |
| 1011 | |
| 1012 | if resp.StatusCode != 200 { |
| 1013 | return ctx, errorFromResponse(resp) |
| 1014 | } |
| 1015 | |
| 1016 | d := json.NewDecoder(resp.Body) |
| 1017 | rawRespBody := json.RawMessage{} |
| 1018 | if err := d.Decode(&rawRespBody); err != nil { |
| 1019 | return ctx, wrapInternal(err, "failed to unmarshal json response") |
| 1020 | } |
| 1021 | unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} |
| 1022 | if err = unmarshaler.Unmarshal(rawRespBody, out); err != nil { |
| 1023 | return ctx, wrapInternal(err, "failed to unmarshal json response") |
| 1024 | } |
| 1025 | if err = ctx.Err(); err != nil { |
| 1026 | return ctx, wrapInternal(err, "aborted because context was done") |
| 1027 | } |
| 1028 | return ctx, nil |
| 1029 | } |
| 1030 | |
| 1031 | // Call twirp.ServerHooks.RequestReceived if the hook is available |
| 1032 | func callRequestReceived(ctx context.Context, h *twirp.ServerHooks) (context.Context, error) { |
no test coverage detected