http

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 25, 2020 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package http provides the HTTP transport client and request/response types needed to round trip API operation calls with an service.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddCloseResponseBodyMiddleware

func AddCloseResponseBodyMiddleware(stack *middleware.Stack) error

AddCloseResponseBodyMiddleware adds the middleware to automatically close the response body of an operation request, after the response had been deserialized.

func AddComputeContentLengthMiddleware added in v0.4.0

func AddComputeContentLengthMiddleware(stack *middleware.Stack) error

AddComputeContentLengthMiddleware adds ComputeContentLength to the middleware stack's Build step.

func AddContentChecksumMiddleware added in v0.4.0

func AddContentChecksumMiddleware(stack *middleware.Stack) error

AddContentChecksumMiddleware adds checksum middleware to middleware's build step.

func AddErrorCloseResponseBodyMiddleware

func AddErrorCloseResponseBodyMiddleware(stack *middleware.Stack) error

AddErrorCloseResponseBodyMiddleware adds the middleware to automatically close the response body of an operation request if the request response failed.

func AddHeaderValue

func AddHeaderValue(header string, value string) func(stack *middleware.Stack) error

AddHeaderValue returns a stack mutator that adds the header value pair to header. Appends to any existing values if present.

func DisableEndpointHostPrefix added in v0.4.0

func DisableEndpointHostPrefix(ctx context.Context, value bool) context.Context

DisableEndpointHostPrefix sets or modifies if the request's endpoint host prefixing to be disabled. If value is set to true, endpoint host prefixing will be disabled.

func GetHostnameImmutable added in v0.3.0

func GetHostnameImmutable(ctx context.Context) (v bool)

GetHostnameImmutable retrieves if the endpoint hostname should be considered immutable or not.

func IsEndpointHostPrefixDisabled added in v0.4.0

func IsEndpointHostPrefixDisabled(ctx context.Context) (v bool)

IsEndpointHostPrefixDisabled retrieves if the hostname prefixing

is disabled.

func NewStackRequest

func NewStackRequest() interface{}

NewStackRequest returns an initialized request ready to populated with the HTTP request details. Returns empty interface so the function can be used as a parameter to the Smithy middleware Stack constructor.

func RequestCloner

func RequestCloner(v interface{}) interface{}

RequestCloner is a function that can take an input request type and clone the request for use in a subsequent retry attempt

func SetHeaderValue

func SetHeaderValue(header string, value string) func(stack *middleware.Stack) error

SetHeaderValue returns a stack mutator that adds the header value pair to header. Replaces any existing values if present.

func SetHostnameImmutable added in v0.3.0

func SetHostnameImmutable(ctx context.Context, value bool) context.Context

SetHostnameImmutable sets or modifies if the request's endpoint hostname should be considered immutable or not.

func SplitHTTPDateTimestampHeaderListValues

func SplitHTTPDateTimestampHeaderListValues(vs []string) ([]string, error)

SplitHTTPDateTimestampHeaderListValues attempts to split the HTTP-Date timestamp values in the slice by commas, and return a list of all values separated. The split is aware of HTTP-Date timestamp format, and will skip comma within the timestamp value. Returns an error if unable to split the timestamp values.

func SplitHeaderListValues

func SplitHeaderListValues(vs []string) ([]string, error)

SplitHeaderListValues attempts to split the elements of the slice by commas, and return a list of all values separated. Returns error if unable to separate the values.

func ValidHostLabel

func ValidHostLabel(label string) bool

ValidHostLabel returns if the label is a valid RFC 3986 host label.

func ValidateContentLengthHeader added in v0.2.0

func ValidateContentLengthHeader(stack *middleware.Stack) error

ValidateContentLengthHeader adds middleware that validates request content-length is set to value greater than zero.

func ValidateEndpointHost

func ValidateEndpointHost(host string) error

ValidateEndpointHost validates that the host string passed in is a valid RFC 3986 host. Returns error if the host is not valid.

Types

type ClientDo

type ClientDo interface {
	Do(*http.Request) (*http.Response, error)
}

ClientDo provides the interface for custom HTTP client implementations.

type ClientDoFunc

type ClientDoFunc func(*http.Request) (*http.Response, error)

ClientDoFunc provides a helper to wrap an function as an HTTP client for round tripping requests.

func (ClientDoFunc) Do

