jsonrpc.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Package jsonrpc provides JSON RPC utilities for serialization of AWS
  2. // requests and responses.
  3. package jsonrpc
  4. //go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/json.json build_test.go
  5. //go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go
  6. import (
  7. "encoding/json"
  8. "io/ioutil"
  9. "strings"
  10. "github.com/aws/aws-sdk-go/aws/awserr"
  11. "github.com/aws/aws-sdk-go/aws/request"
  12. "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
  13. "github.com/aws/aws-sdk-go/private/protocol/rest"
  14. )
  15. var emptyJSON = []byte("{}")
  16. // BuildHandler is a named request handler for building jsonrpc protocol requests
  17. var BuildHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Build", Fn: Build}
  18. // UnmarshalHandler is a named request handler for unmarshaling jsonrpc protocol requests
  19. var UnmarshalHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Unmarshal", Fn: Unmarshal}
  20. // UnmarshalMetaHandler is a named request handler for unmarshaling jsonrpc protocol request metadata
  21. var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalMeta", Fn: UnmarshalMeta}
  22. // UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc protocol request errors
  23. var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalError", Fn: UnmarshalError}
  24. // Build builds a JSON payload for a JSON RPC request.
  25. func Build(req *request.Request) {
  26. var buf []byte
  27. var err error
  28. if req.ParamsFilled() {
  29. buf, err = jsonutil.BuildJSON(req.Params)
  30. if err != nil {
  31. req.Error = awserr.New("SerializationError", "failed encoding JSON RPC request", err)
  32. return
  33. }
  34. } else {
  35. buf = emptyJSON
  36. }
  37. if req.ClientInfo.TargetPrefix != "" || string(buf) != "{}" {
  38. req.SetBufferBody(buf)
  39. }
  40. if req.ClientInfo.TargetPrefix != "" {
  41. target := req.ClientInfo.TargetPrefix + "." + req.Operation.Name
  42. req.HTTPRequest.Header.Add("X-Amz-Target", target)
  43. }
  44. if req.ClientInfo.JSONVersion != "" {
  45. jsonVersion := req.ClientInfo.JSONVersion
  46. req.HTTPRequest.Header.Add("Content-Type", "application/x-amz-json-"+jsonVersion)
  47. }
  48. }
  49. // Unmarshal unmarshals a response for a JSON RPC service.
  50. func Unmarshal(req *request.Request) {
  51. defer req.HTTPResponse.Body.Close()
  52. if req.DataFilled() {
  53. err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body)
  54. if err != nil {
  55. req.Error = awserr.New("SerializationError", "failed decoding JSON RPC response", err)
  56. }
  57. }
  58. return
  59. }
  60. // UnmarshalMeta unmarshals headers from a response for a JSON RPC service.
  61. func UnmarshalMeta(req *request.Request) {
  62. rest.UnmarshalMeta(req)
  63. }
  64. // UnmarshalError unmarshals an error response for a JSON RPC service.
  65. func UnmarshalError(req *request.Request) {
  66. defer req.HTTPResponse.Body.Close()
  67. bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body)
  68. if err != nil {
  69. req.Error = awserr.New("SerializationError", "failed reading JSON RPC error response", err)
  70. return
  71. }
  72. if len(bodyBytes) == 0 {
  73. req.Error = awserr.NewRequestFailure(
  74. awserr.New("SerializationError", req.HTTPResponse.Status, nil),
  75. req.HTTPResponse.StatusCode,
  76. "",
  77. )
  78. return
  79. }
  80. var jsonErr jsonErrorResponse
  81. if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil {
  82. req.Error = awserr.New("SerializationError", "failed decoding JSON RPC error response", err)
  83. return
  84. }
  85. codes := strings.SplitN(jsonErr.Code, "#", 2)
  86. req.Error = awserr.NewRequestFailure(
  87. awserr.New(codes[len(codes)-1], jsonErr.Message, nil),
  88. req.HTTPResponse.StatusCode,
  89. req.RequestID,
  90. )
  91. }
  92. type jsonErrorResponse struct {
  93. Code string `json:"__type"`
  94. Message string `json:"message"`
  95. }