jsonrpc.go 2.8 KB

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