func (fn ClientDoFunc) Do(r *http.Request) (*http.Response, error)

Do will invoke the underlying func, returning the result.

type ClientHandler

type ClientHandler struct {
	// contains filtered or unexported fields
}

ClientHandler wraps a client that implements the HTTP Do method. Standard implementation is http.Client.

func NewClientHandler

func NewClientHandler(client ClientDo) ClientHandler

NewClientHandler returns an initialized middleware handler for the client.

func (ClientHandler) Handle

func (c ClientHandler) Handle(ctx context.Context, input interface{}) (
	out interface{}, metadata middleware.Metadata, err error,
)

Handle implements the middleware Handler interface, that will invoke the underlying HTTP client. Requires the input to be an Smithy *Request. Returns a smithy *Response, or error if the request failed.

type ComputeContentLength added in v0.4.0

type ComputeContentLength struct {
}

ComputeContentLength provides a middleware to set the content-length header for the length of a serialize request body.

func (*ComputeContentLength) HandleBuild added in v0.4.0

HandleBuild adds the length of the serialized request to the HTTP header if the length can be determined.

func (*ComputeContentLength) ID added in v0.4.0

func (m *ComputeContentLength) ID() string

ID the identifier for the ComputeContentLength

type NopClient added in v0.2.0

type NopClient struct{}

NopClient provides a client that ignores the request, and returns a empty successful HTTP response value.

func (NopClient) Do added in v0.2.0

func (NopClient) Do(r *http.Request) (*http.Response, error)

Do ignores the request and returns a 200 status empty response.

type Request

type Request struct {
	*http.Request
	// contains filtered or unexported fields
}

Request provides the HTTP specific request structure for HTTP specific middleware steps to use to serialize input, and send an operation's request.

Example (SerializeMiddleware)
// Create the stack and provide the function that will create a new Request
// when the SerializeStep is invoked.
stack := middleware.NewStack("serialize example", NewStackRequest)

type Input struct {
	FooName  string
	BarCount int
}

// Add the serialization middleware.
stack.Serialize.Add(middleware.SerializeMiddlewareFunc("example serialize",
	func(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
		middleware.SerializeOutput, middleware.Metadata, error,
	) {
		req := in.Request.(*Request)
		input := in.Parameters.(*Input)

		req.Header.Set("foo-name", input.FooName)
		req.Header.Set("bar-count", strconv.Itoa(input.BarCount))

		return next.HandleSerialize(ctx, in)
	}),
	middleware.After,
)

// Mock example handler taking the request input and returning a response
mockHandler := middleware.HandlerFunc(func(ctx context.Context, in interface{}) (
	output interface{}, metadata middleware.Metadata, err error,
) {
	// Returns the standard http Request for the handler to make request
	// using standard http compatible client.
	req := in.(*Request).Build(context.Background())

	fmt.Println("foo-name", req.Header.Get("foo-name"))
	fmt.Println("bar-count", req.Header.Get("bar-count"))

	return &Response{
		Response: &http.Response{
			StatusCode: 200,
			Header:     http.Header{},
		},
	}, metadata, nil
})

// Use the stack to decorate the handler then invoke the decorated handler
// with the inputs.
handler := middleware.DecorateHandler(mockHandler, stack)
_, _, err := handler.Handle(context.Background(), &Input{FooName: "abc", BarCount: 123})
if err != nil {
	fmt.Fprintf(os.Stderr, "failed to call operation, %v", err)
	return
}
Output:

foo-name abc
bar-count 123

func (*Request) Build

func (r *Request) Build(ctx context.Context) *http.Request

Build returns a build standard HTTP request value from the Smithy request. The request's stream is wrapped in a safe container that allows it to be reused for subsequent attempts.

func (*Request) Clone

func (r *Request) Clone() *Request

Clone returns a deep copy of the Request for the new context. A reference to the Stream is copied, but the underlying stream is not copied.

func (*Request) GetStream

func (r *Request) GetStream() io.Reader

GetStream returns the request stream io.Reader if a stream is set. If no stream is present nil will be returned.

func (*Request) IsStreamSeekable

func (r *Request) IsStreamSeekable() bool

IsStreamSeekable returns if the stream is seekable.

func (*Request) RewindStream

func (r *Request) RewindStream() error

RewindStream will rewind the io.Reader to the relative start position if it is an io.Seeker.

func (*Request) SetStream

