From da252f76f782959cb0e3876d62d51969abd5972b Mon Sep 17 00:00:00 2001 From: Victor Vazquez Date: Tue, 1 Jun 2021 10:02:55 -0700 Subject: [PATCH] remove duplicated headers and update tests (#2369) --- sdk/core/azure-core/CMakeLists.txt | 10 +- .../src/private/curl_connection.hpp | 204 --------- .../src/private/curl_connection_pool.hpp | 127 ------ .../azure-core/src/private/curl_session.hpp | 418 ------------------ .../test/ut/azure_libcurl_core_main_test.cpp | 6 +- .../test/ut/curl_connection_pool_test.cpp | 7 +- .../azure-core/test/ut/curl_options_test.cpp | 4 +- .../azure-core/test/ut/curl_session_test.hpp | 2 +- .../test/ut/curl_session_test_test.cpp | 4 +- 9 files changed, 17 insertions(+), 765 deletions(-) delete mode 100644 sdk/core/azure-core/src/private/curl_connection.hpp delete mode 100644 sdk/core/azure-core/src/private/curl_connection_pool.hpp delete mode 100644 sdk/core/azure-core/src/private/curl_session.hpp diff --git a/sdk/core/azure-core/CMakeLists.txt b/sdk/core/azure-core/CMakeLists.txt index 8ee63e9c0..d1887f760 100644 --- a/sdk/core/azure-core/CMakeLists.txt +++ b/sdk/core/azure-core/CMakeLists.txt @@ -33,7 +33,12 @@ if(BUILD_TRANSPORT_CURL) endif() if(BUILD_TRANSPORT_CURL) - SET(CURL_TRANSPORT_ADAPTER_SRC src/http/curl/curl.cpp) + SET(CURL_TRANSPORT_ADAPTER_SRC + src/http/curl/curl_connection_pool_private.hpp + src/http/curl/curl_connection_private.hpp + src/http/curl/curl_session_private.hpp + src/http/curl/curl.cpp + ) SET(CURL_TRANSPORT_ADAPTER_INC inc/azure/core/http/curl_transport.hpp) endif() if(BUILD_TRANSPORT_WINHTTP) @@ -102,9 +107,6 @@ set( src/http/url.cpp src/io/body_stream.cpp src/io/random_access_file_body_stream.cpp - src/private/curl_connection.hpp - src/private/curl_connection_pool.hpp - src/private/curl_session.hpp src/private/environment_log_level_listener.hpp src/private/package_version.hpp src/base64.cpp diff --git a/sdk/core/azure-core/src/private/curl_connection.hpp b/sdk/core/azure-core/src/private/curl_connection.hpp deleted file mode 100644 index 8d1e5726d..000000000 --- a/sdk/core/azure-core/src/private/curl_connection.hpp +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// SPDX-License-Identifier: MIT - -/** - * @file - * @brief The libcurl connection keeps the curl handle and performs the data transfer to the - * network. - */ - -#pragma once - -#include "azure/core/http/http.hpp" - -#include -#include -#include - -namespace Azure { namespace Core { namespace Http { - - namespace _detail { - // libcurl CURL_MAX_WRITE_SIZE is 64k. Using same value for default uploading chunk size. - // This can be customizable in the HttpRequest - constexpr static int64_t DefaultUploadChunkSize = 1024 * 64; - constexpr static auto DefaultLibcurlReaderSize = 1024; - // Run time error template - constexpr static const char* DefaultFailedToGetNewConnectionTemplate - = "Fail to get a new connection for: "; - constexpr static int32_t DefaultMaxOpenNewConnectionIntentsAllowed = 10; - // After 3 connections are received from the pool and failed to send a request, the next - // connections would ask the pool to be clean and spawn new connection. - constexpr static int32_t RequestPoolResetAfterConnectionFailed = 3; - // 90 sec -> cleaner wait time before next clean routine - constexpr static int32_t DefaultCleanerIntervalMilliseconds = 1000 * 90; - // 60 sec -> expired connection is when it waits for 60 sec or more and it's not re-used - constexpr static int32_t DefaultConnectionExpiredMilliseconds = 1000 * 60; - // Define the maximun allowed connections per host-index in the pool. If this number is reached - // for the host-index, next connections trying to be added to the pool will be ignored. - constexpr static size_t MaxConnectionsPerIndex = 1024; - } // namespace _detail - - /** - * @brief Interface for the connection to the network with Curl. - * - * @remark This interface enables to mock the communication to the network with any behavior for - * testing. - * - */ - class CurlNetworkConnection { - protected: - bool m_isShutDown = false; - - public: - /** - * @brief Allow derived classes calling a destructor. - * - */ - virtual ~CurlNetworkConnection() = default; - - /** - * @brief Get the Connection Properties Key object - * - */ - virtual std::string const& GetConnectionKey() const = 0; - - /** - * @brief Update last usage time for the connection. - * - */ - virtual void UpdateLastUsageTime() = 0; - - /** - * @brief Checks whether this CURL connection is expired. - * - */ - virtual bool IsExpired() = 0; - - /** - * @brief This function is used when working with streams to pull more data from the wire. - * Function will try to keep pulling data from socket until the buffer is all written or until - * there is no more data to get from the socket. - * - */ - virtual size_t ReadFromSocket(uint8_t* buffer, size_t bufferSize, Context const& context) = 0; - - /** - * @brief This method will use libcurl socket to write all the bytes from buffer. - * - */ - virtual CURLcode SendBuffer(uint8_t const* buffer, size_t bufferSize, Context const& context) - = 0; - - /** - * @brief Set the connection into an invalid and unusable state. - * - * @remark A connection won't be returned to the connection pool if it was shut it down. - * - */ - virtual void Shutdown() { m_isShutDown = true; }; - - /** - * @brief Check if the the connection was shut it down. - * - * @return `true` is the connection was shut it down. - */ - bool IsShutdown() const { return m_isShutDown; }; - }; - - /** - * @brief CURL HTTP connection. - * - */ - class CurlConnection final : public CurlNetworkConnection { - private: - CURL* m_handle; - curl_socket_t m_curlSocket; - std::chrono::steady_clock::time_point m_lastUseTime; - std::string m_connectionKey; - - public: - /** - * @Brief Construct CURL HTTP connection. - * - * @param host HTTP connection host name. - */ - CurlConnection(CURL* handle, std::string connectionPropertiesKey) - : m_handle(handle), m_connectionKey(std::move(connectionPropertiesKey)) - { - // Get the socket that libcurl is using from handle. Will use this to wait while - // reading/writing - // into wire -#if defined(_MSC_VER) -#pragma warning(push) -// C26812: The enum type 'CURLcode' is un-scoped. Prefer 'enum class' over 'enum' (Enum.3) -#pragma warning(disable : 26812) -#endif - auto result = curl_easy_getinfo(m_handle, CURLINFO_ACTIVESOCKET, &m_curlSocket); -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - if (result != CURLE_OK) - { - throw Http::TransportException( - "Broken connection. Couldn't get the active sockect for it." - + std::string(curl_easy_strerror(result))); - } - } - - /** - * @brief Destructor. - * @details Cleans up CURL (invokes `curl_easy_cleanup()`). - */ - ~CurlConnection() override { curl_easy_cleanup(this->m_handle); } - - std::string const& GetConnectionKey() const override { return this->m_connectionKey; } - - /** - * @brief Update last usage time for the connection. - * - */ - void UpdateLastUsageTime() override - { - this->m_lastUseTime = std::chrono::steady_clock::now(); - } - - /** - * @brief Checks whether this CURL connection is expired. - * @return `true` if this connection is considered expired, `false` otherwise. - */ - bool IsExpired() override - { - auto connectionOnWaitingTimeMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - this->m_lastUseTime); - return connectionOnWaitingTimeMs.count() >= _detail::DefaultConnectionExpiredMilliseconds; - } - - /** - * @brief This function is used when working with streams to pull more data from the wire. - * Function will try to keep pulling data from socket until the buffer is all written or until - * there is no more data to get from the socket. - * - * @param context #Azure::Core::Context so that operation can be cancelled. - * @param buffer ptr to buffer where to copy bytes from socket. - * @param bufferSize size of the buffer and the requested bytes to be pulled from wire. - * @return return the numbers of bytes pulled from socket. It can be less than what it was - * requested. - */ - size_t ReadFromSocket(uint8_t* buffer, size_t bufferSize, Context const& context) override; - - /** - * @brief This method will use libcurl socket to write all the bytes from buffer. - * - * @remarks Hardcoded timeout is used in case a socket stop responding. - * - * @param context #Azure::Core::Context so that operation can be cancelled. - * @param buffer ptr to the data to be sent to wire. - * @param bufferSize size of the buffer to send. - * @return CURL_OK when response is sent successfully. - */ - CURLcode SendBuffer(uint8_t const* buffer, size_t bufferSize, Context const& context) - override; - - void Shutdown() override; - }; -}}} // namespace Azure::Core::Http diff --git a/sdk/core/azure-core/src/private/curl_connection_pool.hpp b/sdk/core/azure-core/src/private/curl_connection_pool.hpp deleted file mode 100644 index 758da8c10..000000000 --- a/sdk/core/azure-core/src/private/curl_connection_pool.hpp +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// SPDX-License-Identifier: MIT - -/** - * @file - * @brief The curl connection pool provides the utilities for creating a new curl connection and to - * keep a pool of connections to be re-used. - */ - -#pragma once - -#include "azure/core/dll_import_export.hpp" -#include "azure/core/http/http.hpp" - -#include "private/curl_connection.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(TESTING_BUILD) -// Define the class name that reads from ConnectionPool private members -namespace Azure { namespace Core { namespace Test { - class CurlConnectionPool_connectionPoolTest_Test; - class CurlConnectionPool_uniquePort_Test; -}}} // namespace Azure::Core::Test -#endif - -namespace Azure { namespace Core { namespace Http { namespace _detail { - - /** - * @brief CURL HTTP connection pool makes it possible to re-use one curl connection to perform - * more than one request. Use this component when connections are not re-used by default. - * - * This pool offers static methods and it is allocated statically. There can be only one - * connection pool per application. - */ - class CurlConnectionPool final { -#if defined(TESTING_BUILD) - // Give access to private to this tests class - friend class Azure::Core::Test::CurlConnectionPool_connectionPoolTest_Test; - friend class Azure::Core::Test::CurlConnectionPool_uniquePort_Test; -#endif - - public: - ~CurlConnectionPool() - { - using namespace Azure::Core::Http::_detail; - if (m_cleanThread.joinable()) - { - { - std::unique_lock lock(ConnectionPoolMutex); - // Remove all connections - g_curlConnectionPool.ConnectionPoolIndex.clear(); - } - // Signal clean thread to wake up - ConditionalVariableForCleanThread.notify_one(); - // join thread - m_cleanThread.join(); - } - curl_global_cleanup(); - } - - /** - * @brief Finds a connection to be re-used from the connection pool. - * @remark If there is not any available connection, a new connection is created. - * - * @param request HTTP request to get #Azure::Core::Http::CurlNetworkConnection for. - * @param options The connection settings which includes host name and libcurl handle specific - * configuration. - * @param resetPool Request the pool to remove all current connections for the provided - * options to force the creation of a new connection. - * - * @return #Azure::Core::Http::CurlNetworkConnection to use. - */ - std::unique_ptr ExtractOrCreateCurlConnection( - Request& request, - CurlTransportOptions const& options, - bool resetPool = false); - - /** - * @brief Moves a connection back to the pool to be re-used. - * - * @param connection CURL HTTP connection to add to the pool. - * @param lastStatusCode The most recent HTTP status code received from the \p connection. - */ - void MoveConnectionBackToPool( - std::unique_ptr connection, - HttpStatusCode lastStatusCode); - - /** - * @brief Keeps a unique key for each host and creates a connection pool for each key. - * - * @details This way getting a connection for a specific host can be done in O(1) instead of - * looping a single connection list to find the first connection for the required host. - * - * @remark There might be multiple connections for each host. - */ - std::map>> ConnectionPoolIndex; - - std::mutex ConnectionPoolMutex; - - // This is used to put the cleaning pool thread to sleep and yet to be able to wake it if the - // application finishes. - std::condition_variable ConditionalVariableForCleanThread; - - AZ_CORE_DLLEXPORT static Azure::Core::Http::_detail::CurlConnectionPool g_curlConnectionPool; - - bool IsCleanThreadRunning = false; - - private: - // private constructor to keep this as singleton. - CurlConnectionPool() { curl_global_init(CURL_GLOBAL_ALL); } - - // Makes possible to know the number of current connections in the connection pool for an - // index - int64_t ConnectionsOnPool(std::string const& host) { return ConnectionPoolIndex[host].size(); }; - - std::thread m_cleanThread; - }; - -}}}} // namespace Azure::Core::Http::_detail diff --git a/sdk/core/azure-core/src/private/curl_session.hpp b/sdk/core/azure-core/src/private/curl_session.hpp deleted file mode 100644 index d4be31084..000000000 --- a/sdk/core/azure-core/src/private/curl_session.hpp +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// SPDX-License-Identifier: MIT - -/** - * @file - * @brief The curl session consumes a curl connection to perform a request with it and start - * streaming the response. - * - * @remark The curl session is a body stream derived class. - */ - -#pragma once - -#include "azure/core/http/http.hpp" - -#include "private/curl_connection.hpp" -#include "private/curl_connection_pool.hpp" - -#include -#include - -#ifdef TESTING_BUILD -// Define the class name that reads from ConnectionPool private members -namespace Azure { namespace Core { namespace Test { - class CurlConnectionPool_connectionPoolTest_Test; -}}} // namespace Azure::Core::Test -#endif - -namespace Azure { namespace Core { namespace Http { - - /** - * @brief Stateful component that controls sending an HTTP Request with libcurl over the wire. - * - * @remark This component does not use the classic libcurl easy interface to send and receive - * bytes from the network using callbacks. Instead, `CurlSession` supports working with the custom - * HTTP protocol option from libcurl to manually upload and download bytes from the network socket - * using curl_easy_send() and curl_easy_recv(). - * - * @remarks This component is expected to be used by an HTTP Transporter to ensure that - * transporter to be reusable in multiple pipelines while every call to network is unique. - */ - class CurlSession final : public Azure::Core::IO::BodyStream { -#ifdef TESTING_BUILD - // Give access to private to this tests class - friend class Azure::Core::Test::CurlConnectionPool_connectionPoolTest_Test; -#endif - private: - /** - * @brief Read one expected byte and throw if it is different than the \p expected - * - */ - void ReadExpected(uint8_t expected, Context const& context); - - /** - * @brief Read `\\r\\n` from internal buffer or from the wire. - * - * @remark throw if `\\r\\n` are not the next data read. - */ - void ReadCRLF(Context const& context); - - /** - * @brief This is used to set the current state of a session. - * - * @remark The session needs to know what's the state on it when an exception occurs so the - * connection is not moved back to the connection pool. When a new request is going to be sent, - * the session will be in `PERFORM` until the request has been uploaded and a response code is - * received from the server. At that point the state will change to `STREAMING`. - * If there is any error before changing the state, the connection need to be cleaned up. - * - */ - enum class SessionState - { - PERFORM, - STREAMING - }; - - /* - * Enum used by ResponseBufferParser to control the parsing internal state while building - * the HTTP RawResponse - * - */ - enum class ResponseParserState - { - StatusLine, - Headers, - EndOfHeaders, - }; - - /** - * @brief stateful component used to read and parse a buffer to construct a valid HTTP - * RawResponse. - * - * @remark It uses an internal string as a buffer to accumulate a response token (version, code, - * header, etc.) until the next delimiter is found. Then it uses this string to keep building - * the HTTP RawResponse. - * - * @remark Only status line and headers are parsed and built. Body is ignored by this - * component. A libcurl session will use this component to build and return the HTTP - * RawResponse with a body stream to the pipeline. - */ - class ResponseBufferParser final { - private: - /** - * @brief Controls what the parser is expecting during the reading process - * - */ - ResponseParserState state = ResponseParserState::StatusLine; - /** - * @brief Unique ptr to a response. Parser will create an Initial-valid HTTP RawResponse and - * then it will append headers to it. This response is moved to a different owner once - * parsing is completed. - * - */ - std::unique_ptr m_response; - /** - * @brief Indicates if parser has found the end of the headers and there is nothing left for - * the HTTP RawResponse. - * - */ - bool m_parseCompleted = false; - - bool m_delimiterStartInPrevPosition = false; - - /** - * @brief This buffer is used when the parsed buffer doesn't contain a completed token. The - * content from the buffer will be appended to this buffer. Once that a delimiter is found, - * the token for the HTTP RawResponse is taken from this internal sting if it contains data. - * - * @remark This buffer allows a libcurl session to use any size of buffer to read from a - * socket while constructing an initial valid HTTP RawResponse. No matter if the response - * from wire contains hundreds of headers, we can use only one fixed size buffer to parse it - * all. - * - */ - std::string m_internalBuffer; - - /** - * @brief This method is invoked by the Parsing process if the internal state is set to - * status code. Function will get the status-line expected tokens until finding the end of - * status line delimiter. - * - * @remark When the end of status line delimiter is found, this method will create the HTTP - * RawResponse. The HTTP RawResponse is constructed by default with body type as Stream. - * - * @param buffer Points to a memory address with all or some part of a HTTP status line. - * @param bufferSize Indicates the size of the buffer. - * @return Returns the index of the last parsed position from buffer. - */ - int64_t BuildStatusCode(uint8_t const* const buffer, int64_t const bufferSize); - - /** - * @brief This method is invoked by the Parsing process if the internal state is set to - * headers. Function will keep adding headers to the HTTP RawResponse created before while - * parsing an status line. - * - * @param buffer Points to a memory address with all or some part of a HTTP header. - * @param bufferSize Indicates the size of the buffer. - * @return Returns the index of the last parsed position from buffer. When the returned - * value is smaller than the body size, means there is part of the body response in the - * buffer. - */ - int64_t BuildHeader(uint8_t const* const buffer, int64_t const bufferSize); - - public: - /** - * @brief Construct a new RawResponse Buffer Parser object. - * - */ - ResponseBufferParser() {} - - /** - * @brief Parses the content of a buffer to construct a valid HTTP RawResponse. This method - * is expected to be called over and over until it returns 0, indicating there is nothing - * more to parse to build the HTTP RawResponse. - * - * @param buffer points to a memory area that contains, all or some part of an HTTP - * response. - * @param bufferSize Indicates the size of the buffer. - * @return Returns the index of the last parsed position. Returning a 0 means nothing was - * parsed and it is likely that the HTTP RawResponse is completed. Returning the same value - * as the buffer size means all buffer was parsed and the HTTP might be completed or not. - * Returning a value smaller than the buffer size will likely indicate that the HTTP - * RawResponse is completed and that the rest of the buffer contains part of the response - * body. - */ - int64_t Parse(uint8_t const* const buffer, int64_t const bufferSize); - - /** - * @brief Indicates when the parser has completed parsing and building the HTTP RawResponse. - * - * @return `true` if parsing is completed. Otherwise `false`. - */ - bool IsParseCompleted() const { return m_parseCompleted; } - - /** - * @brief Moves the internal response to a different owner. - * - * @return Will move the response only if parsing is completed and if the HTTP RawResponse - * was not moved before. - */ - std::unique_ptr ExtractResponse() - { - if (m_parseCompleted && m_response != nullptr) - { - return std::move(m_response); - } - return nullptr; // parse is not completed or response has been moved already. - } - }; - - /** - * @brief The current state of the session. - * - * @remark The state of the session is used to determine if a connection can be moved back to - * the connection pool or not. A connection can be re-used only when the session state is - * `STREAMING` and the response has been read completely. - * - */ - SessionState m_sessionState = SessionState::PERFORM; - - std::unique_ptr m_connection; - - /** - * @brief unique ptr for the HTTP RawResponse. The session is responsable for creating the - * response once that an HTTP status line is received. - * - */ - std::unique_ptr m_response; - - /** - * @brief The HTTP Request for to be used by the session. - * - */ - Request& m_request; - - /** - * @brief Control field to handle the case when part of HTTP response body was copied to the - * inner buffer. When a libcurl stream tries to read part of the body, this field will help to - * decide how much data to take from the inner buffer before pulling more data from network. - * - */ - int64_t m_bodyStartInBuffer = -1; - - /** - * @brief Control field to handle the number of bytes containing relevant data within the - * internal buffer. This is because internal buffer can be set to be size N but after writing - * from wire into it, it can be holding less then N bytes. - * - */ - int64_t m_innerBufferSize = _detail::DefaultLibcurlReaderSize; - - bool m_isChunkedResponseType = false; - - /** - * @brief This is a copy of the value of an HTTP response header `content-length`. The value - * is received as string and parsed to size_t. This field avoid parsing the string header - * every time from HTTP RawResponse. - * - * @remark This value is also used to avoid trying to read more data from network than what we - * are expecting to. - * - */ - int64_t m_contentLength = 0; - - /** - * @brief For chunked responses, this field knows the size of the current chuck size server - * will de sending - * - */ - int64_t m_chunkSize = 0; - - int64_t m_sessionTotalRead = 0; - - /** - * @brief Internal buffer from a session used to read bytes from a socket. This buffer is only - * used while constructing an HTTP RawResponse without adding a body to it. Customers would - * provide their own buffer to copy from socket when reading the HTTP body using streams. - * - */ - uint8_t m_readBuffer[_detail::DefaultLibcurlReaderSize] - = {0}; // to work with libcurl custom read. - - /** - * @brief Function used when working with Streams to manually write from the HTTP Request to - * the wire. - * - * @param context #Azure::Core::Context so that operation can be cancelled. - * - * @return CURL_OK when response is sent successfully. - */ - CURLcode SendRawHttp(Context const& context); - - /** - * @brief Upload body. - * - * @param context #Azure::Core::Context so that operation can be cancelled. - * - * @return Curl code. - */ - CURLcode UploadBody(Context const& context); - - /** - * @brief This function is used after sending an HTTP request to the server to read the HTTP - * RawResponse from wire until the end of headers only. - * - * @param context #Azure::Core::Context so that operation can be cancelled. - * @param reuseInternalBuffer Indicates whether the internal buffer should be reused. - */ - void ReadStatusLineAndHeadersFromRawResponse( - Context const& context, - bool reuseInternalBuffer = false); - - /** - * @brief Reads from inner buffer or from Wire until chunkSize is parsed and converted to - * unsigned long long - * - * @param context #Azure::Core::Context so that operation can be cancelled. - */ - void ParseChunkSize(Context const& context); - - /** - * @brief Last HTTP status code read. - * - * @remark The last status is initialized as a bad request just as a way to know that there's - * not a good request performed by the session. The status will be updated as soon as the - * session sent a request and it is used to decide if a connection can be re-used or not. - */ - Http::HttpStatusCode m_lastStatusCode = Http::HttpStatusCode::BadRequest; - - /** - * @brief check whether an end of file has been reached. - * @return `true` if end of file has been reached, `false` otherwise. - */ - bool IsEOF() - { - auto eof = m_isChunkedResponseType ? m_chunkSize == 0 : m_contentLength == m_sessionTotalRead; - - // `IsEOF` is called before trying to move a connection back to the connection pool. - // If the session state is `PERFORM` it means the request could not complete an upload - // operation (might have throw while uploading). - // Connection should not be moved back to the connection pool on this scenario. - return eof && m_sessionState != SessionState::PERFORM; - } - - /** - * @brief All connections will request to keep the channel open to re-use the - * connection. - * - * @remark This option can be disabled from the transport adapter options. When disabled, the - * session won't return connections to the connection pool. Connection will be closed as soon as - * the request is completed. - * - */ - bool m_keepAlive = true; - - /** - * @brief Implement #Azure::Core::IO::BodyStream::OnRead(). Calling this function pulls data - * from the wire. - * - * @param context #Azure::Core::Context so that operation can be cancelled. - * @param buffer Buffer where data from wire is written to. - * @param count The number of bytes to read from the network. - * @return The actual number of bytes read from the network. - */ - size_t OnRead(uint8_t* buffer, size_t count, Azure::Core::Context const& context) override; - - public: - /** - * @brief Construct a new Curl Session object. Init internal libcurl handler. - * - * @param request reference to an HTTP Request. - */ - CurlSession(Request& request, std::unique_ptr connection, bool keepAlive) - : m_connection(std::move(connection)), m_request(request), m_keepAlive(keepAlive) - { - } - - ~CurlSession() override - { - // mark connection as reusable only if entire response was read - // If not, connection can't be reused because next Read will start from what it is currently - // in the wire. - // By not moving the connection back to the pool, it gets destroyed calling the connection - // destructor to clean libcurl handle and close the connection. - // IsEOF will also handle a connection that fail to complete an upload request. - if (IsEOF() && m_keepAlive) - { - _detail::CurlConnectionPool::g_curlConnectionPool.MoveConnectionBackToPool( - std::move(m_connection), m_lastStatusCode); - } - } - - /** - * @brief Function will use the HTTP request received in constructor to perform a network call - * based on the HTTP request configuration. - * - * @param context #Azure::Core::Context so that operation can be cancelled. - * @return CURLE_OK when the network call is completed successfully. - */ - CURLcode Perform(Context const& context); - - /** - * @brief Moved the ownership of the HTTP RawResponse out of the session. - * - * @return the unique ptr to the HTTP RawResponse or null if the HTTP RawResponse is not yet - * created or was moved before. - */ - std::unique_ptr ExtractResponse(); - - /** - * @brief Implement #Azure::Core::IO::BodyStream length. - * - * @return The size of the payload. - */ - int64_t Length() const override { return m_contentLength; } - }; - -}}} // namespace Azure::Core::Http diff --git a/sdk/core/azure-core/test/ut/azure_libcurl_core_main_test.cpp b/sdk/core/azure-core/test/ut/azure_libcurl_core_main_test.cpp index 43ae6db3b..c85e97728 100644 --- a/sdk/core/azure-core/test/ut/azure_libcurl_core_main_test.cpp +++ b/sdk/core/azure-core/test/ut/azure_libcurl_core_main_test.cpp @@ -25,9 +25,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include diff --git a/sdk/core/azure-core/test/ut/curl_connection_pool_test.cpp b/sdk/core/azure-core/test/ut/curl_connection_pool_test.cpp index cfed7b06c..028288df0 100644 --- a/sdk/core/azure-core/test/ut/curl_connection_pool_test.cpp +++ b/sdk/core/azure-core/test/ut/curl_connection_pool_test.cpp @@ -15,11 +15,10 @@ #include // The next includes are from Azure Core private headers. -// That's why the path starts from `private/` // They are included to test the connection pool from the libcurl transport adapter implementation. -#include -#include -#include +#include +#include +#include #include "curl_session_test.hpp" diff --git a/sdk/core/azure-core/test/ut/curl_options_test.cpp b/sdk/core/azure-core/test/ut/curl_options_test.cpp index 490057e53..75fb89929 100644 --- a/sdk/core/azure-core/test/ut/curl_options_test.cpp +++ b/sdk/core/azure-core/test/ut/curl_options_test.cpp @@ -14,8 +14,8 @@ #include "azure/core/http/curl_transport.hpp" #endif -#include -#include +#include +#include #include "transport_adapter_base_test.hpp" diff --git a/sdk/core/azure-core/test/ut/curl_session_test.hpp b/sdk/core/azure-core/test/ut/curl_session_test.hpp index 2b565946b..fc6b28c14 100644 --- a/sdk/core/azure-core/test/ut/curl_session_test.hpp +++ b/sdk/core/azure-core/test/ut/curl_session_test.hpp @@ -24,7 +24,7 @@ #include #include -#include +#include namespace Azure { namespace Core { namespace Test { diff --git a/sdk/core/azure-core/test/ut/curl_session_test_test.cpp b/sdk/core/azure-core/test/ut/curl_session_test_test.cpp index e625597c9..ae3dfc0e8 100644 --- a/sdk/core/azure-core/test/ut/curl_session_test_test.cpp +++ b/sdk/core/azure-core/test/ut/curl_session_test_test.cpp @@ -6,8 +6,8 @@ #include #include -#include -#include +#include +#include using ::testing::_; using ::testing::DoAll;