std::shared_ptr HttpClientConnection::NewClientStream()

in source/http/HttpConnection.cpp [182:235]


            std::shared_ptr<HttpClientStream> HttpClientConnection::NewClientStream(
                const HttpRequestOptions &requestOptions) noexcept
            {
                AWS_ASSERT(requestOptions.onIncomingHeaders);
                AWS_ASSERT(requestOptions.onStreamComplete);

                aws_http_make_request_options options;
                AWS_ZERO_STRUCT(options);
                options.self_size = sizeof(aws_http_make_request_options);
                options.request = requestOptions.request->GetUnderlyingMessage();
                options.on_response_body = HttpStream::s_onIncomingBody;
                options.on_response_headers = HttpStream::s_onIncomingHeaders;
                options.on_response_header_block_done = HttpStream::s_onIncomingHeaderBlockDone;
                options.on_complete = HttpStream::s_onStreamComplete;

                /* Do the same ref counting trick we did with HttpClientConnection. We need to maintain a reference
                 * internally (regardless of what the user does), until the Stream shuts down. */
                auto *toSeat = static_cast<HttpClientStream *>(aws_mem_acquire(m_allocator, sizeof(HttpClientStream)));

                if (toSeat)
                {
                    toSeat = new (toSeat) HttpClientStream(this->shared_from_this());

                    Allocator *captureAllocator = m_allocator;
                    std::shared_ptr<HttpClientStream> stream(
                        toSeat,
                        [captureAllocator](HttpStream *stream) { Delete(stream, captureAllocator); },
                        StlAllocator<HttpClientStream>(captureAllocator));

                    stream->m_onIncomingBody = requestOptions.onIncomingBody;
                    stream->m_onIncomingHeaders = requestOptions.onIncomingHeaders;
                    stream->m_onIncomingHeadersBlockDone = requestOptions.onIncomingHeadersBlockDone;
                    stream->m_onStreamComplete = requestOptions.onStreamComplete;
                    stream->m_callbackData.allocator = m_allocator;

                    // we purposefully do not set m_callbackData::stream because we don't want the reference count
                    // incremented until the request is kicked off via HttpClientStream::Activate(). Activate()
                    // increments the ref count.
                    options.user_data = &stream->m_callbackData;
                    stream->m_stream = aws_http_connection_make_request(m_connection, &options);

                    if (!stream->m_stream)
                    {
                        stream = nullptr;
                        m_lastError = aws_last_error();
                        return nullptr;
                    }

                    return stream;
                }

                m_lastError = aws_last_error();
                return nullptr;
            }