func (r *Request) SetStream(reader io.Reader) (rc *Request, err error)

SetStream returns a clone of the request with the stream set to the provided reader. May return an error if the provided reader is seekable but returns an error.

func (*Request) StreamLength

func (r *Request) StreamLength() (size int64, ok bool, err error)

StreamLength returns the number of bytes of the serialized stream attached to the request and ok set. If the length cannot be determined, an error will be returned.

type RequestResponseLogger added in v0.4.0

type RequestResponseLogger struct {
	LogRequest         bool
	LogRequestWithBody bool

	LogResponse         bool
	LogResponseWithBody bool
}

RequestResponseLogger is a deserialize middleware that will log the request and response HTTP messages and optionally their respective bodies. Will not perform any logging if none of the options are set.

func (*RequestResponseLogger) HandleDeserialize added in v0.4.0

HandleDeserialize will log the request and response HTTP messages if configured accordingly.

func (*RequestResponseLogger) ID added in v0.4.0

func (r *RequestResponseLogger) ID() string

ID is the middleware identifier.

type RequestSendError

type RequestSendError struct {
	Err error
}

RequestSendError provides a generic request transport error. This error should wrap errors making HTTP client requests.

The ClientHandler will wrap the HTTP client's error if the client request fails, and did not fail because of context canceled.

func (*RequestSendError) ConnectionError

func (e *RequestSendError) ConnectionError() bool

ConnectionError return that the error is related to not being able to send the request, or receive a response from the service.

func (*RequestSendError) Error

func (e *RequestSendError) Error() string

func (*RequestSendError) Unwrap

func (e *RequestSendError) Unwrap() error

Unwrap returns the underlying error, if there was one.

type Response

type Response struct {
	*http.Response
}

Response provides the HTTP specific response structure for HTTP specific middleware steps to use to deserialize the response from an operation call.

Example (DeserializeMiddleware)
// Create the stack and provide the function that will create a new Request
// when the SerializeStep is invoked.
stack := middleware.NewStack("deserialize example", NewStackRequest)

type Output struct {
	FooName  string
	BarCount int
}

// Add a Deserialize middleware that will extract the RawResponse and
// deserialize into the target output type.
stack.Deserialize.Add(middleware.DeserializeMiddlewareFunc("example deserialize",
	func(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) (
		out middleware.DeserializeOutput, metadata middleware.Metadata, err error,
	) {
		out, metadata, err = next.HandleDeserialize(ctx, in)
		if err != nil {
			return middleware.DeserializeOutput{}, metadata, err
		}

		metadata.Set("example-meta", "meta-value")

		rawResp := out.RawResponse.(*Response)
		out.Result = &Output{
			FooName: rawResp.Header.Get("foo-name"),
			BarCount: func() int {
				v, _ := strconv.Atoi(rawResp.Header.Get("bar-count"))
				return v
			}(),
		}

		return out, metadata, nil
	}),
	middleware.After,
)

// Mock example handler taking the request input and returning a response
mockHandler := middleware.HandlerFunc(func(ctx context.Context, in interface{}) (
	output interface{}, metadata middleware.Metadata, err error,
) {
	resp := &http.Response{
		StatusCode: 200,
		Header:     http.Header{},
	}
	resp.Header.Set("foo-name", "abc")
	resp.Header.Set("bar-count", "123")

	// The handler's returned response will be available as the
	// DeserializeOutput.RawResponse field.
	return &Response{
		Response: resp,
	}, metadata, nil
})

// Use the stack to decorate the handler then invoke the decorated handler
// with the inputs.
handler := middleware.DecorateHandler(mockHandler, stack)
result, metadata, err := handler.Handle(context.Background(), struct{}{})
if err != nil {
	fmt.Fprintf(os.Stderr, "failed to call operation, %v", err)
	return
}

// Cast the result returned by the handler to the expected Output type.
res := result.(*Output)
fmt.Println("FooName", res.FooName)
fmt.Println("BarCount", res.BarCount)
fmt.Println("Metadata:", "example-meta:", metadata.Get("example-meta"))
Output:

FooName abc
BarCount 123
Metadata: example-meta: meta-value

type ResponseError

type ResponseError struct {
	Response *Response
	Err      error
}

ResponseError provides the HTTP centric error type wrapping the underlying error with the HTTP response value.

Example
stack := middleware.NewStack("my cool stack", NewStackRequest)

