src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

middleware.go (5027B)


      1 package client
      2 
      3 import (
      4 	"context"
      5 	"encoding/json"
      6 	"fmt"
      7 	"io"
      8 	"net/url"
      9 
     10 	"github.com/aws/smithy-go"
     11 	smithymiddleware "github.com/aws/smithy-go/middleware"
     12 	smithyhttp "github.com/aws/smithy-go/transport/http"
     13 )
     14 
     15 type buildEndpoint struct {
     16 	Endpoint string
     17 }
     18 
     19 func (b *buildEndpoint) ID() string {
     20 	return "BuildEndpoint"
     21 }
     22 
     23 func (b *buildEndpoint) HandleBuild(ctx context.Context, in smithymiddleware.BuildInput, next smithymiddleware.BuildHandler) (
     24 	out smithymiddleware.BuildOutput, metadata smithymiddleware.Metadata, err error,
     25 ) {
     26 	request, ok := in.Request.(*smithyhttp.Request)
     27 	if !ok {
     28 		return out, metadata, fmt.Errorf("unknown transport, %T", in.Request)
     29 	}
     30 
     31 	if len(b.Endpoint) == 0 {
     32 		return out, metadata, fmt.Errorf("endpoint not provided")
     33 	}
     34 
     35 	parsed, err := url.Parse(b.Endpoint)
     36 	if err != nil {
     37 		return out, metadata, fmt.Errorf("failed to parse endpoint, %w", err)
     38 	}
     39 
     40 	request.URL = parsed
     41 
     42 	return next.HandleBuild(ctx, in)
     43 }
     44 
     45 type serializeOpGetCredential struct{}
     46 
     47 func (s *serializeOpGetCredential) ID() string {
     48 	return "OperationSerializer"
     49 }
     50 
     51 func (s *serializeOpGetCredential) HandleSerialize(ctx context.Context, in smithymiddleware.SerializeInput, next smithymiddleware.SerializeHandler) (
     52 	out smithymiddleware.SerializeOutput, metadata smithymiddleware.Metadata, err error,
     53 ) {
     54 	request, ok := in.Request.(*smithyhttp.Request)
     55 	if !ok {
     56 		return out, metadata, fmt.Errorf("unknown transport type, %T", in.Request)
     57 	}
     58 
     59 	params, ok := in.Parameters.(*GetCredentialsInput)
     60 	if !ok {
     61 		return out, metadata, fmt.Errorf("unknown input parameters, %T", in.Parameters)
     62 	}
     63 
     64 	const acceptHeader = "Accept"
     65 	request.Header[acceptHeader] = append(request.Header[acceptHeader][:0], "application/json")
     66 
     67 	if len(params.AuthorizationToken) > 0 {
     68 		const authHeader = "Authorization"
     69 		request.Header[authHeader] = append(request.Header[authHeader][:0], params.AuthorizationToken)
     70 	}
     71 
     72 	return next.HandleSerialize(ctx, in)
     73 }
     74 
     75 type deserializeOpGetCredential struct{}
     76 
     77 func (d *deserializeOpGetCredential) ID() string {
     78 	return "OperationDeserializer"
     79 }
     80 
     81 func (d *deserializeOpGetCredential) HandleDeserialize(ctx context.Context, in smithymiddleware.DeserializeInput, next smithymiddleware.DeserializeHandler) (
     82 	out smithymiddleware.DeserializeOutput, metadata smithymiddleware.Metadata, err error,
     83 ) {
     84 	out, metadata, err = next.HandleDeserialize(ctx, in)
     85 	if err != nil {
     86 		return out, metadata, err
     87 	}
     88 
     89 	response, ok := out.RawResponse.(*smithyhttp.Response)
     90 	if !ok {
     91 		return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
     92 	}
     93 
     94 	if response.StatusCode < 200 || response.StatusCode >= 300 {
     95 		return out, metadata, deserializeError(response)
     96 	}
     97 
     98 	var shape *GetCredentialsOutput
     99 	if err = json.NewDecoder(response.Body).Decode(&shape); err != nil {
    100 		return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("failed to deserialize json response, %w", err)}
    101 	}
    102 
    103 	out.Result = shape
    104 	return out, metadata, err
    105 }
    106 
    107 func deserializeError(response *smithyhttp.Response) error {
    108 	// we could be talking to anything, json isn't guaranteed
    109 	// see https://github.com/aws/aws-sdk-go-v2/issues/2316
    110 	if response.Header.Get("Content-Type") == "application/json" {
    111 		return deserializeJSONError(response)
    112 	}
    113 
    114 	msg, err := io.ReadAll(response.Body)
    115 	if err != nil {
    116 		return &smithy.DeserializationError{
    117 			Err: fmt.Errorf("read response, %w", err),
    118 		}
    119 	}
    120 
    121 	return &EndpointError{
    122 		// no sensible value for Code
    123 		Message:    string(msg),
    124 		Fault:      stof(response.StatusCode),
    125 		statusCode: response.StatusCode,
    126 	}
    127 }
    128 
    129 func deserializeJSONError(response *smithyhttp.Response) error {
    130 	var errShape *EndpointError
    131 	if err := json.NewDecoder(response.Body).Decode(&errShape); err != nil {
    132 		return &smithy.DeserializationError{
    133 			Err: fmt.Errorf("failed to decode error message, %w", err),
    134 		}
    135 	}
    136 
    137 	errShape.Fault = stof(response.StatusCode)
    138 	errShape.statusCode = response.StatusCode
    139 	return errShape
    140 }
    141 
    142 // maps HTTP status code to smithy ErrorFault
    143 func stof(code int) smithy.ErrorFault {
    144 	if code >= 500 {
    145 		return smithy.FaultServer
    146 	}
    147 	return smithy.FaultClient
    148 }
    149 
    150 func addProtocolFinalizerMiddlewares(stack *smithymiddleware.Stack, options Options, operation string) error {
    151 	if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, smithymiddleware.Before); err != nil {
    152 		return fmt.Errorf("add ResolveAuthScheme: %w", err)
    153 	}
    154 	if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", smithymiddleware.After); err != nil {
    155 		return fmt.Errorf("add GetIdentity: %w", err)
    156 	}
    157 	if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", smithymiddleware.After); err != nil {
    158 		return fmt.Errorf("add ResolveEndpointV2: %w", err)
    159 	}
    160 	if err := stack.Finalize.Insert(&signRequestMiddleware{}, "ResolveEndpointV2", smithymiddleware.After); err != nil {
    161 		return fmt.Errorf("add Signing: %w", err)
    162 	}
    163 	return nil
    164 }