package http import ( "context" "fmt" "io" "github.com/aws/smithy-go/middleware" ) type eventStreamWriterKey struct{} // GetInputStreamWriter returns the io.WriteCloser pipe used for the // operation's input event stream. func GetInputStreamWriter(ctx context.Context) io.WriteCloser { writeCloser, _ := middleware.GetStackValue(ctx, eventStreamWriterKey{}).(io.WriteCloser) return writeCloser } func setInputStreamWriter(ctx context.Context, writeCloser io.WriteCloser) context.Context { return middleware.WithStackValue(ctx, eventStreamWriterKey{}, writeCloser) } // InitializeStreamWriter is a Finalize middleware that creates an in-memory // pipe and sets it as the HTTP request body so event stream messages can be // written after the request is sent. type InitializeStreamWriter struct{} // AddInitializeStreamWriter adds the InitializeStreamWriter middleware to the // provided stack. func AddInitializeStreamWriter(stack *middleware.Stack) error { return stack.Finalize.Add(&InitializeStreamWriter{}, middleware.After) } // ID returns the identifier for the middleware. func (i *InitializeStreamWriter) ID() string { return "InitializeStreamWriter" } // HandleFinalize is the middleware implementation. func (i *InitializeStreamWriter) HandleFinalize( ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, ) ( out middleware.FinalizeOutput, metadata middleware.Metadata, err error, ) { request, ok := in.Request.(*Request) if !ok { return out, metadata, fmt.Errorf("unknown transport type: %T", in.Request) } inputReader, inputWriter := io.Pipe() defer func() { if err == nil { return } _ = inputReader.Close() _ = inputWriter.Close() }() request, err = request.SetStream(inputReader) if err != nil { return out, metadata, err } in.Request = request ctx = setInputStreamWriter(ctx, inputWriter) return next.HandleFinalize(ctx, in) }