stack.Deserialize.Add(middleware.DeserializeMiddlewareFunc("wrap http response error",
	func(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) (
		out middleware.DeserializeOutput, metadata middleware.Metadata, err error,
	) {
		out, metadata, err = next.HandleDeserialize(ctx, in)
		if err == nil {
			// Nothing to do when there is no error.
			return out, metadata, err
		}

		rawResp, ok := out.RawResponse.(*Response)
		if !ok {
			// No raw response to wrap with.
			return out, metadata, err
		}

		// Wrap the returned error with the response error containing the
		// returned response.
		err = &ResponseError{
			Response: rawResp,
			Err:      err,
		}

		return out, metadata, err
	}),
	middleware.After,
)

stack.Deserialize.Add(middleware.DeserializeMiddlewareFunc("deserialize error",
	func(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) (
		out middleware.DeserializeOutput, metadata middleware.Metadata, err error,
	) {
		out, metadata, err = next.HandleDeserialize(ctx, in)
		if err != nil {
			return middleware.DeserializeOutput{}, metadata, err
		}

		rawResp := out.RawResponse.(*Response)
		if rawResp.StatusCode == 200 {
			return out, metadata, nil
		}

		// Deserialize the response API error values.
		err = &smithy.GenericAPIError{
			Code:    rawResp.Header.Get("Error-Code"),
			Message: rawResp.Header.Get("Error-Message"),
		}

		return out, metadata, err
	}),
	middleware.After,
)

// Mock example handler taking the request input and returning a response
mockHandler := middleware.HandlerFunc(func(ctx context.Context, in interface{}) (
	output interface{}, metadata middleware.Metadata, err error,
) {
	// populate the mock response with an API error and additional data.
	resp := &http.Response{
		StatusCode: 404,
		Header: http.Header{
			"Extra-Header":  []string{"foo value"},
			"Error-Code":    []string{"FooException"},
			"Error-Message": []string{"some message about the error"},
		},
	}

	// The handler's returned response will be available as the
	// DeserializeOutput.RawResponse field.
	return &Response{
		Response: resp,
	}, metadata, nil
})

// Use the stack to decorate the handler then invoke the decorated handler
// with the inputs.
handler := middleware.DecorateHandler(mockHandler, stack)
_, _, err := handler.Handle(context.Background(), struct{}{})
if err == nil {
	fmt.Printf("expect error, got none")
	return
}

if err != nil {
	var apiErr smithy.APIError
	if errors.As(err, &apiErr) {
		fmt.Printf("request failed: %s, %s\n", apiErr.ErrorCode(), apiErr.ErrorMessage())
	}

	var respErr *ResponseError
	if errors.As(err, &respErr) {
		fmt.Printf("response status: %v\n", respErr.HTTPStatusCode())
		fmt.Printf("response header: %v\n", respErr.HTTPResponse().Header.Get("Extra-Header"))
	}
}
Output:

request failed: FooException, some message about the error
response status: 404
response header: foo value

func (*ResponseError) Error

func (e *ResponseError) Error() string

func (*ResponseError) HTTPResponse

func (e *ResponseError) HTTPResponse() *Response

HTTPResponse returns the HTTP response received from the service.

func (*ResponseError) HTTPStatusCode

func (e *ResponseError) HTTPStatusCode() int

HttpStatusCode returns the HTTP response status code received from the service

func (*ResponseError) Unwrap

func (e *ResponseError) Unwrap() error

Unwrap returns the nested error if any, or nil.

type UserAgentBuilder

type UserAgentBuilder struct {
	// contains filtered or unexported fields
}

UserAgentBuilder is a builder for a HTTP User-Agent string.

func NewUserAgentBuilder

func NewUserAgentBuilder() *UserAgentBuilder

NewUserAgentBuilder returns a new UserAgentBuilder.

func (*UserAgentBuilder) AddKey

func (u *UserAgentBuilder) AddKey(key string)

AddKey adds the named component/product to the agent string

func (*UserAgentBuilder) AddKeyValue

func (u *UserAgentBuilder) AddKeyValue(key, value string)

AddKeyValue adds the named key to the agent string with the given value.

func (*UserAgentBuilder) Build

func (u *UserAgentBuilder) Build() string

Build returns the constructed User-Agent string. May be called multiple times.

Directories

Path Synopsis
internal
io

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL