Lesson 35 - Get Compute Auth Token Working
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/common/common.h>
|
||||
#include <aws/crt/Exports.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
using Allocator = aws_allocator;
|
||||
|
||||
/**
|
||||
* Each object from this library can use an explicit allocator.
|
||||
* If you construct an object without specifying an allocator,
|
||||
* then THIS allocator is used instead.
|
||||
*
|
||||
* You can customize this allocator when initializing
|
||||
* \ref ApiHandle::ApiHandle(Allocator*) "ApiHandle".
|
||||
*/
|
||||
AWS_CRT_CPP_API Allocator *ApiAllocator() noexcept;
|
||||
|
||||
/**
|
||||
* Returns the default implementation of an Allocator.
|
||||
*
|
||||
* If you initialize \ref ApiHandle::ApiHandle(Allocator*) "ApiHandle"
|
||||
* without specifying a custom allocator, then this implementation is used.
|
||||
*/
|
||||
AWS_CRT_CPP_API Allocator *DefaultAllocatorImplementation() noexcept;
|
||||
|
||||
/**
|
||||
* @deprecated Use DefaultAllocatorImplementation() instead.
|
||||
* DefaultAllocator() is too easily confused with ApiAllocator().
|
||||
*/
|
||||
AWS_CRT_CPP_API Allocator *DefaultAllocator() noexcept;
|
||||
|
||||
/**
|
||||
* @deprecated Use ApiAllocator() instead, to avoid issues with delay-loaded DLLs.
|
||||
* https://github.com/aws/aws-sdk-cpp/issues/1960
|
||||
*/
|
||||
extern AWS_CRT_CPP_API Allocator *g_allocator;
|
||||
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
240
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/Api.h
Normal file
240
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/Api.h
Normal file
@@ -0,0 +1,240 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/crt/crypto/HMAC.h>
|
||||
#include <aws/crt/crypto/Hash.h>
|
||||
#include <aws/crt/mqtt/Mqtt5Client.h>
|
||||
#include <aws/crt/mqtt/MqttClient.h>
|
||||
|
||||
#include <aws/common/logging.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
/**
|
||||
* Detail level control for logging output
|
||||
*/
|
||||
enum class LogLevel
|
||||
{
|
||||
None = AWS_LL_NONE,
|
||||
Fatal = AWS_LL_FATAL,
|
||||
Error = AWS_LL_ERROR,
|
||||
Warn = AWS_LL_WARN,
|
||||
Info = AWS_LL_INFO,
|
||||
Debug = AWS_LL_DEBUG,
|
||||
Trace = AWS_LL_TRACE,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
/**
|
||||
* Should the API Handle destructor block on all shutdown/thread completion logic or not?
|
||||
*/
|
||||
enum class ApiHandleShutdownBehavior
|
||||
{
|
||||
Blocking,
|
||||
NonBlocking
|
||||
};
|
||||
|
||||
/**
|
||||
* A singleton object representing the init/cleanup state of the entire CRT. It's invalid to have more than one
|
||||
* active simultaneously and it's also invalid to use CRT functionality without one active.
|
||||
*/
|
||||
class AWS_CRT_CPP_API ApiHandle
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Customize the ApiAllocator(), which is be used by any objects
|
||||
* constructed without an explicit allocator.
|
||||
*/
|
||||
ApiHandle(Allocator *allocator) noexcept;
|
||||
ApiHandle() noexcept;
|
||||
~ApiHandle();
|
||||
ApiHandle(const ApiHandle &) = delete;
|
||||
ApiHandle(ApiHandle &&) = delete;
|
||||
ApiHandle &operator=(const ApiHandle &) = delete;
|
||||
ApiHandle &operator=(ApiHandle &&) = delete;
|
||||
|
||||
/**
|
||||
* Initialize logging in awscrt.
|
||||
* @param level: Display messages of this importance and higher. LogLevel.NoLogs will disable
|
||||
* logging.
|
||||
* @param filename: Logging destination, a file path from the disk.
|
||||
*/
|
||||
void InitializeLogging(LogLevel level, const char *filename);
|
||||
|
||||
/**
|
||||
* Initialize logging in awscrt.
|
||||
* @param level: Display messages of this importance and higher. LogLevel.NoLogs will disable
|
||||
* logging.
|
||||
* @param fp: The FILE object for logging destination.
|
||||
*/
|
||||
void InitializeLogging(LogLevel level, FILE *fp);
|
||||
|
||||
/**
|
||||
* Configures the shutdown behavior of the api handle instance
|
||||
* @param behavior desired shutdown behavior
|
||||
*/
|
||||
void SetShutdownBehavior(ApiHandleShutdownBehavior behavior);
|
||||
|
||||
/**
|
||||
* BYO_CRYPTO: set callback for creating MD5 hashes.
|
||||
* If using BYO_CRYPTO, you must call this.
|
||||
*/
|
||||
void SetBYOCryptoNewMD5Callback(Crypto::CreateHashCallback &&callback);
|
||||
|
||||
/**
|
||||
* BYO_CRYPTO: set callback for creating SHA256 hashes.
|
||||
* If using BYO_CRYPTO, you must call this.
|
||||
*/
|
||||
void SetBYOCryptoNewSHA256Callback(Crypto::CreateHashCallback &&callback);
|
||||
|
||||
/**
|
||||
* BYO_CRYPTO: set callback for creating SHA1 hashes.
|
||||
* If using BYO_CRYPTO, you must call this.
|
||||
*/
|
||||
void SetBYOCryptoNewSHA1Callback(Crypto::CreateHashCallback &&callback);
|
||||
|
||||
/**
|
||||
* BYO_CRYPTO: set callback for creating Streaming SHA256 HMAC objects.
|
||||
* If using BYO_CRYPTO, you must call this.
|
||||
*/
|
||||
void SetBYOCryptoNewSHA256HMACCallback(Crypto::CreateHMACCallback &&callback);
|
||||
|
||||
/**
|
||||
* BYO_CRYPTO: set callback for creating a ClientTlsChannelHandler.
|
||||
* If using BYO_CRYPTO, you must call this prior to creating any client channels in the
|
||||
* application.
|
||||
*/
|
||||
void SetBYOCryptoClientTlsCallback(Io::NewClientTlsHandlerCallback &&callback);
|
||||
|
||||
/**
|
||||
* BYO_CRYPTO: set callbacks for the TlsContext.
|
||||
* If using BYO_CRYPTO, you need to call this function prior to creating a TlsContext.
|
||||
*
|
||||
* @param newCallback Create custom implementation object, to be stored inside TlsContext.
|
||||
* Return nullptr if failure occurs.
|
||||
* @param deleteCallback Destroy object that was created by newCallback.
|
||||
* @param alpnCallback Return whether ALPN is supported.
|
||||
*/
|
||||
void SetBYOCryptoTlsContextCallbacks(
|
||||
Io::NewTlsContextImplCallback &&newCallback,
|
||||
Io::DeleteTlsContextImplCallback &&deleteCallback,
|
||||
Io::IsTlsAlpnSupportedCallback &&alpnCallback);
|
||||
|
||||
/// @private
|
||||
static const Io::NewTlsContextImplCallback &GetBYOCryptoNewTlsContextImplCallback();
|
||||
/// @private
|
||||
static const Io::DeleteTlsContextImplCallback &GetBYOCryptoDeleteTlsContextImplCallback();
|
||||
/// @private
|
||||
static const Io::IsTlsAlpnSupportedCallback &GetBYOCryptoIsTlsAlpnSupportedCallback();
|
||||
|
||||
/**
|
||||
* Gets the static default ClientBootstrap, creating it if necessary.
|
||||
*
|
||||
* This default will be used when a ClientBootstrap is not explicitly passed but is needed
|
||||
* to allow the process to function. An example of this would be in the MQTT connection creation workflow.
|
||||
* The default ClientBootstrap will use the default EventLoopGroup and HostResolver, creating them if
|
||||
* necessary.
|
||||
*
|
||||
* The default ClientBootstrap will be automatically managed and released by the API handle when it's
|
||||
* resources are being freed, not requiring any manual memory management.
|
||||
*
|
||||
* @return ClientBootstrap* A pointer to the static default ClientBootstrap
|
||||
*/
|
||||
static Io::ClientBootstrap *GetOrCreateStaticDefaultClientBootstrap();
|
||||
|
||||
/**
|
||||
* Gets the static default EventLoopGroup, creating it if necessary.
|
||||
*
|
||||
* This default will be used when a EventLoopGroup is not explicitly passed but is needed
|
||||
* to allow the process to function. An example of this would be in the MQTT connection creation workflow.
|
||||
*
|
||||
* The EventLoopGroup will automatically pick a default number of threads based on the system. You can
|
||||
* manually adjust the number of threads being used by creating a EventLoopGroup and passing it through
|
||||
* the SetDefaultEventLoopGroup function.
|
||||
*
|
||||
* The default EventLoopGroup will be automatically managed and released by the API handle when it's
|
||||
* resources are being freed, not requiring any manual memory management.
|
||||
*
|
||||
* @return EventLoopGroup* A pointer to the static default EventLoopGroup
|
||||
*/
|
||||
static Io::EventLoopGroup *GetOrCreateStaticDefaultEventLoopGroup();
|
||||
|
||||
/**
|
||||
* Gets the static default HostResolver, creating it if necessary.
|
||||
*
|
||||
* This default will be used when a HostResolver is not explicitly passed but is needed
|
||||
* to allow the process to function. An example of this would be in the MQTT connection creation workflow.
|
||||
*
|
||||
* The HostResolver will be set to have a maximum of 8 entries by default. You can
|
||||
* manually adjust the maximum number of entries being used by creating a HostResolver and passing it
|
||||
* through the SetDefaultEventLoopGroup function.
|
||||
*
|
||||
* The default HostResolver will be automatically managed and released by the API handle when it's
|
||||
* resources are being freed, not requiring any manual memory management.
|
||||
*
|
||||
* @return HostResolver* A pointer to the static default HostResolver
|
||||
*/
|
||||
static Io::HostResolver *GetOrCreateStaticDefaultHostResolver();
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct Version
|
||||
{
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
uint16_t patch;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
/**
|
||||
* Gets the version of the AWS-CRT-CPP library
|
||||
* @return Version representing the library version
|
||||
*/
|
||||
Version GetCrtVersion() const;
|
||||
|
||||
private:
|
||||
void InitializeLoggingCommon(struct aws_logger_standard_options &options);
|
||||
|
||||
aws_logger m_logger;
|
||||
|
||||
ApiHandleShutdownBehavior m_shutdownBehavior;
|
||||
|
||||
static Io::ClientBootstrap *s_static_bootstrap;
|
||||
static std::mutex s_lock_client_bootstrap;
|
||||
static void ReleaseStaticDefaultClientBootstrap();
|
||||
|
||||
static Io::EventLoopGroup *s_static_event_loop_group;
|
||||
static std::mutex s_lock_event_loop_group;
|
||||
static void ReleaseStaticDefaultEventLoopGroup();
|
||||
|
||||
static int s_host_resolver_default_max_hosts;
|
||||
static Io::HostResolver *s_static_default_host_resolver;
|
||||
static std::mutex s_lock_default_host_resolver;
|
||||
static void ReleaseStaticDefaultHostResolver();
|
||||
|
||||
Version m_version = {0, 0, 0};
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a string description of a CRT error code
|
||||
* @param error error code to get a descriptive string for
|
||||
* @return a string description of the error code
|
||||
*/
|
||||
AWS_CRT_CPP_API const char *ErrorDebugString(int error) noexcept;
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error on the current thread. Return 0 if no aws-error raised before.
|
||||
*/
|
||||
AWS_CRT_CPP_API int LastError() noexcept;
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error on the current thread. Return AWS_ERROR_UNKNOWN, if no aws-error
|
||||
* raised before.
|
||||
*/
|
||||
AWS_CRT_CPP_API int LastErrorOrUnknown() noexcept;
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#define AWS_CRT_CPP_VERSION "0.29.3"
|
||||
#define AWS_CRT_CPP_VERSION_MAJOR 0
|
||||
#define AWS_CRT_CPP_VERSION_MINOR 29
|
||||
#define AWS_CRT_CPP_VERSION_PATCH 3
|
||||
#define AWS_CRT_CPP_GIT_HASH "281a7caff7e10f68a5422d8fca8acf0b48e4215f"
|
||||
198
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/DateTime.h
Normal file
198
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/DateTime.h
Normal file
@@ -0,0 +1,198 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/Exports.h>
|
||||
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
#include <aws/common/date_time.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
enum class DateFormat
|
||||
{
|
||||
RFC822 = AWS_DATE_FORMAT_RFC822,
|
||||
ISO_8601 = AWS_DATE_FORMAT_ISO_8601,
|
||||
AutoDetect = AWS_DATE_FORMAT_AUTO_DETECT,
|
||||
};
|
||||
|
||||
enum class Month
|
||||
{
|
||||
January = AWS_DATE_MONTH_JANUARY,
|
||||
February = AWS_DATE_MONTH_FEBRUARY,
|
||||
March = AWS_DATE_MONTH_MARCH,
|
||||
April = AWS_DATE_MONTH_APRIL,
|
||||
May = AWS_DATE_MONTH_MAY,
|
||||
June = AWS_DATE_MONTH_JUNE,
|
||||
July = AWS_DATE_MONTH_JULY,
|
||||
August = AWS_DATE_MONTH_AUGUST,
|
||||
September = AWS_DATE_MONTH_SEPTEMBER,
|
||||
October = AWS_DATE_MONTH_OCTOBER,
|
||||
November = AWS_DATE_MONTH_NOVEMBER,
|
||||
December = AWS_DATE_MONTH_DECEMBER,
|
||||
};
|
||||
|
||||
enum class DayOfWeek
|
||||
{
|
||||
Sunday = AWS_DATE_DAY_OF_WEEK_SUNDAY,
|
||||
Monday = AWS_DATE_DAY_OF_WEEK_MONDAY,
|
||||
Tuesday = AWS_DATE_DAY_OF_WEEK_TUESDAY,
|
||||
Wednesday = AWS_DATE_DAY_OF_WEEK_WEDNESDAY,
|
||||
Thursday = AWS_DATE_DAY_OF_WEEK_THURSDAY,
|
||||
Friday = AWS_DATE_DAY_OF_WEEK_FRIDAY,
|
||||
Saturday = AWS_DATE_DAY_OF_WEEK_SATURDAY,
|
||||
};
|
||||
|
||||
class AWS_CRT_CPP_API DateTime final
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initializes time point to epoch
|
||||
*/
|
||||
DateTime() noexcept;
|
||||
|
||||
/**
|
||||
* Initializes time point to any other arbitrary timepoint
|
||||
*/
|
||||
DateTime(const std::chrono::system_clock::time_point &timepointToAssign) noexcept;
|
||||
|
||||
/**
|
||||
* Initializes time point to millis Since epoch
|
||||
*/
|
||||
DateTime(uint64_t millisSinceEpoch) noexcept;
|
||||
|
||||
/**
|
||||
* Initializes time point to epoch time in seconds.millis
|
||||
*/
|
||||
DateTime(double epoch_millis) noexcept;
|
||||
|
||||
/**
|
||||
* Initializes time point to value represented by timestamp and format.
|
||||
*/
|
||||
DateTime(const char *timestamp, DateFormat format) noexcept;
|
||||
|
||||
bool operator==(const DateTime &other) const noexcept;
|
||||
bool operator<(const DateTime &other) const noexcept;
|
||||
bool operator>(const DateTime &other) const noexcept;
|
||||
bool operator!=(const DateTime &other) const noexcept;
|
||||
bool operator<=(const DateTime &other) const noexcept;
|
||||
bool operator>=(const DateTime &other) const noexcept;
|
||||
|
||||
DateTime operator+(const std::chrono::milliseconds &a) const noexcept;
|
||||
DateTime operator-(const std::chrono::milliseconds &a) const noexcept;
|
||||
|
||||
/**
|
||||
* Assign from seconds.millis since epoch.
|
||||
*/
|
||||
DateTime &operator=(double secondsSinceEpoch) noexcept;
|
||||
|
||||
/**
|
||||
* Assign from millis since epoch.
|
||||
*/
|
||||
DateTime &operator=(uint64_t millisSinceEpoch) noexcept;
|
||||
|
||||
/**
|
||||
* Assign from another time_point
|
||||
*/
|
||||
DateTime &operator=(const std::chrono::system_clock::time_point &timepointToAssign) noexcept;
|
||||
|
||||
/**
|
||||
* Assign from an ISO8601 or RFC822 formatted string
|
||||
*/
|
||||
DateTime &operator=(const char *timestamp) noexcept;
|
||||
|
||||
explicit operator bool() const noexcept;
|
||||
int GetLastError() const noexcept;
|
||||
|
||||
/**
|
||||
* Convert dateTime to local time string using predefined format.
|
||||
*/
|
||||
bool ToLocalTimeString(DateFormat format, ByteBuf &outputBuf) const noexcept;
|
||||
|
||||
/**
|
||||
* Convert dateTime to GMT time string using predefined format.
|
||||
*/
|
||||
bool ToGmtString(DateFormat format, ByteBuf &outputBuf) const noexcept;
|
||||
|
||||
/**
|
||||
* Get the representation of this datetime as seconds.milliseconds since epoch
|
||||
*/
|
||||
double SecondsWithMSPrecision() const noexcept;
|
||||
|
||||
/**
|
||||
* Milliseconds since epoch of this datetime.
|
||||
*/
|
||||
uint64_t Millis() const noexcept;
|
||||
|
||||
/**
|
||||
* In the likely case this class doesn't do everything you need to do, here's a copy of the time_point
|
||||
* structure. Have fun.
|
||||
*/
|
||||
std::chrono::system_clock::time_point UnderlyingTimestamp() const noexcept;
|
||||
|
||||
/**
|
||||
* Get the Year portion of this dateTime. localTime if true, return local time, otherwise return UTC
|
||||
*/
|
||||
uint16_t GetYear(bool localTime = false) const noexcept;
|
||||
|
||||
/**
|
||||
* Get the Month portion of this dateTime. localTime if true, return local time, otherwise return UTC
|
||||
*/
|
||||
Month GetMonth(bool localTime = false) const noexcept;
|
||||
|
||||
/**
|
||||
* Get the Day of the Month portion of this dateTime. localTime if true, return local time, otherwise return
|
||||
* UTC
|
||||
*/
|
||||
uint8_t GetDay(bool localTime = false) const noexcept;
|
||||
|
||||
/**
|
||||
* Get the Day of the Week portion of this dateTime. localTime if true, return local time, otherwise return
|
||||
* UTC
|
||||
*/
|
||||
DayOfWeek GetDayOfWeek(bool localTime = false) const noexcept;
|
||||
|
||||
/**
|
||||
* Get the Hour portion of this dateTime. localTime if true, return local time, otherwise return UTC
|
||||
*/
|
||||
uint8_t GetHour(bool localTime = false) const noexcept;
|
||||
|
||||
/**
|
||||
* Get the Minute portion of this dateTime. localTime if true, return local time, otherwise return UTC
|
||||
*/
|
||||
uint8_t GetMinute(bool localTime = false) const noexcept;
|
||||
|
||||
/**
|
||||
* Get the Second portion of this dateTime. localTime if true, return local time, otherwise return UTC
|
||||
*/
|
||||
uint8_t GetSecond(bool localTime = false) const noexcept;
|
||||
|
||||
/**
|
||||
* Get whether or not this dateTime is in Daylight savings time. localTime if true, return local time,
|
||||
* otherwise return UTC
|
||||
*/
|
||||
bool IsDST(bool localTime = false) const noexcept;
|
||||
|
||||
/**
|
||||
* Get an instance of DateTime representing this very instant.
|
||||
*/
|
||||
static DateTime Now() noexcept;
|
||||
|
||||
/**
|
||||
* Computes the difference between two DateTime instances and returns the difference
|
||||
* in milliseconds.
|
||||
*/
|
||||
std::chrono::milliseconds operator-(const DateTime &other) const noexcept;
|
||||
|
||||
private:
|
||||
aws_date_time m_date_time;
|
||||
bool m_good;
|
||||
};
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
*Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
*Licensed under the Apache License, Version 2.0 (the "License").
|
||||
*You may not use this file except in compliance with the License.
|
||||
*A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined(USE_WINDOWS_DLL_SEMANTICS) || defined(WIN32)
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(disable : 4251)
|
||||
# endif // _MSC_VER
|
||||
# ifdef AWS_CRT_CPP_USE_IMPORT_EXPORT
|
||||
# ifdef AWS_CRT_CPP_EXPORTS
|
||||
# define AWS_CRT_CPP_API __declspec(dllexport)
|
||||
# else
|
||||
# define AWS_CRT_CPP_API __declspec(dllimport)
|
||||
# endif /* AWS_CRT_CPP_API */
|
||||
# else
|
||||
# define AWS_CRT_CPP_API
|
||||
# endif // AWS_CRT_CPP_USE_IMPORT_EXPORT
|
||||
|
||||
#else // defined (USE_WINDOWS_DLL_SEMANTICS) || defined (WIN32)
|
||||
# if ((__GNUC__ >= 4) || defined(__clang__)) && defined(AWS_CRT_CPP_USE_IMPORT_EXPORT) && \
|
||||
defined(AWS_CRT_CPP_EXPORTS)
|
||||
# define AWS_CRT_CPP_API __attribute__((visibility("default")))
|
||||
# else
|
||||
# define AWS_CRT_CPP_API
|
||||
# endif // __GNUC__ >= 4 || defined(__clang__)
|
||||
#endif
|
||||
@@ -0,0 +1,386 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/DateTime.h>
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/Types.h>
|
||||
#include <functional>
|
||||
|
||||
struct aws_credentials;
|
||||
struct aws_imds_client;
|
||||
struct aws_imds_instance_info;
|
||||
struct aws_imds_iam_profile;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
|
||||
namespace Crt
|
||||
{
|
||||
|
||||
namespace Io
|
||||
{
|
||||
class ClientBootstrap;
|
||||
}
|
||||
|
||||
namespace Auth
|
||||
{
|
||||
class Credentials;
|
||||
}
|
||||
|
||||
namespace Imds
|
||||
{
|
||||
|
||||
struct AWS_CRT_CPP_API ImdsClientConfig
|
||||
{
|
||||
ImdsClientConfig() : Bootstrap(nullptr) {}
|
||||
|
||||
/**
|
||||
* Connection bootstrap to use to create the http connection required to
|
||||
* query resource from the Ec2 instance metadata service
|
||||
*
|
||||
* Note: If null, then the default ClientBootstrap is used
|
||||
* (see Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap)
|
||||
*/
|
||||
Io::ClientBootstrap *Bootstrap;
|
||||
|
||||
/* Should add retry strategy support once that is available */
|
||||
};
|
||||
|
||||
/**
|
||||
* https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html
|
||||
*/
|
||||
struct AWS_CRT_CPP_API IamProfileView
|
||||
{
|
||||
DateTime lastUpdated;
|
||||
StringView instanceProfileArn;
|
||||
StringView instanceProfileId;
|
||||
};
|
||||
|
||||
/**
|
||||
* A convenient class for you to persist data from IamProfileView, which has StringView members.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API IamProfile
|
||||
{
|
||||
IamProfile() {}
|
||||
IamProfile(const IamProfileView &other);
|
||||
|
||||
IamProfile &operator=(const IamProfileView &other);
|
||||
|
||||
DateTime lastUpdated;
|
||||
String instanceProfileArn;
|
||||
String instanceProfileId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Block of per-instance EC2-specific data
|
||||
*
|
||||
* https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
|
||||
*/
|
||||
struct AWS_CRT_CPP_API InstanceInfoView
|
||||
{
|
||||
/* an array of StringView */
|
||||
Vector<StringView> marketplaceProductCodes;
|
||||
StringView availabilityZone;
|
||||
StringView privateIp;
|
||||
StringView version;
|
||||
StringView instanceId;
|
||||
/* an array of StringView */
|
||||
Vector<StringView> billingProducts;
|
||||
StringView instanceType;
|
||||
StringView accountId;
|
||||
StringView imageId;
|
||||
DateTime pendingTime;
|
||||
StringView architecture;
|
||||
StringView kernelId;
|
||||
StringView ramdiskId;
|
||||
StringView region;
|
||||
};
|
||||
|
||||
/**
|
||||
* A convenient class for you to persist data from InstanceInfoView, which has StringView members.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API InstanceInfo
|
||||
{
|
||||
InstanceInfo() {}
|
||||
InstanceInfo(const InstanceInfoView &other);
|
||||
|
||||
InstanceInfo &operator=(const InstanceInfoView &other);
|
||||
|
||||
/* an array of StringView */
|
||||
Vector<String> marketplaceProductCodes;
|
||||
String availabilityZone;
|
||||
String privateIp;
|
||||
String version;
|
||||
String instanceId;
|
||||
/* an array of StringView */
|
||||
Vector<String> billingProducts;
|
||||
String instanceType;
|
||||
String accountId;
|
||||
String imageId;
|
||||
DateTime pendingTime;
|
||||
String architecture;
|
||||
String kernelId;
|
||||
String ramdiskId;
|
||||
String region;
|
||||
};
|
||||
|
||||
using OnResourceAcquired = std::function<void(const StringView &resource, int errorCode, void *userData)>;
|
||||
using OnVectorResourceAcquired =
|
||||
std::function<void(const Vector<StringView> &resource, int errorCode, void *userData)>;
|
||||
using OnCredentialsAcquired =
|
||||
std::function<void(const Auth::Credentials &credentials, int errorCode, void *userData)>;
|
||||
using OnIamProfileAcquired =
|
||||
std::function<void(const IamProfileView &iamProfile, int errorCode, void *userData)>;
|
||||
using OnInstanceInfoAcquired =
|
||||
std::function<void(const InstanceInfoView &instanceInfo, int errorCode, void *userData)>;
|
||||
|
||||
class AWS_CRT_CPP_API ImdsClient
|
||||
{
|
||||
public:
|
||||
ImdsClient(const ImdsClientConfig &config, Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
~ImdsClient();
|
||||
|
||||
ImdsClient(const ImdsClient &) = delete;
|
||||
ImdsClient(ImdsClient &&) = delete;
|
||||
ImdsClient &operator=(const ImdsClient &) = delete;
|
||||
ImdsClient &operator=(ImdsClient &&) = delete;
|
||||
|
||||
aws_imds_client *GetUnderlyingHandle() { return m_client; }
|
||||
|
||||
/**
|
||||
* Queries a generic resource (string) from the ec2 instance metadata document
|
||||
*
|
||||
* @param resourcePath path of the resource to query
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetResource(const StringView &resourcePath, OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the ami id of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetAmiId(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the ami launch index of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetAmiLaunchIndex(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the ami manifest path of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetAmiManifestPath(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the list of ancestor ami ids of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetAncestorAmiIds(OnVectorResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the instance-action of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetInstanceAction(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the instance id of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetInstanceId(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the instance type of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetInstanceType(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the mac address of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetMacAddress(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the private ip address of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetPrivateIpAddress(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the availability zone of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetAvailabilityZone(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the product codes of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetProductCodes(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the public key of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetPublicKey(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the ramdisk id of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetRamDiskId(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the reservation id of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetReservationId(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the list of the security groups of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetSecurityGroups(OnVectorResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the list of block device mappings of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetBlockDeviceMapping(OnVectorResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the attached iam role of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetAttachedIamRole(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets temporary credentials based on the attached iam role of the ec2 instance
|
||||
*
|
||||
* @param iamRoleName iam role name to get temporary credentials through
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetCredentials(const StringView &iamRoleName, OnCredentialsAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the iam profile information of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetIamProfile(OnIamProfileAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the user data of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetUserData(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the signature of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetInstanceSignature(OnResourceAcquired callback, void *userData);
|
||||
|
||||
/**
|
||||
* Gets the instance information data block of the ec2 instance from the instance metadata document
|
||||
*
|
||||
* @param callback callback function to invoke on query success or failure
|
||||
* @param userData opaque data to invoke the completion callback with
|
||||
* @return AWS_OP_SUCCESS if the query was successfully started, AWS_OP_ERR otherwise
|
||||
*/
|
||||
int GetInstanceInfo(OnInstanceInfoAcquired callback, void *userData);
|
||||
|
||||
private:
|
||||
static void s_onResourceAcquired(const aws_byte_buf *resource, int erroCode, void *userData);
|
||||
|
||||
static void s_onVectorResourceAcquired(const aws_array_list *array, int errorCode, void *userData);
|
||||
|
||||
static void s_onCredentialsAcquired(const aws_credentials *credentials, int errorCode, void *userData);
|
||||
|
||||
static void s_onIamProfileAcquired(
|
||||
const aws_imds_iam_profile *iamProfileInfo,
|
||||
int errorCode,
|
||||
void *userData);
|
||||
|
||||
static void s_onInstanceInfoAcquired(
|
||||
const aws_imds_instance_info *instanceInfo,
|
||||
int error_code,
|
||||
void *userData);
|
||||
|
||||
aws_imds_client *m_client;
|
||||
Allocator *m_allocator;
|
||||
};
|
||||
|
||||
} // namespace Imds
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,453 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/StlAllocator.h>
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
struct aws_json_value;
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
|
||||
class JsonView;
|
||||
/**
|
||||
* JSON DOM manipulation class.
|
||||
* To read or serialize use @ref View function.
|
||||
*/
|
||||
class AWS_CRT_CPP_API JsonObject
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructs empty JSON DOM.
|
||||
*/
|
||||
JsonObject();
|
||||
|
||||
/**
|
||||
* Constructs a JSON DOM by parsing the input string.
|
||||
* Call WasParseSuccessful() on new object to determine if parse was successful.
|
||||
*/
|
||||
JsonObject(const String &stringToParse);
|
||||
|
||||
/**
|
||||
* Construct a deep copy.
|
||||
* Prefer using a @ref JsonView if copying is not needed.
|
||||
*/
|
||||
JsonObject(const JsonObject &other);
|
||||
|
||||
/**
|
||||
* Move constructor.
|
||||
* No copying is performed.
|
||||
*/
|
||||
JsonObject(JsonObject &&other) noexcept;
|
||||
|
||||
~JsonObject();
|
||||
|
||||
/**
|
||||
* Performs a deep copy.
|
||||
*/
|
||||
JsonObject &operator=(const JsonObject &other);
|
||||
|
||||
/**
|
||||
* Moves the ownership of the internal JSON DOM of the parameter to the current object.
|
||||
* No copying is performed.
|
||||
* A DOM currently owned by the object will be freed prior to copying.
|
||||
* @warning This will result in invalidating any outstanding views of the current DOM. However, views
|
||||
* to the moved-from DOM would still valid.
|
||||
*/
|
||||
JsonObject &operator=(JsonObject &&other) noexcept;
|
||||
|
||||
bool operator==(const JsonObject &other) const;
|
||||
bool operator!=(const JsonObject &other) const;
|
||||
|
||||
/**
|
||||
* Adds a string to the top level of this node with key.
|
||||
*/
|
||||
JsonObject &WithString(const String &key, const String &value);
|
||||
JsonObject &WithString(const char *key, const String &value);
|
||||
|
||||
/**
|
||||
* Converts the current JSON node to a string.
|
||||
*/
|
||||
JsonObject &AsString(const String &value);
|
||||
|
||||
/**
|
||||
* Adds a bool value with key to the top level of this node.
|
||||
*/
|
||||
JsonObject &WithBool(const String &key, bool value);
|
||||
JsonObject &WithBool(const char *key, bool value);
|
||||
|
||||
/**
|
||||
* Converts the current JSON node to a bool.
|
||||
*/
|
||||
JsonObject &AsBool(bool value);
|
||||
|
||||
/**
|
||||
* Adds a number value at key at the top level of this node.
|
||||
* Precision may be lost.
|
||||
*/
|
||||
JsonObject &WithInteger(const String &key, int value);
|
||||
JsonObject &WithInteger(const char *key, int value);
|
||||
|
||||
/**
|
||||
* Converts the current JSON node to a number.
|
||||
* Precision may be lost.
|
||||
*/
|
||||
JsonObject &AsInteger(int value);
|
||||
|
||||
/**
|
||||
* Adds a number value at key to the top level of this node.
|
||||
* Precision may be lost.
|
||||
*/
|
||||
JsonObject &WithInt64(const String &key, int64_t value);
|
||||
JsonObject &WithInt64(const char *key, int64_t value);
|
||||
|
||||
/**
|
||||
* Converts the current JSON node to a number.
|
||||
* Precision may be lost.
|
||||
*/
|
||||
JsonObject &AsInt64(int64_t value);
|
||||
|
||||
/**
|
||||
* Adds a number value at key at the top level of this node.
|
||||
*/
|
||||
JsonObject &WithDouble(const String &key, double value);
|
||||
JsonObject &WithDouble(const char *key, double value);
|
||||
|
||||
/**
|
||||
* Converts the current JSON node to a number.
|
||||
*/
|
||||
JsonObject &AsDouble(double value);
|
||||
|
||||
/**
|
||||
* Adds an array of strings to the top level of this node at key.
|
||||
*/
|
||||
JsonObject &WithArray(const String &key, const Vector<String> &array);
|
||||
JsonObject &WithArray(const char *key, const Vector<String> &array);
|
||||
|
||||
/**
|
||||
* Adds an array of arbitrary JSON objects to the top level of this node at key.
|
||||
* The values in the array parameter will be deep-copied.
|
||||
*/
|
||||
JsonObject &WithArray(const String &key, const Vector<JsonObject> &array);
|
||||
|
||||
/**
|
||||
* Adds an array of arbitrary JSON objects to the top level of this node at key.
|
||||
* The values in the array parameter will be moved-from.
|
||||
*/
|
||||
JsonObject &WithArray(const String &key, Vector<JsonObject> &&array);
|
||||
|
||||
/**
|
||||
* Converts the current JSON node to an array whose values are deep-copied from the array parameter.
|
||||
*/
|
||||
JsonObject &AsArray(const Vector<JsonObject> &array);
|
||||
|
||||
/**
|
||||
* Converts the current JSON node to an array whose values are moved from the array parameter.
|
||||
*/
|
||||
JsonObject &AsArray(Vector<JsonObject> &&array);
|
||||
|
||||
/**
|
||||
* Sets the current JSON node as null.
|
||||
*/
|
||||
JsonObject &AsNull();
|
||||
|
||||
/**
|
||||
* Adds a JSON object to the top level of this node at key.
|
||||
* The object parameter is deep-copied.
|
||||
*/
|
||||
JsonObject &WithObject(const String &key, const JsonObject &value);
|
||||
JsonObject &WithObject(const char *key, const JsonObject &value);
|
||||
|
||||
/**
|
||||
* Adds a JSON object to the top level of this node at key.
|
||||
*/
|
||||
JsonObject &WithObject(const String &key, JsonObject &&value);
|
||||
JsonObject &WithObject(const char *key, JsonObject &&value);
|
||||
|
||||
/**
|
||||
* Converts the current JSON node to a JSON object by deep-copying the parameter.
|
||||
*/
|
||||
JsonObject &AsObject(const JsonObject &value);
|
||||
|
||||
/**
|
||||
* Converts the current JSON node to a JSON object by moving from the parameter.
|
||||
*/
|
||||
JsonObject &AsObject(JsonObject &&value);
|
||||
|
||||
/**
|
||||
* Returns true if the last parse request was successful.
|
||||
*/
|
||||
inline bool WasParseSuccessful() const { return m_value != nullptr; }
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
const String &GetErrorMessage() const;
|
||||
|
||||
/**
|
||||
* Creates a view of this JSON node.
|
||||
*/
|
||||
JsonView View() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Construct a duplicate of this JSON value.
|
||||
*/
|
||||
JsonObject(const aws_json_value *valueToCopy);
|
||||
|
||||
/**
|
||||
* Helper for all AsXYZ() functions.
|
||||
* Destroys any pre-existing value and takes ownership of new value.
|
||||
*/
|
||||
JsonObject &AsNewValue(aws_json_value *valueToOwn);
|
||||
|
||||
/**
|
||||
* Helper for all WithXZY() functions.
|
||||
* Take ownership of new value and add at key, replacing any previous value.
|
||||
* Converts this node to JSON object if necessary.
|
||||
*/
|
||||
JsonObject &WithNewKeyValue(const char *key, aws_json_value *valueToOwn);
|
||||
|
||||
/**
|
||||
* Return new aws_json_value, an array containing duplicates of everything in objectsToCopy.
|
||||
*/
|
||||
static aws_json_value *NewArray(const Vector<JsonObject> &objectsToCopy);
|
||||
|
||||
/**
|
||||
* Return new aws_json_value, an array which has taken ownership of everything in objectsToMove
|
||||
*/
|
||||
static aws_json_value *NewArray(Vector<JsonObject> &&objectsToMove);
|
||||
|
||||
aws_json_value *m_value;
|
||||
|
||||
/* Once upon a time each class instance had an m_errorMessage string member,
|
||||
* and if parse failed the string would explain why.
|
||||
* When we switched json implementations, there was no longer a unique string
|
||||
* explaining why parse failed so we dropped that member from the class.
|
||||
* To avoid breaking the GetErrorMessage() API, which returns the string by REFERENCE,
|
||||
* we now use singletons that are created/destroyed along with library init/cleanup. */
|
||||
static std::unique_ptr<String> s_errorMessage;
|
||||
static std::unique_ptr<String> s_okMessage;
|
||||
static void OnLibraryInit();
|
||||
static void OnLibraryCleanup();
|
||||
|
||||
friend class JsonView;
|
||||
friend class ApiHandle;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides read-only view to an existing JsonObject. This allows lightweight copying without making deep
|
||||
* copies of the JsonObject.
|
||||
* Note: This class does not extend the lifetime of the given JsonObject. It's your responsibility to ensure
|
||||
* the lifetime of the JsonObject is extended beyond the lifetime of its view.
|
||||
*/
|
||||
class AWS_CRT_CPP_API JsonView
|
||||
{
|
||||
public:
|
||||
/* constructors */
|
||||
JsonView();
|
||||
JsonView(const JsonObject &val);
|
||||
JsonView &operator=(const JsonObject &val);
|
||||
|
||||
/**
|
||||
* Gets a string from this node by its key.
|
||||
*/
|
||||
String GetString(const String &key) const;
|
||||
/**
|
||||
* Gets a string from this node by its key.
|
||||
*/
|
||||
String GetString(const char *key) const;
|
||||
|
||||
/**
|
||||
* Returns the value of this node as a string.
|
||||
* The behavior is undefined if the node is _not_ of type string.
|
||||
*/
|
||||
String AsString() const;
|
||||
|
||||
/**
|
||||
* Gets a boolean value from this node by its key.
|
||||
*/
|
||||
bool GetBool(const String &key) const;
|
||||
/**
|
||||
* Gets a boolean value from this node by its key.
|
||||
*/
|
||||
bool GetBool(const char *key) const;
|
||||
|
||||
/**
|
||||
* Returns the value of this node as a boolean.
|
||||
*/
|
||||
bool AsBool() const;
|
||||
|
||||
/**
|
||||
* Gets an integer value from this node by its key.
|
||||
* The integer is of the same size as an int on the machine.
|
||||
*/
|
||||
int GetInteger(const String &key) const;
|
||||
/**
|
||||
* Gets an integer value from this node by its key.
|
||||
* The integer is of the same size as an int on the machine.
|
||||
*/
|
||||
int GetInteger(const char *key) const;
|
||||
|
||||
/**
|
||||
* Returns the value of this node as an int.
|
||||
*/
|
||||
int AsInteger() const;
|
||||
|
||||
/**
|
||||
* Gets a 64-bit integer value from this node by its key.
|
||||
* The value is 64-bit regardless of the platform/machine.
|
||||
*/
|
||||
int64_t GetInt64(const String &key) const;
|
||||
/**
|
||||
* Gets a 64-bit integer value from this node by its key.
|
||||
* The value is 64-bit regardless of the platform/machine.
|
||||
*/
|
||||
int64_t GetInt64(const char *key) const;
|
||||
|
||||
/**
|
||||
* Returns the value of this node as 64-bit integer.
|
||||
*/
|
||||
int64_t AsInt64() const;
|
||||
|
||||
/**
|
||||
* Gets a double precision floating-point value from this node by its key.
|
||||
*/
|
||||
double GetDouble(const String &key) const;
|
||||
/**
|
||||
* Gets a double precision floating-point value from this node by its key.
|
||||
*/
|
||||
double GetDouble(const char *key) const;
|
||||
|
||||
/**
|
||||
* Returns the value of this node as a double precision floating-point.
|
||||
*/
|
||||
double AsDouble() const;
|
||||
|
||||
/**
|
||||
* Gets an array of JsonView objects from this node by its key.
|
||||
*/
|
||||
Vector<JsonView> GetArray(const String &key) const;
|
||||
/**
|
||||
* Gets an array of JsonView objects from this node by its key.
|
||||
*/
|
||||
Vector<JsonView> GetArray(const char *key) const;
|
||||
|
||||
/**
|
||||
* Returns the value of this node as an array of JsonView objects.
|
||||
*/
|
||||
Vector<JsonView> AsArray() const;
|
||||
|
||||
/**
|
||||
* Gets a JsonView object from this node by its key.
|
||||
*/
|
||||
JsonView GetJsonObject(const String &key) const;
|
||||
/**
|
||||
* Gets a JsonView object from this node by its key.
|
||||
*/
|
||||
JsonView GetJsonObject(const char *key) const;
|
||||
|
||||
JsonObject GetJsonObjectCopy(const String &key) const;
|
||||
|
||||
JsonObject GetJsonObjectCopy(const char *key) const;
|
||||
|
||||
/**
|
||||
* Returns the value of this node as a JsonView object.
|
||||
*/
|
||||
JsonView AsObject() const;
|
||||
|
||||
/**
|
||||
* Reads all json objects at the top level of this node (does not traverse the tree any further)
|
||||
* along with their keys.
|
||||
*/
|
||||
Map<String, JsonView> GetAllObjects() const;
|
||||
|
||||
/**
|
||||
* Tests whether a value exists at the current node level for the given key.
|
||||
* Returns true if a value has been found and its value is not null, false otherwise.
|
||||
*/
|
||||
bool ValueExists(const String &key) const;
|
||||
/**
|
||||
* Tests whether a value exists at the current node level for the given key.
|
||||
* Returns true if a value has been found and its value is not null, false otherwise.
|
||||
*/
|
||||
bool ValueExists(const char *key) const;
|
||||
|
||||
/**
|
||||
* Tests whether a key exists at the current node level.
|
||||
*/
|
||||
bool KeyExists(const String &key) const;
|
||||
/**
|
||||
* Tests whether a key exists at the current node level.
|
||||
*/
|
||||
bool KeyExists(const char *key) const;
|
||||
|
||||
/**
|
||||
* Tests whether the current value is a JSON object.
|
||||
*/
|
||||
bool IsObject() const;
|
||||
|
||||
/**
|
||||
* Tests whether the current value is a boolean.
|
||||
*/
|
||||
bool IsBool() const;
|
||||
|
||||
/**
|
||||
* Tests whether the current value is a string.
|
||||
*/
|
||||
bool IsString() const;
|
||||
|
||||
/**
|
||||
* Tests whether the current value is a number.
|
||||
*/
|
||||
bool IsNumber() const;
|
||||
|
||||
/**
|
||||
* Tests whether the current value is a number that can convert to an int64_t without losing precision.
|
||||
*/
|
||||
bool IsIntegerType() const;
|
||||
|
||||
/**
|
||||
* Tests whether the current value is a number that will lose precision if converted to an int64_t.
|
||||
*/
|
||||
bool IsFloatingPointType() const;
|
||||
|
||||
/**
|
||||
* Tests whether the current value is a JSON array.
|
||||
*/
|
||||
bool IsListType() const;
|
||||
|
||||
/**
|
||||
* Tests whether the current value is a JSON null.
|
||||
*/
|
||||
bool IsNull() const;
|
||||
|
||||
/**
|
||||
* Writes the current JSON view without whitespace characters starting at the current level to a string.
|
||||
* @param treatAsObject if the current value is empty, writes out '{}' rather than an empty string.
|
||||
*/
|
||||
String WriteCompact(bool treatAsObject = true) const;
|
||||
|
||||
/**
|
||||
* Writes the current JSON view to a string in a human friendly format.
|
||||
* @param treatAsObject if the current value is empty, writes out '{}' rather than an empty string.
|
||||
*/
|
||||
String WriteReadable(bool treatAsObject = true) const;
|
||||
|
||||
/**
|
||||
* Creates a deep copy of the JSON value rooted in the current JSON view.
|
||||
*/
|
||||
JsonObject Materialize() const;
|
||||
|
||||
private:
|
||||
JsonView(const aws_json_value *val);
|
||||
|
||||
String Write(bool treatAsObject, bool readable) const;
|
||||
|
||||
const aws_json_value *m_value;
|
||||
};
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
220
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/Optional.h
Normal file
220
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/Optional.h
Normal file
@@ -0,0 +1,220 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/Utility.h>
|
||||
#include <utility>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
/**
|
||||
* Custom implementation of an Option type. std::optional requires C++17
|
||||
* @tparam T type of the optional value
|
||||
*/
|
||||
template <typename T> class Optional
|
||||
{
|
||||
public:
|
||||
Optional() : m_value(nullptr) {}
|
||||
Optional(const T &val)
|
||||
{
|
||||
new (m_storage) T(val);
|
||||
m_value = reinterpret_cast<T *>(m_storage);
|
||||
}
|
||||
|
||||
Optional(T &&val)
|
||||
{
|
||||
new (m_storage) T(std::forward<T>(val));
|
||||
m_value = reinterpret_cast<T *>(m_storage);
|
||||
}
|
||||
|
||||
~Optional()
|
||||
{
|
||||
if (m_value)
|
||||
{
|
||||
m_value->~T();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U = T> Optional &operator=(U &&u)
|
||||
{
|
||||
if (m_value)
|
||||
{
|
||||
*m_value = std::forward<U>(u);
|
||||
return *this;
|
||||
}
|
||||
|
||||
new (m_storage) T(std::forward<U>(u));
|
||||
m_value = reinterpret_cast<T *>(m_storage);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Optional(const Optional<T> &other)
|
||||
{
|
||||
if (other.m_value)
|
||||
{
|
||||
new (m_storage) T(*other.m_value);
|
||||
m_value = reinterpret_cast<T *>(m_storage);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_value = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Optional(Optional<T> &&other)
|
||||
{
|
||||
if (other.m_value)
|
||||
{
|
||||
new (m_storage) T(std::forward<T>(*other.m_value));
|
||||
m_value = reinterpret_cast<T *>(m_storage);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_value = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args> explicit Optional(Aws::Crt::InPlaceT, Args &&...args)
|
||||
{
|
||||
new (m_storage) T(std::forward<Args>(args)...);
|
||||
m_value = reinterpret_cast<T *>(m_storage);
|
||||
}
|
||||
|
||||
Optional &operator=(const Optional &other)
|
||||
{
|
||||
if (this == &other)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (m_value)
|
||||
{
|
||||
if (other.m_value)
|
||||
{
|
||||
*m_value = *other.m_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_value->~T();
|
||||
m_value = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (other.m_value)
|
||||
{
|
||||
new (m_storage) T(*other.m_value);
|
||||
m_value = reinterpret_cast<T *>(m_storage);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U = T> Optional<T> &operator=(const Optional<U> &other)
|
||||
{
|
||||
if (this == &other)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (m_value)
|
||||
{
|
||||
if (other.m_value)
|
||||
{
|
||||
*m_value = *other.m_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_value->~T();
|
||||
m_value = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (other.m_value)
|
||||
{
|
||||
new (m_storage) T(*other.m_value);
|
||||
m_value = reinterpret_cast<T *>(m_storage);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U = T> Optional<T> &operator=(Optional<U> &&other)
|
||||
{
|
||||
if (this == &other)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (m_value)
|
||||
{
|
||||
if (other.m_value)
|
||||
{
|
||||
*m_value = std::forward<U>(*other.m_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_value->~T();
|
||||
m_value = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (other.m_value)
|
||||
{
|
||||
new (m_storage) T(std::forward<U>(*other.m_value));
|
||||
m_value = reinterpret_cast<T *>(m_storage);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename... Args> T &emplace(Args &&...args)
|
||||
{
|
||||
reset();
|
||||
|
||||
new (m_storage) T(std::forward<Args>(args)...);
|
||||
m_value = reinterpret_cast<T *>(m_storage);
|
||||
|
||||
return *m_value;
|
||||
}
|
||||
|
||||
const T *operator->() const { return m_value; }
|
||||
T *operator->() { return m_value; }
|
||||
const T &operator*() const & { return *m_value; }
|
||||
T &operator*() & { return *m_value; }
|
||||
const T &&operator*() const && { return std::move(*m_value); }
|
||||
T &&operator*() && { return std::move(*m_value); }
|
||||
|
||||
explicit operator bool() const noexcept { return m_value != nullptr; }
|
||||
bool has_value() const noexcept { return m_value != nullptr; }
|
||||
|
||||
T &value() & { return *m_value; }
|
||||
const T &value() const & { return *m_value; }
|
||||
|
||||
T &&value() && { return std::move(*m_value); }
|
||||
const T &&value() const && { return std::move(*m_value); }
|
||||
|
||||
void reset()
|
||||
{
|
||||
if (m_value)
|
||||
{
|
||||
m_value->~T();
|
||||
m_value = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
alignas(T) char m_storage[sizeof(T)];
|
||||
T *m_value;
|
||||
};
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/common/assert.h>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
/**
|
||||
* Inherit from RefCounted to allow reference-counting from C code,
|
||||
* which will keep your C++ object alive as long as the count is non-zero.
|
||||
*
|
||||
* A class must inherit from RefCounted and std::enable_shared_from_this.
|
||||
* Your class must always be placed inside a shared_ptr (do not create on
|
||||
* the stack, or keep on the heap as a raw pointer).
|
||||
*
|
||||
* Whenever the reference count goes from 0 to 1 a shared_ptr is created
|
||||
* internally to keep this object alive. Whenever the reference count
|
||||
* goes from 1 to 0 the internal shared_ptr is reset, allowing this object
|
||||
* to be destroyed.
|
||||
*/
|
||||
template <class T> class RefCounted
|
||||
{
|
||||
protected:
|
||||
RefCounted() {}
|
||||
~RefCounted() {}
|
||||
|
||||
void AcquireRef()
|
||||
{
|
||||
m_mutex.lock();
|
||||
if (m_count++ == 0)
|
||||
{
|
||||
m_strongPtr = static_cast<T *>(this)->shared_from_this();
|
||||
}
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
void ReleaseRef()
|
||||
{
|
||||
// Move contents of m_strongPtr to a temp so that this
|
||||
// object can't be destroyed until the function exits.
|
||||
std::shared_ptr<T> tmpStrongPtr;
|
||||
|
||||
m_mutex.lock();
|
||||
AWS_ASSERT(m_count > 0 && "refcount has gone negative");
|
||||
if (m_count-- == 1)
|
||||
{
|
||||
std::swap(m_strongPtr, tmpStrongPtr);
|
||||
}
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
RefCounted(const RefCounted &) = delete;
|
||||
RefCounted &operator=(const RefCounted &) = delete;
|
||||
|
||||
size_t m_count = 0;
|
||||
std::shared_ptr<T> m_strongPtr;
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Allocator.h>
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
/**
|
||||
* Stateful allocator variant that uses an underlying CRT allocator
|
||||
* @tparam T type that allocator can allocate
|
||||
*/
|
||||
template <typename T> class StlAllocator : public std::allocator<T>
|
||||
{
|
||||
public:
|
||||
using Base = std::allocator<T>;
|
||||
|
||||
StlAllocator() noexcept : Base() { m_allocator = ApiAllocator(); }
|
||||
|
||||
StlAllocator(Allocator *allocator) noexcept : Base() { m_allocator = allocator; }
|
||||
|
||||
StlAllocator(const StlAllocator<T> &a) noexcept : Base(a) { m_allocator = a.m_allocator; }
|
||||
|
||||
template <class U> StlAllocator(const StlAllocator<U> &a) noexcept : Base(a)
|
||||
{
|
||||
m_allocator = a.m_allocator;
|
||||
}
|
||||
|
||||
~StlAllocator() {}
|
||||
|
||||
using size_type = std::size_t;
|
||||
|
||||
template <typename U> struct rebind
|
||||
{
|
||||
typedef StlAllocator<U> other;
|
||||
};
|
||||
|
||||
using RawPointer = typename std::allocator_traits<std::allocator<T>>::pointer;
|
||||
|
||||
RawPointer allocate(size_type n, const void *hint = nullptr)
|
||||
{
|
||||
(void)hint;
|
||||
AWS_ASSERT(m_allocator);
|
||||
return static_cast<RawPointer>(aws_mem_acquire(m_allocator, n * sizeof(T)));
|
||||
}
|
||||
|
||||
void deallocate(RawPointer p, size_type)
|
||||
{
|
||||
AWS_ASSERT(m_allocator);
|
||||
aws_mem_release(m_allocator, p);
|
||||
}
|
||||
|
||||
Allocator *m_allocator;
|
||||
};
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/Exports.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
/**
|
||||
* C-string hash function
|
||||
* @param str string to hash
|
||||
* @return hash code of the string
|
||||
*/
|
||||
size_t AWS_CRT_CPP_API HashString(const char *str) noexcept;
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,865 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
/**
|
||||
* To keep ABI compatability, we use CRT's own string view implementation even for C++ 17.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
|
||||
# include <string_view>
|
||||
#endif
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
/**
|
||||
* Custom string view implementation in order to meet C++11 baseline
|
||||
* @tparam CharT
|
||||
* @tparam Traits
|
||||
*/
|
||||
template <typename CharT, typename Traits = std::char_traits<CharT>> class basic_string_view
|
||||
{
|
||||
public:
|
||||
// types
|
||||
using traits_type = Traits;
|
||||
using value_type = CharT;
|
||||
using pointer = value_type *;
|
||||
using const_pointer = const value_type *;
|
||||
using reference = value_type &;
|
||||
using const_reference = const value_type &;
|
||||
using const_iterator = const value_type *;
|
||||
using iterator = const_iterator;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
using reverse_iterator = const_reverse_iterator;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
static constexpr size_type npos = static_cast<size_type>(-1);
|
||||
|
||||
// constructors and assignment
|
||||
|
||||
constexpr basic_string_view() noexcept : m_size{0}, m_data{nullptr} {}
|
||||
|
||||
constexpr basic_string_view(const basic_string_view &) noexcept = default;
|
||||
|
||||
constexpr basic_string_view(const CharT *s) noexcept : m_size{traits_type::length(s)}, m_data{s} {}
|
||||
|
||||
constexpr basic_string_view(const CharT *s, size_type count) noexcept : m_size{count}, m_data{s} {}
|
||||
|
||||
basic_string_view &operator=(const basic_string_view &) noexcept = default;
|
||||
|
||||
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
|
||||
constexpr basic_string_view(const std::basic_string_view<CharT, Traits> &other) noexcept
|
||||
: m_size(other.size()), m_data(other.data())
|
||||
{
|
||||
}
|
||||
|
||||
basic_string_view &operator=(const std::basic_string_view<CharT, Traits> &other) noexcept
|
||||
{
|
||||
m_data = other->data();
|
||||
m_size = other->size();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
// iterators
|
||||
|
||||
constexpr const_iterator begin() const noexcept { return this->m_data; }
|
||||
|
||||
constexpr const_iterator end() const noexcept { return this->m_data + this->m_size; }
|
||||
|
||||
constexpr const_iterator cbegin() const noexcept { return this->m_data; }
|
||||
|
||||
constexpr const_iterator cend() const noexcept { return this->m_data + this->m_size; }
|
||||
|
||||
constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(this->end()); }
|
||||
|
||||
constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(this->begin()); }
|
||||
|
||||
constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(this->end()); }
|
||||
|
||||
constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(this->begin()); }
|
||||
|
||||
constexpr size_type size() const noexcept { return this->m_size; }
|
||||
|
||||
constexpr size_type length() const noexcept { return this->m_size; }
|
||||
|
||||
constexpr size_type max_size() const noexcept { return (std::numeric_limits<size_type>::max)(); }
|
||||
|
||||
constexpr bool empty() const noexcept { return this->m_size == 0; }
|
||||
|
||||
// element accessors
|
||||
|
||||
const_reference operator[](size_type pos) const noexcept
|
||||
{
|
||||
assert(pos < m_size);
|
||||
return *(this->m_data + pos);
|
||||
}
|
||||
|
||||
const_reference at(size_type pos) const
|
||||
{
|
||||
assert(pos < m_size);
|
||||
return *(this->m_data + pos);
|
||||
}
|
||||
|
||||
const_reference front() const noexcept
|
||||
{
|
||||
assert(m_size > 0);
|
||||
return *this->m_data;
|
||||
}
|
||||
|
||||
const_reference back() const noexcept
|
||||
{
|
||||
assert(m_size > 0);
|
||||
return *(this->m_data + this->m_size - 1);
|
||||
}
|
||||
|
||||
constexpr const_pointer data() const noexcept { return this->m_data; }
|
||||
|
||||
// modifiers
|
||||
void remove_prefix(size_type n) noexcept
|
||||
{
|
||||
assert(this->m_size >= n);
|
||||
this->m_data += n;
|
||||
this->m_size -= n;
|
||||
}
|
||||
|
||||
void remove_suffix(size_type n) noexcept { this->m_size -= n; }
|
||||
|
||||
void swap(basic_string_view &other) noexcept
|
||||
{
|
||||
auto tmp = *this;
|
||||
*this = other;
|
||||
other = tmp;
|
||||
}
|
||||
|
||||
// string operations
|
||||
size_type copy(CharT *s, size_type n, size_type pos = 0) const
|
||||
{
|
||||
assert(pos <= size());
|
||||
const size_type copyLen = (std::min)(n, m_size - pos);
|
||||
traits_type::copy(s, data() + pos, copyLen);
|
||||
return copyLen;
|
||||
}
|
||||
|
||||
basic_string_view substr(size_type pos = 0, size_type n = npos) const noexcept(false)
|
||||
{
|
||||
assert(pos <= size());
|
||||
const size_type copyLen = (std::min)(n, m_size - pos);
|
||||
return basic_string_view{m_data + pos, copyLen};
|
||||
}
|
||||
|
||||
int compare(const basic_string_view &s) const noexcept
|
||||
{
|
||||
const size_type compareLen = (std::min)(this->m_size, s.m_size);
|
||||
int ret = traits_type::compare(this->m_data, s.m_data, compareLen);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = _s_compare(this->m_size, s.m_size);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
constexpr int compare(size_type pos1, size_type n1, const basic_string_view &s) const
|
||||
{
|
||||
return this->substr(pos1, n1).compare(s);
|
||||
}
|
||||
|
||||
constexpr int compare(
|
||||
size_type pos1,
|
||||
size_type n1,
|
||||
const basic_string_view &s,
|
||||
size_type pos2,
|
||||
size_type n2) const
|
||||
{
|
||||
return this->substr(pos1, n1).compare(s.substr(pos2, n2));
|
||||
}
|
||||
|
||||
constexpr int compare(const CharT *s) const noexcept { return this->compare(basic_string_view{s}); }
|
||||
|
||||
constexpr int compare(size_type pos1, size_type n1, const CharT *s) const
|
||||
{
|
||||
return this->substr(pos1, n1).compare(basic_string_view{s});
|
||||
}
|
||||
|
||||
constexpr int compare(size_type pos1, size_type n1, const CharT *s, size_type n2) const noexcept(false)
|
||||
{
|
||||
return this->substr(pos1, n1).compare(basic_string_view(s, n2));
|
||||
}
|
||||
|
||||
constexpr bool starts_with(const basic_string_view &other) const noexcept
|
||||
{
|
||||
return this->substr(0, other.size()) == other;
|
||||
}
|
||||
|
||||
constexpr bool starts_with(CharT c) const noexcept
|
||||
{
|
||||
return !this->empty() && traits_type::eq(this->front(), c);
|
||||
}
|
||||
|
||||
constexpr bool starts_with(const CharT *s) const noexcept
|
||||
{
|
||||
return this->starts_with(basic_string_view(s));
|
||||
}
|
||||
|
||||
constexpr bool ends_with(const basic_string_view &other) const noexcept
|
||||
{
|
||||
return this->m_size >= other.m_size && this->compare(this->m_size - other.m_size, npos, other) == 0;
|
||||
}
|
||||
|
||||
constexpr bool ends_with(CharT c) const noexcept
|
||||
{
|
||||
return !this->empty() && traits_type::eq(this->back(), c);
|
||||
}
|
||||
|
||||
constexpr bool ends_with(const CharT *s) const noexcept { return this->ends_with(basic_string_view(s)); }
|
||||
|
||||
// find utilities
|
||||
constexpr size_type find(const basic_string_view &s, size_type pos = 0) const noexcept
|
||||
{
|
||||
return this->find(s.m_data, pos, s.m_size);
|
||||
}
|
||||
|
||||
size_type find(CharT c, size_type pos = 0) const noexcept
|
||||
{
|
||||
if (pos >= m_size)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
const CharT *r = Traits::find(m_data + pos, m_size - pos, c);
|
||||
if (r == nullptr)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
return static_cast<size_type>(r - m_data);
|
||||
}
|
||||
|
||||
size_type find(const CharT *s, size_type pos, size_type n) const noexcept
|
||||
{
|
||||
if (n && !s)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
if (pos > m_size)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
const CharT *r = _s_search_substr(m_data + pos, m_data + m_size, s, s + n);
|
||||
|
||||
if (r == m_data + m_size)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
return static_cast<size_type>(r - m_data);
|
||||
}
|
||||
|
||||
constexpr size_type find(const CharT *s, size_type pos = 0) const noexcept
|
||||
{
|
||||
return this->find(s, pos, traits_type::length(s));
|
||||
}
|
||||
|
||||
size_type rfind(basic_string_view s, size_type pos = npos) const noexcept
|
||||
{
|
||||
if (s.m_size && !s.m_data)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
return this->rfind(s.m_data, pos, s.m_size);
|
||||
}
|
||||
|
||||
size_type rfind(CharT c, size_type pos = npos) const noexcept
|
||||
{
|
||||
if (m_size <= 0)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
if (pos < m_size)
|
||||
{
|
||||
++pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = m_size;
|
||||
}
|
||||
|
||||
for (const CharT *ptr = m_data + pos; ptr != m_data;)
|
||||
{
|
||||
if (Traits::eq(*--ptr, c))
|
||||
{
|
||||
return static_cast<size_type>(ptr - m_data);
|
||||
}
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
size_type rfind(const CharT *s, size_type pos, size_type n) const noexcept
|
||||
{
|
||||
if (n && !s)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
pos = (std::min)(pos, m_size);
|
||||
if (n < m_size - pos)
|
||||
{
|
||||
pos += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = m_size;
|
||||
}
|
||||
const CharT *r = _s_find_end(m_data, m_data + pos, s, s + n);
|
||||
if (n > 0 && r == m_data + pos)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
return static_cast<size_type>(r - m_data);
|
||||
}
|
||||
|
||||
constexpr size_type rfind(const CharT *s, size_type pos = npos) const noexcept
|
||||
{
|
||||
return this->rfind(s, pos, traits_type::length(s));
|
||||
}
|
||||
|
||||
constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept
|
||||
{
|
||||
return this->find_first_of(s.m_data, pos, s.m_size);
|
||||
}
|
||||
|
||||
constexpr size_type find_first_of(CharT c, size_type pos = 0) const noexcept { return this->find(c, pos); }
|
||||
|
||||
size_type find_first_of(const CharT *s, size_type pos, size_type n) const noexcept
|
||||
{
|
||||
if (pos >= m_size || !n || !s)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
const CharT *r = _s_find_first_of_ce(m_data + pos, m_data + m_size, s, s + n);
|
||||
|
||||
if (r == m_data + m_size)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
return static_cast<size_type>(r - m_data);
|
||||
}
|
||||
|
||||
constexpr size_type find_first_of(const CharT *s, size_type pos = 0) const noexcept
|
||||
{
|
||||
return this->find_first_of(s, pos, traits_type::length(s));
|
||||
}
|
||||
|
||||
constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept
|
||||
{
|
||||
return this->find_last_of(s.m_data, pos, s.m_size);
|
||||
}
|
||||
|
||||
constexpr size_type find_last_of(CharT c, size_type pos = npos) const noexcept
|
||||
{
|
||||
return this->rfind(c, pos);
|
||||
}
|
||||
|
||||
size_type find_last_of(const CharT *s, size_type pos, size_type n) const noexcept
|
||||
{
|
||||
if (!n || s == nullptr)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
if (pos < m_size)
|
||||
{
|
||||
++pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = m_size;
|
||||
}
|
||||
|
||||
for (const CharT *ptr = m_data + pos; ptr != m_data;)
|
||||
{
|
||||
const CharT *r = Traits::find(s, n, *--ptr);
|
||||
if (r)
|
||||
{
|
||||
return static_cast<size_type>(ptr - m_data);
|
||||
}
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
constexpr size_type find_last_of(const CharT *s, size_type pos = npos) const noexcept
|
||||
{
|
||||
return this->find_last_of(s, pos, traits_type::length(s));
|
||||
}
|
||||
|
||||
size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept
|
||||
{
|
||||
if (s.m_size && !s.m_data)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
return this->find_first_not_of(s.m_data, pos, s.m_size);
|
||||
}
|
||||
|
||||
size_type find_first_not_of(CharT c, size_type pos = 0) const noexcept
|
||||
{
|
||||
if (!m_data || pos >= m_size)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
const CharT *pend = m_data + m_size;
|
||||
for (const CharT *ptr = m_data + pos; ptr != pend; ++ptr)
|
||||
{
|
||||
if (!Traits::eq(*ptr, c))
|
||||
{
|
||||
return static_cast<size_type>(ptr - m_data);
|
||||
}
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
size_type find_first_not_of(const CharT *s, size_type pos, size_type n) const noexcept
|
||||
{
|
||||
if (n && s == nullptr)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
if (m_data == nullptr || pos >= m_size)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
const CharT *pend = m_data + m_size;
|
||||
for (const CharT *ptr = m_data + pos; ptr != pend; ++ptr)
|
||||
{
|
||||
if (Traits::find(s, n, *ptr) == 0)
|
||||
{
|
||||
return static_cast<size_type>(ptr - m_data);
|
||||
}
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
constexpr size_type find_first_not_of(const CharT *s, size_type pos = 0) const noexcept
|
||||
{
|
||||
return this->find_first_not_of(s, pos, traits_type::length(s));
|
||||
}
|
||||
|
||||
size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept
|
||||
{
|
||||
if (s.m_size && !s.m_data)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
return this->find_last_not_of(s.m_data, pos, s.m_size);
|
||||
}
|
||||
|
||||
size_type find_last_not_of(CharT c, size_type pos = npos) const noexcept
|
||||
{
|
||||
if (pos < m_size)
|
||||
{
|
||||
++pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = m_size;
|
||||
}
|
||||
|
||||
for (const CharT *ptr = m_data + pos; ptr != m_data;)
|
||||
{
|
||||
if (!Traits::eq(*--ptr, c))
|
||||
{
|
||||
return static_cast<size_type>(ptr - m_data);
|
||||
}
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
size_type find_last_not_of(const CharT *s, size_type pos, size_type n) const noexcept
|
||||
{
|
||||
if (n && !s)
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
|
||||
if (pos < m_size)
|
||||
{
|
||||
++pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = m_size;
|
||||
}
|
||||
|
||||
for (const CharT *ptr = m_data + pos; ptr != m_data;)
|
||||
{
|
||||
if (Traits::find(s, n, *--ptr) == 0)
|
||||
{
|
||||
return static_cast<size_type>(ptr - m_data);
|
||||
}
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
constexpr size_type find_last_not_of(const CharT *s, size_type pos = npos) const noexcept
|
||||
{
|
||||
return this->find_last_not_of(s, pos, traits_type::length(s));
|
||||
}
|
||||
|
||||
private:
|
||||
static int _s_compare(size_type n1, size_type n2) noexcept
|
||||
{
|
||||
const difference_type diff = n1 - n2;
|
||||
|
||||
if (diff > (std::numeric_limits<int>::max)())
|
||||
{
|
||||
return (std::numeric_limits<int>::max)();
|
||||
}
|
||||
|
||||
if (diff < (std::numeric_limits<int>::min)())
|
||||
{
|
||||
return (std::numeric_limits<int>::min)();
|
||||
}
|
||||
|
||||
return static_cast<int>(diff);
|
||||
}
|
||||
|
||||
static const CharT *_s_search_substr(
|
||||
const CharT *first1,
|
||||
const CharT *last1,
|
||||
const CharT *first2,
|
||||
const CharT *last2)
|
||||
{
|
||||
const ptrdiff_t length2 = last2 - first2;
|
||||
if (length2 == 0)
|
||||
{
|
||||
return first1;
|
||||
}
|
||||
|
||||
ptrdiff_t length1 = last1 - first1;
|
||||
if (length1 < length2)
|
||||
{
|
||||
return last1;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
length1 = last1 - first1;
|
||||
if (length1 < length2)
|
||||
{
|
||||
return last1;
|
||||
}
|
||||
|
||||
first1 = Traits::find(first1, length1 - length2 + 1, *first2);
|
||||
if (first1 == 0)
|
||||
{
|
||||
return last1;
|
||||
}
|
||||
|
||||
if (Traits::compare(first1, first2, length2) == 0)
|
||||
{
|
||||
return first1;
|
||||
}
|
||||
|
||||
++first1;
|
||||
}
|
||||
}
|
||||
|
||||
static const CharT *_s_find_end(
|
||||
const CharT *first1,
|
||||
const CharT *last1,
|
||||
const CharT *first2,
|
||||
const CharT *last2)
|
||||
{
|
||||
const CharT *r = last1;
|
||||
if (first2 == last2)
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (first1 == last1)
|
||||
{
|
||||
return r;
|
||||
}
|
||||
if (Traits::eq(*first1, *first2))
|
||||
{
|
||||
break;
|
||||
}
|
||||
++first1;
|
||||
}
|
||||
|
||||
const CharT *m1 = first1;
|
||||
const CharT *m2 = first2;
|
||||
while (true)
|
||||
{
|
||||
if (++m2 == last2)
|
||||
{
|
||||
r = first1;
|
||||
++first1;
|
||||
break;
|
||||
}
|
||||
if (++m1 == last1)
|
||||
{
|
||||
return r;
|
||||
}
|
||||
if (!Traits::eq(*m1, *m2))
|
||||
{
|
||||
++first1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const CharT *_s_find_first_of_ce(
|
||||
const CharT *first1,
|
||||
const CharT *last1,
|
||||
const CharT *first2,
|
||||
const CharT *last2)
|
||||
{
|
||||
for (; first1 != last1; ++first1)
|
||||
{
|
||||
for (const CharT *ptr = first2; ptr != last2; ++ptr)
|
||||
{
|
||||
if (Traits::eq(*first1, *ptr))
|
||||
{
|
||||
return first1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return last1;
|
||||
}
|
||||
|
||||
size_type m_size;
|
||||
const CharT *m_data;
|
||||
};
|
||||
|
||||
// operator ==
|
||||
template <class CharT, class Traits>
|
||||
bool operator==(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return (lhs.size() != rhs.size()) ? false : lhs.compare(rhs) == 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
bool operator==(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &rhs) noexcept
|
||||
{
|
||||
return (lhs.size() != rhs.size()) ? false : lhs.compare(rhs) == 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
bool operator==(
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return (lhs.size() != rhs.size()) ? false : lhs.compare(rhs) == 0;
|
||||
}
|
||||
|
||||
// operator !=
|
||||
template <class CharT, class Traits>
|
||||
bool operator!=(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return (lhs.size() != rhs.size()) ? true : lhs.compare(rhs) != 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
bool operator!=(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &rhs) noexcept
|
||||
{
|
||||
return (lhs.size() != rhs.size()) ? true : lhs.compare(rhs) != 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
bool operator!=(
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return (lhs.size() != rhs.size()) ? true : lhs.compare(rhs) != 0;
|
||||
}
|
||||
|
||||
// operator <
|
||||
template <class CharT, class Traits>
|
||||
bool operator<(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) < 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
constexpr bool operator<(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) < 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
constexpr bool operator<(
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) < 0;
|
||||
}
|
||||
|
||||
// operator >
|
||||
template <class CharT, class Traits>
|
||||
constexpr bool operator>(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) > 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
constexpr bool operator>(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) > 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
constexpr bool operator>(
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) > 0;
|
||||
}
|
||||
|
||||
// operator <=
|
||||
template <class CharT, class Traits>
|
||||
constexpr bool operator<=(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) <= 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
constexpr bool operator<=(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) <= 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
constexpr bool operator<=(
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) <= 0;
|
||||
}
|
||||
|
||||
// operator >=
|
||||
template <class CharT, class Traits>
|
||||
constexpr bool operator>=(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) >= 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
constexpr bool operator>=(
|
||||
const basic_string_view<CharT, Traits> &lhs,
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) >= 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits>
|
||||
constexpr bool operator>=(
|
||||
typename std::common_type<basic_string_view<CharT, Traits>>::type &lhs,
|
||||
const basic_string_view<CharT, Traits> &rhs) noexcept
|
||||
{
|
||||
return lhs.compare(rhs) >= 0;
|
||||
}
|
||||
|
||||
typedef basic_string_view<char> string_view;
|
||||
typedef basic_string_view<char16_t> u16string_view;
|
||||
typedef basic_string_view<char32_t> u32string_view;
|
||||
typedef basic_string_view<wchar_t> wstring_view;
|
||||
|
||||
inline namespace literals
|
||||
{
|
||||
inline namespace string_view_literals
|
||||
{
|
||||
inline basic_string_view<char> operator"" _sv(const char *s, size_t length) noexcept
|
||||
{
|
||||
return basic_string_view<char>(s, length);
|
||||
}
|
||||
|
||||
inline basic_string_view<wchar_t> operator"" _sv(const wchar_t * s, size_t length) noexcept
|
||||
{
|
||||
return basic_string_view<wchar_t>(s, length);
|
||||
}
|
||||
|
||||
inline basic_string_view<char16_t> operator"" _sv(const char16_t *s, size_t length) noexcept
|
||||
{
|
||||
return basic_string_view<char16_t>(s, length);
|
||||
}
|
||||
|
||||
inline basic_string_view<char32_t> operator"" _sv(const char32_t *s, size_t length) noexcept
|
||||
{
|
||||
return basic_string_view<char32_t>(s, length);
|
||||
}
|
||||
} // namespace string_view_literals
|
||||
|
||||
} // namespace literals
|
||||
|
||||
using StringView = string_view;
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
|
||||
// hash
|
||||
namespace std
|
||||
{
|
||||
template <class CharT, class Traits> struct hash<Aws::Crt::basic_string_view<CharT, Traits>>
|
||||
{
|
||||
size_t operator()(const Aws::Crt::basic_string_view<CharT, Traits> &val) const noexcept;
|
||||
};
|
||||
|
||||
template <class CharT, class Traits>
|
||||
size_t hash<Aws::Crt::basic_string_view<CharT, Traits>>::operator()(
|
||||
const Aws::Crt::basic_string_view<CharT, Traits> &val) const noexcept
|
||||
{
|
||||
auto str = std::basic_string<CharT, Traits>(val.data(), val.size());
|
||||
return std::hash<std::basic_string<CharT, Traits>>{}(str);
|
||||
}
|
||||
} // namespace std
|
||||
166
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/Types.h
Normal file
166
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/Types.h
Normal file
@@ -0,0 +1,166 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/common/common.h>
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/Optional.h>
|
||||
#include <aws/crt/StlAllocator.h>
|
||||
#include <aws/crt/StringView.h>
|
||||
#include <aws/io/socket.h>
|
||||
#include <aws/mqtt/mqtt.h>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
struct aws_byte_buf;
|
||||
struct aws_byte_cursor;
|
||||
struct aws_socket_options;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
using ByteBuf = aws_byte_buf;
|
||||
using ByteCursor = aws_byte_cursor;
|
||||
|
||||
namespace Io
|
||||
{
|
||||
using IStream = std::basic_istream<char, std::char_traits<char>>;
|
||||
} // namespace Io
|
||||
|
||||
namespace Mqtt
|
||||
{
|
||||
using QOS = aws_mqtt_qos;
|
||||
using ReturnCode = aws_mqtt_connect_return_code;
|
||||
} // namespace Mqtt
|
||||
|
||||
template <typename T> class StlAllocator;
|
||||
using String = std::basic_string<char, std::char_traits<char>, StlAllocator<char>>;
|
||||
using StringStream = std::basic_stringstream<char, std::char_traits<char>, StlAllocator<char>>;
|
||||
template <typename K, typename V> using Map = std::map<K, V, std::less<K>, StlAllocator<std::pair<const K, V>>>;
|
||||
template <typename K, typename V>
|
||||
using UnorderedMap =
|
||||
std::unordered_map<K, V, std::hash<K>, std::equal_to<K>, StlAllocator<std::pair<const K, V>>>;
|
||||
template <typename K, typename V>
|
||||
using MultiMap = std::multimap<K, V, std::less<K>, StlAllocator<std::pair<const K, V>>>;
|
||||
template <typename T> using Vector = std::vector<T, StlAllocator<T>>;
|
||||
template <typename T> using List = std::list<T, StlAllocator<T>>;
|
||||
|
||||
AWS_CRT_CPP_API ByteBuf ByteBufFromCString(const char *str) noexcept;
|
||||
AWS_CRT_CPP_API ByteBuf ByteBufFromEmptyArray(const uint8_t *array, size_t len) noexcept;
|
||||
AWS_CRT_CPP_API ByteBuf ByteBufFromArray(const uint8_t *array, size_t capacity) noexcept;
|
||||
AWS_CRT_CPP_API ByteBuf ByteBufNewCopy(Allocator *alloc, const uint8_t *array, size_t len);
|
||||
AWS_CRT_CPP_API ByteBuf ByteBufInit(Allocator *alloc, size_t len);
|
||||
AWS_CRT_CPP_API void ByteBufDelete(ByteBuf &);
|
||||
|
||||
AWS_CRT_CPP_API ByteCursor ByteCursorFromCString(const char *str) noexcept;
|
||||
AWS_CRT_CPP_API ByteCursor ByteCursorFromString(const Crt::String &str) noexcept;
|
||||
AWS_CRT_CPP_API ByteCursor ByteCursorFromStringView(const Crt::StringView &str) noexcept;
|
||||
AWS_CRT_CPP_API ByteCursor ByteCursorFromByteBuf(const ByteBuf &) noexcept;
|
||||
AWS_CRT_CPP_API ByteCursor ByteCursorFromArray(const uint8_t *array, size_t len) noexcept;
|
||||
|
||||
AWS_CRT_CPP_API Vector<uint8_t> Base64Decode(const String &decode) noexcept;
|
||||
AWS_CRT_CPP_API String Base64Encode(const Vector<uint8_t> &encode) noexcept;
|
||||
|
||||
template <typename RawType, typename TargetType> using TypeConvertor = std::function<TargetType(RawType)>;
|
||||
|
||||
/**
|
||||
* Template function to convert an aws_array_list of RawType to a C++ like Vector of TargetType.
|
||||
* A conversion function should be provided to do the type conversion
|
||||
*/
|
||||
template <typename RawType, typename TargetType>
|
||||
Vector<TargetType> ArrayListToVector(const aws_array_list *array, TypeConvertor<RawType, TargetType> conv)
|
||||
{
|
||||
Vector<TargetType> v;
|
||||
size_t cnt = aws_array_list_length(array);
|
||||
for (size_t i = 0; i < cnt; i++)
|
||||
{
|
||||
RawType t;
|
||||
aws_array_list_get_at(array, &t, i);
|
||||
v.emplace_back(conv(t));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template function to convert an aws_array_list of RawType to a C++ like Vector of TargetType.
|
||||
* This template assumes a direct constructor: TargetType(RawType) is available
|
||||
*/
|
||||
template <typename RawType, typename TargetType>
|
||||
Vector<TargetType> ArrayListToVector(const aws_array_list *array)
|
||||
{
|
||||
Vector<TargetType> v;
|
||||
size_t cnt = aws_array_list_length(array);
|
||||
for (size_t i = 0; i < cnt; i++)
|
||||
{
|
||||
RawType t;
|
||||
aws_array_list_get_at(array, &t, i);
|
||||
v.emplace_back(TargetType(t));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template function to convert an aws_array_list of Type to a C++ like Vector of Type.
|
||||
*/
|
||||
template <typename Type> Vector<Type> ArrayListToVector(const aws_array_list *array)
|
||||
{
|
||||
Vector<Type> v;
|
||||
size_t cnt = aws_array_list_length(array);
|
||||
for (size_t i = 0; i < cnt; i++)
|
||||
{
|
||||
Type t;
|
||||
aws_array_list_get_at(array, &t, i);
|
||||
v.emplace_back(t);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
AWS_CRT_CPP_API inline StringView ByteCursorToStringView(const ByteCursor &bc)
|
||||
{
|
||||
return StringView(reinterpret_cast<char *>(bc.ptr), bc.len);
|
||||
}
|
||||
|
||||
AWS_CRT_CPP_API inline ByteCursor StringViewToByteCursor(const StringView &sv)
|
||||
{
|
||||
ByteCursor bc;
|
||||
bc.ptr = (uint8_t *)(sv.data());
|
||||
bc.len = sv.size();
|
||||
return bc;
|
||||
}
|
||||
|
||||
template <typename T> void Delete(T *t, Allocator *allocator)
|
||||
{
|
||||
t->~T();
|
||||
aws_mem_release(allocator, t);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args> T *New(Allocator *allocator, Args &&...args)
|
||||
{
|
||||
T *t = reinterpret_cast<T *>(aws_mem_acquire(allocator, sizeof(T)));
|
||||
if (!t)
|
||||
return nullptr;
|
||||
return new (t) T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args> std::shared_ptr<T> MakeShared(Allocator *allocator, Args &&...args)
|
||||
{
|
||||
T *t = reinterpret_cast<T *>(aws_mem_acquire(allocator, sizeof(T)));
|
||||
if (!t)
|
||||
return nullptr;
|
||||
new (t) T(std::forward<Args>(args)...);
|
||||
|
||||
return std::shared_ptr<T>(t, [allocator](T *obj) { Delete(obj, allocator); });
|
||||
}
|
||||
|
||||
template <typename T> using ScopedResource = std::unique_ptr<T, std::function<void(T *)>>;
|
||||
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
42
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/UUID.h
Normal file
42
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/UUID.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/StlAllocator.h>
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
#include <aws/common/uuid.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
/**
|
||||
* Utility class for creating UUIDs and serializing them to a string
|
||||
*/
|
||||
class AWS_CRT_CPP_API UUID final
|
||||
{
|
||||
public:
|
||||
UUID() noexcept;
|
||||
UUID(const String &str) noexcept;
|
||||
|
||||
UUID &operator=(const String &str) noexcept;
|
||||
|
||||
bool operator==(const UUID &other) noexcept;
|
||||
bool operator!=(const UUID &other) noexcept;
|
||||
operator String() const;
|
||||
operator ByteBuf() const noexcept;
|
||||
|
||||
inline operator bool() const noexcept { return m_good; }
|
||||
|
||||
int GetLastError() const noexcept;
|
||||
|
||||
String ToString() const;
|
||||
|
||||
private:
|
||||
aws_uuid m_uuid;
|
||||
bool m_good;
|
||||
};
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
/**
|
||||
* Custom implementation of an in_place type tag for constructor parameter list
|
||||
*/
|
||||
struct InPlaceT
|
||||
{
|
||||
explicit InPlaceT() = default;
|
||||
};
|
||||
static constexpr InPlaceT InPlace{};
|
||||
|
||||
template <typename T> struct InPlaceTypeT
|
||||
{
|
||||
explicit InPlaceTypeT() = default;
|
||||
};
|
||||
/** Variable templates are only available since C++14
|
||||
* Use a dummy object "Aws::Crt::InPlaceTypeT<T>() in-place instead in C++11"*/
|
||||
#if defined(__cplusplus) && __cplusplus > 201103L //
|
||||
template <class T> static constexpr InPlaceTypeT<T> InPlaceType{};
|
||||
#endif
|
||||
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
591
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/Variant.h
Normal file
591
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/Variant.h
Normal file
@@ -0,0 +1,591 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/common/assert.h>
|
||||
#include <aws/crt/Utility.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace VariantDetail
|
||||
{
|
||||
template <typename T> constexpr const T &ConstExprMax(const T &a, const T &b)
|
||||
{
|
||||
return (a < b) ? b : a;
|
||||
}
|
||||
|
||||
namespace ParameterPackSize
|
||||
{
|
||||
// Returns a max of sizeof(T) over all T in a template parameter pack
|
||||
template <typename Last> constexpr std::size_t GetMaxSizeOf(std::size_t curMax = 0)
|
||||
{
|
||||
return ConstExprMax(curMax, sizeof(Last));
|
||||
}
|
||||
|
||||
template <typename First, typename Second, typename... Rest>
|
||||
constexpr std::size_t GetMaxSizeOf(std::size_t curMax = 0)
|
||||
{
|
||||
return ConstExprMax(curMax, GetMaxSizeOf<Second, Rest...>(ConstExprMax(curMax, sizeof(First))));
|
||||
}
|
||||
|
||||
// some old gcc versions does not work with alignas(Ts..)
|
||||
template <typename Last> constexpr std::size_t AlignAsPack(std::size_t curMax = 0)
|
||||
{
|
||||
return ConstExprMax(curMax, alignof(Last));
|
||||
}
|
||||
|
||||
template <typename First, typename Second, typename... Rest>
|
||||
constexpr std::size_t AlignAsPack(std::size_t curMax = 0)
|
||||
{
|
||||
return ConstExprMax(curMax, AlignAsPack<Second, Rest...>(ConstExprMax(curMax, alignof(First))));
|
||||
}
|
||||
} // namespace ParameterPackSize
|
||||
|
||||
namespace Index
|
||||
{
|
||||
using VariantIndex = short;
|
||||
|
||||
template <typename T, typename Last> constexpr VariantIndex GetIndexOf(VariantIndex curIndex = 0)
|
||||
{
|
||||
return std::is_same<T, Last>::value ? curIndex : -1;
|
||||
}
|
||||
|
||||
template <typename T, typename First, typename Second, typename... Rest>
|
||||
constexpr VariantIndex GetIndexOf(VariantIndex curIndex = 0)
|
||||
{
|
||||
return std::is_same<T, First>::value ? curIndex : GetIndexOf<T, Second, Rest...>(++curIndex);
|
||||
}
|
||||
} // namespace Index
|
||||
|
||||
namespace Checker
|
||||
{
|
||||
// Returns True if the template parameter pack Ts has a type T, i.e. ContainsType<T, Ts>() == true if T
|
||||
// is in the list of Ts
|
||||
template <typename T, typename Last> constexpr bool ContainsType()
|
||||
{
|
||||
return std::is_same<T, Last>::value;
|
||||
}
|
||||
|
||||
template <typename T, typename First, typename Second, typename... Rest> constexpr bool ContainsType()
|
||||
{
|
||||
return std::is_same<T, First>::value || ContainsType<T, Second, Rest...>();
|
||||
}
|
||||
|
||||
// a case when the template parameter pack is empty (i.e. Variant<>)
|
||||
template <typename T> constexpr bool ContainsType()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T, typename... Ts> struct HasType
|
||||
{
|
||||
static const bool value = ContainsType<T, Ts...>();
|
||||
};
|
||||
} // namespace Checker
|
||||
#if defined(AWS_CRT_ENABLE_VARIANT_DEBUG)
|
||||
namespace VariantDebug
|
||||
{
|
||||
template <typename... Ts> class VariantDebugBrowser
|
||||
{
|
||||
public:
|
||||
VariantDebugBrowser(char *storage) { InitTuple<0, Ts...>(storage); }
|
||||
std::tuple<typename std::add_pointer<Ts>::type...> as_tuple;
|
||||
|
||||
private:
|
||||
template <IndexT Index, typename First, typename Second, typename... Rest>
|
||||
void InitTuple(char *storage)
|
||||
{
|
||||
First *value = reinterpret_cast<First *>(storage);
|
||||
std::get<Index>(as_tuple) = value;
|
||||
InitTuple<Index + 1, Second, Rest...>(storage);
|
||||
}
|
||||
|
||||
template <IndexT Index, typename Last> void InitTuple(char *storage)
|
||||
{
|
||||
Last *value = reinterpret_cast<Last *>(storage);
|
||||
std::get<Index>(as_tuple) = value;
|
||||
}
|
||||
};
|
||||
} // namespace VariantDebug
|
||||
#endif /* defined(AWS_CRT_ENABLE_VARIANT_DEBUG) */
|
||||
} // namespace VariantDetail
|
||||
|
||||
template <std::size_t Index, typename... Ts> class VariantAlternative;
|
||||
|
||||
/**
|
||||
* Custom implementation of a Variant type. std::variant requires C++17
|
||||
* @tparam Ts types of the variant value
|
||||
*/
|
||||
template <typename... Ts> class Variant
|
||||
{
|
||||
private:
|
||||
template <std::size_t Index> using ThisVariantAlternative = VariantAlternative<Index, Ts...>;
|
||||
|
||||
template <typename OtherT>
|
||||
using EnableIfOtherIsThisVariantAlternative = typename std::
|
||||
enable_if<VariantDetail::Checker::HasType<typename std::decay<OtherT>::type, Ts...>::value, int>::type;
|
||||
|
||||
public:
|
||||
using IndexT = VariantDetail::Index::VariantIndex;
|
||||
static constexpr std::size_t AlternativeCount = sizeof...(Ts);
|
||||
|
||||
Variant()
|
||||
{
|
||||
using FirstAlternative = typename ThisVariantAlternative<0>::type;
|
||||
new (m_storage) FirstAlternative();
|
||||
m_index = 0;
|
||||
}
|
||||
|
||||
Variant(const Variant &other)
|
||||
{
|
||||
AWS_FATAL_ASSERT(other.m_index != -1);
|
||||
m_index = other.m_index;
|
||||
VisitorUtil<0, Ts...>::VisitBinary(this, other, CopyMoveConstructor());
|
||||
}
|
||||
|
||||
Variant(Variant &&other)
|
||||
{
|
||||
AWS_FATAL_ASSERT(other.m_index != -1);
|
||||
m_index = other.m_index;
|
||||
VisitorUtil<0, Ts...>::VisitBinary(this, std::move(other), CopyMoveConstructor());
|
||||
}
|
||||
|
||||
template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> Variant(const T &val)
|
||||
{
|
||||
static_assert(
|
||||
VariantDetail::Checker::HasType<typename std::decay<T>::type, Ts...>::value,
|
||||
"This variant does not have such alternative T.");
|
||||
static_assert(
|
||||
sizeof(T) <= STORAGE_SIZE,
|
||||
"Attempting to instantiate a Variant with a type bigger than all alternatives.");
|
||||
|
||||
using PlainT = typename std::decay<T>::type;
|
||||
new (m_storage) PlainT(val);
|
||||
m_index = VariantDetail::Index::GetIndexOf<PlainT, Ts...>();
|
||||
AWS_ASSERT(m_index != -1);
|
||||
}
|
||||
|
||||
template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> Variant(T &&val)
|
||||
{
|
||||
static_assert(
|
||||
VariantDetail::Checker::HasType<typename std::decay<T>::type, Ts...>::value,
|
||||
"This variant does not have such alternative T.");
|
||||
static_assert(
|
||||
sizeof(T) <= STORAGE_SIZE,
|
||||
"Attempting to instantiate a Variant with a type bigger than all alternatives.");
|
||||
|
||||
using PlainT = typename std::decay<T>::type;
|
||||
new (m_storage) PlainT(std::forward<T>(val));
|
||||
m_index = VariantDetail::Index::GetIndexOf<PlainT, Ts...>();
|
||||
AWS_ASSERT(m_index != -1);
|
||||
}
|
||||
|
||||
// An overload to initialize with an Alternative T in-place
|
||||
template <typename T, typename... Args> explicit Variant(Aws::Crt::InPlaceTypeT<T>, Args &&...args)
|
||||
{
|
||||
static_assert(
|
||||
VariantDetail::Checker::HasType<typename std::decay<T>::type, Ts...>::value,
|
||||
"This variant does not have such alternative T.");
|
||||
static_assert(
|
||||
sizeof(T) <= STORAGE_SIZE,
|
||||
"Attempting to instantiate a Variant with a type bigger than all alternatives.");
|
||||
|
||||
using PlainT = typename std::decay<T>::type;
|
||||
new (m_storage) PlainT(std::forward<Args>(args)...);
|
||||
m_index = VariantDetail::Index::GetIndexOf<PlainT, Ts...>();
|
||||
AWS_ASSERT(m_index != -1);
|
||||
}
|
||||
|
||||
Variant &operator=(const Variant &other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
AWS_FATAL_ASSERT(other.m_index != -1);
|
||||
if (m_index != other.m_index)
|
||||
{
|
||||
Destroy();
|
||||
m_index = other.m_index;
|
||||
VisitorUtil<0, Ts...>::VisitBinary(this, other, CopyMoveConstructor());
|
||||
}
|
||||
else
|
||||
{
|
||||
VisitorUtil<0, Ts...>::VisitBinary(this, other, CopyMoveAssigner());
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Variant &operator=(Variant &&other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
AWS_FATAL_ASSERT(other.m_index != -1);
|
||||
if (m_index != other.m_index)
|
||||
{
|
||||
Destroy();
|
||||
m_index = other.m_index;
|
||||
VisitorUtil<0, Ts...>::VisitBinary(this, std::move(other), CopyMoveConstructor());
|
||||
}
|
||||
else
|
||||
{
|
||||
VisitorUtil<0, Ts...>::VisitBinary(this, std::move(other), CopyMoveAssigner());
|
||||
};
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* emplace */
|
||||
template <typename T, typename... Args, EnableIfOtherIsThisVariantAlternative<T> = 1>
|
||||
T &emplace(Args &&...args)
|
||||
{
|
||||
static_assert(
|
||||
VariantDetail::Checker::HasType<typename std::decay<T>::type, Ts...>::value,
|
||||
"This variant does not have such alternative T.");
|
||||
static_assert(
|
||||
sizeof(T) <= STORAGE_SIZE,
|
||||
"Attempting to instantiate a Variant with a type bigger than all alternatives.");
|
||||
|
||||
Destroy();
|
||||
|
||||
using PlainT = typename std::decay<T>::type;
|
||||
new (m_storage) PlainT(std::forward<Args>(args)...);
|
||||
m_index = VariantDetail::Index::GetIndexOf<PlainT, Ts...>();
|
||||
AWS_ASSERT(m_index != -1);
|
||||
|
||||
T *value = reinterpret_cast<T *>(m_storage);
|
||||
return *value;
|
||||
}
|
||||
|
||||
template <std::size_t Index, typename... Args>
|
||||
auto emplace(Args &&...args) -> typename ThisVariantAlternative<Index>::type &
|
||||
{
|
||||
static_assert(Index < AlternativeCount, "Unknown alternative index to emplace");
|
||||
using AlternativeT = typename ThisVariantAlternative<Index>::type;
|
||||
|
||||
return emplace<AlternativeT, Args...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> bool holds_alternative() const
|
||||
{
|
||||
AWS_ASSERT(m_index != -1);
|
||||
return m_index == VariantDetail::Index::GetIndexOf<T, Ts...>();
|
||||
}
|
||||
|
||||
/* non-const get */
|
||||
template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> T &get()
|
||||
{
|
||||
AWS_FATAL_ASSERT(holds_alternative<T>());
|
||||
T *value = reinterpret_cast<T *>(m_storage);
|
||||
return *value;
|
||||
}
|
||||
|
||||
template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> T *get_if()
|
||||
{
|
||||
if (holds_alternative<T>())
|
||||
{
|
||||
T *value = reinterpret_cast<T *>(m_storage);
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t Index> auto get() -> typename ThisVariantAlternative<Index>::type &
|
||||
{
|
||||
static_assert(Index < AlternativeCount, "Unknown alternative index to get");
|
||||
AWS_FATAL_ASSERT(holds_alternative<Index>());
|
||||
using AlternativeT = typename ThisVariantAlternative<Index>::type;
|
||||
AlternativeT *ret = reinterpret_cast<AlternativeT *>(m_storage);
|
||||
return *ret;
|
||||
}
|
||||
|
||||
/* const get */
|
||||
template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> const T &get() const
|
||||
{
|
||||
AWS_FATAL_ASSERT(holds_alternative<T>());
|
||||
const T *value = reinterpret_cast<const T *>(m_storage);
|
||||
return *value;
|
||||
}
|
||||
|
||||
template <typename T, EnableIfOtherIsThisVariantAlternative<T> = 1> const T *get_if() const
|
||||
{
|
||||
if (holds_alternative<T>())
|
||||
{
|
||||
T *value = reinterpret_cast<T *>(m_storage);
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t Index> auto get() const -> const typename ThisVariantAlternative<Index>::type &
|
||||
{
|
||||
static_assert(Index < AlternativeCount, "Unknown alternative index to get");
|
||||
AWS_ASSERT(Index == m_index);
|
||||
using AlternativeT = typename ThisVariantAlternative<Index>::type;
|
||||
const AlternativeT *ret = reinterpret_cast<const AlternativeT *>(m_storage);
|
||||
return *ret;
|
||||
}
|
||||
|
||||
/* This is just a templated way to say
|
||||
* "int*" for
|
||||
* a VariantAlternative<0, Variant<int, char, long>()>*/
|
||||
template <std::size_t Index>
|
||||
using RawAlternativePointerT =
|
||||
typename std::add_pointer<typename ThisVariantAlternative<Index>::type>::type;
|
||||
|
||||
template <std::size_t Index> auto get_if() -> RawAlternativePointerT<Index>
|
||||
{
|
||||
static_assert(Index < AlternativeCount, "Unknown alternative index to get");
|
||||
if (holds_alternative<Index>())
|
||||
{
|
||||
using AlternativePtrT = RawAlternativePointerT<Index>;
|
||||
AlternativePtrT value = reinterpret_cast<AlternativePtrT>(m_storage);
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t Index>
|
||||
using ConstRawAlternativePointerT = typename std::add_pointer<
|
||||
typename std::add_const<typename ThisVariantAlternative<Index>::type>::type>::type;
|
||||
|
||||
template <std::size_t Index> auto get_if() const -> ConstRawAlternativePointerT<Index>
|
||||
{
|
||||
static_assert(Index < AlternativeCount, "Unknown alternative index to get");
|
||||
if (holds_alternative<Index>())
|
||||
{
|
||||
using AlternativePtrT = ConstRawAlternativePointerT<Index>;
|
||||
AlternativePtrT value = reinterpret_cast<AlternativePtrT>(m_storage);
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t index() const { return m_index; }
|
||||
|
||||
~Variant() { Destroy(); }
|
||||
|
||||
template <typename VisitorT> void Visit(VisitorT &&visitor)
|
||||
{
|
||||
return VisitorUtil<0, Ts...>::Visit(this, std::forward<VisitorT>(visitor));
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr std::size_t STORAGE_SIZE = VariantDetail::ParameterPackSize::GetMaxSizeOf<Ts...>();
|
||||
|
||||
alignas(VariantDetail::ParameterPackSize::AlignAsPack<Ts...>()) char m_storage[STORAGE_SIZE];
|
||||
IndexT m_index = -1;
|
||||
#if defined(AWS_CRT_ENABLE_VARIANT_DEBUG)
|
||||
VariantDetail::VariantDebug::VariantDebugBrowser<Ts...> browser = m_storage;
|
||||
#endif /* defined(AWS_CRT_ENABLE_VARIANT_DEBUG) */
|
||||
|
||||
template <size_t Index> constexpr bool holds_alternative() const { return Index == m_index; }
|
||||
|
||||
struct Destroyer
|
||||
{
|
||||
template <typename AlternativeT> void operator()(AlternativeT &&value) const
|
||||
{
|
||||
using PlaintT = typename std::remove_reference<AlternativeT>::type;
|
||||
value.~PlaintT();
|
||||
}
|
||||
};
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
AWS_FATAL_ASSERT(m_index != -1);
|
||||
Visit(Destroyer());
|
||||
|
||||
m_index = -1;
|
||||
}
|
||||
|
||||
struct CopyMoveConstructor
|
||||
{
|
||||
template <typename AlternativeT> void operator()(AlternativeT &&value, AlternativeT &&other) const
|
||||
{
|
||||
using PlaintT = typename std::remove_reference<AlternativeT>::type;
|
||||
new (&value) PlaintT(std::move<AlternativeT>(other));
|
||||
}
|
||||
|
||||
template <typename AlternativeT, typename ConstAlternativeT>
|
||||
void operator()(AlternativeT &&value, ConstAlternativeT &other) const
|
||||
{
|
||||
using PlaintT = typename std::remove_reference<AlternativeT>::type;
|
||||
using PlaintOtherT =
|
||||
typename std::remove_const<typename std::remove_reference<AlternativeT>::type>::type;
|
||||
static_assert(std::is_same<PlaintT, PlaintOtherT>::value, "Incompatible types");
|
||||
|
||||
new (&value) PlaintT(other);
|
||||
}
|
||||
};
|
||||
|
||||
struct CopyMoveAssigner
|
||||
{
|
||||
template <typename AlternativeT> void operator()(AlternativeT &&value, AlternativeT &&other) const
|
||||
{
|
||||
value = std::move(other);
|
||||
}
|
||||
|
||||
template <typename AlternativeT, typename ConstAlternativeT>
|
||||
void operator()(AlternativeT &&value, ConstAlternativeT &other) const
|
||||
{
|
||||
using PlaintT = typename std::remove_reference<AlternativeT>::type;
|
||||
using PlaintOtherT =
|
||||
typename std::remove_const<typename std::remove_reference<AlternativeT>::type>::type;
|
||||
static_assert(std::is_same<PlaintT, PlaintOtherT>::value, "Incompatible types");
|
||||
|
||||
value = other;
|
||||
}
|
||||
};
|
||||
|
||||
template <IndexT Index, typename... Args> struct VisitorUtil;
|
||||
|
||||
template <IndexT Index, typename First, typename Second, typename... Rest>
|
||||
struct VisitorUtil<Index, First, Second, Rest...>
|
||||
{
|
||||
template <typename VisitorStruct> static void Visit(Variant *pThis, VisitorStruct &&visitor)
|
||||
{
|
||||
static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
|
||||
|
||||
if (Index == pThis->m_index)
|
||||
{
|
||||
using AlternativeT = typename ThisVariantAlternative<Index>::type;
|
||||
AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
|
||||
visitor(*value);
|
||||
}
|
||||
else
|
||||
{
|
||||
VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>::Visit(
|
||||
pThis, std::forward<VisitorStruct>(visitor));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VisitorStruct>
|
||||
static void VisitBinary(Variant<Ts...> *pThis, Variant<Ts...> &&other, VisitorStruct &&visitor)
|
||||
{
|
||||
static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
|
||||
|
||||
if (Index == pThis->m_index)
|
||||
{
|
||||
using AlternativeT = typename ThisVariantAlternative<Index>::type;
|
||||
AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
|
||||
visitor(*value, other.get<AlternativeT>());
|
||||
}
|
||||
else
|
||||
{
|
||||
VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>::VisitBinary(
|
||||
pThis, std::forward<Variant<Ts...>>(other), std::forward<VisitorStruct>(visitor));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VisitorStruct>
|
||||
static void VisitBinary(Variant<Ts...> *pThis, const Variant<Ts...> &other, VisitorStruct &&visitor)
|
||||
{
|
||||
static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
|
||||
|
||||
if (Index == pThis->m_index)
|
||||
{
|
||||
using AlternativeT = typename ThisVariantAlternative<Index>::type;
|
||||
AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
|
||||
const AlternativeT &otherValue = other.get<AlternativeT>();
|
||||
visitor(*value, otherValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>::VisitBinary(
|
||||
pThis, other, std::forward<VisitorStruct>(visitor));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <IndexT Index, typename Last> struct VisitorUtil<Index, Last>
|
||||
{
|
||||
template <typename VisitorStruct> static void Visit(Variant *pThis, VisitorStruct &&visitor)
|
||||
{
|
||||
static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
|
||||
|
||||
if (Index == pThis->m_index)
|
||||
{
|
||||
using AlternativeT = typename ThisVariantAlternative<Index>::type;
|
||||
AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
|
||||
visitor(*value);
|
||||
}
|
||||
else
|
||||
{
|
||||
AWS_FATAL_ASSERT(!"Unknown variant alternative to visit!");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VisitorStruct>
|
||||
static void VisitBinary(Variant<Ts...> *pThis, Variant<Ts...> &&other, VisitorStruct &&visitor)
|
||||
{
|
||||
static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
|
||||
|
||||
if (Index == pThis->m_index)
|
||||
{
|
||||
using AlternativeT = typename ThisVariantAlternative<Index>::type;
|
||||
AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
|
||||
visitor(*value, other.get<AlternativeT>());
|
||||
}
|
||||
else
|
||||
{
|
||||
AWS_FATAL_ASSERT(!"Unknown variant alternative to visit!");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VisitorStruct>
|
||||
static void VisitBinary(Variant<Ts...> *pThis, const Variant<Ts...> &other, VisitorStruct &&visitor)
|
||||
{
|
||||
static_assert(Index < AlternativeCount, "Attempting to visit unknown Index Type");
|
||||
|
||||
if (Index == pThis->m_index)
|
||||
{
|
||||
using AlternativeT = typename ThisVariantAlternative<Index>::type;
|
||||
AlternativeT *value = reinterpret_cast<AlternativeT *>(pThis->m_storage);
|
||||
const AlternativeT &otherValue = other.get<AlternativeT>();
|
||||
visitor(*value, otherValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
AWS_FATAL_ASSERT(!"Unknown variant alternative to visit!");
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/* Helper template to get an actual type from an Index */
|
||||
template <std::size_t Index, typename... Ts> class VariantAlternative
|
||||
{
|
||||
public:
|
||||
// uses std::tuple as a helper struct to provide index-based access of a parameter pack
|
||||
using type = typename std::tuple_element<Index, std::tuple<Ts...>>::type;
|
||||
|
||||
VariantAlternative(const Variant<Ts...> &) {}
|
||||
|
||||
VariantAlternative(const Variant<Ts...> *) {}
|
||||
};
|
||||
|
||||
template <typename T> class VariantSize
|
||||
{
|
||||
constexpr static const std::size_t Value = T::AlternativeCount;
|
||||
};
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,585 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/crt/http/HttpConnection.h>
|
||||
#include <aws/crt/io/TlsOptions.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
|
||||
struct aws_credentials;
|
||||
struct aws_credentials_provider;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
class ClientBootstrap;
|
||||
}
|
||||
|
||||
namespace Http
|
||||
{
|
||||
class HttpClientConnectionProxyOptions;
|
||||
}
|
||||
|
||||
namespace Auth
|
||||
{
|
||||
/**
|
||||
* A class to hold the basic components necessary for various AWS authentication protocols.
|
||||
*/
|
||||
class AWS_CRT_CPP_API Credentials
|
||||
{
|
||||
public:
|
||||
Credentials(const aws_credentials *credentials) noexcept;
|
||||
Credentials(
|
||||
ByteCursor access_key_id,
|
||||
ByteCursor secret_access_key,
|
||||
ByteCursor session_token,
|
||||
uint64_t expiration_timepoint_in_seconds,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Create new anonymous Credentials.
|
||||
* Use anonymous Credentials when you want to skip signing.
|
||||
* @param allocator
|
||||
*/
|
||||
Credentials(Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
~Credentials();
|
||||
|
||||
Credentials(const Credentials &) = delete;
|
||||
Credentials(Credentials &&) = delete;
|
||||
Credentials &operator=(const Credentials &) = delete;
|
||||
Credentials &operator=(Credentials &&) = delete;
|
||||
|
||||
/**
|
||||
* Gets the value of the access key component of aws credentials
|
||||
*/
|
||||
ByteCursor GetAccessKeyId() const noexcept;
|
||||
|
||||
/**
|
||||
* Gets the value of the secret access key component of aws credentials
|
||||
*/
|
||||
ByteCursor GetSecretAccessKey() const noexcept;
|
||||
|
||||
/**
|
||||
* Gets the value of the session token of aws credentials
|
||||
*/
|
||||
ByteCursor GetSessionToken() const noexcept;
|
||||
|
||||
/**
|
||||
* Gets the expiration timestamp for the credentials, or UINT64_MAX if no expiration
|
||||
*/
|
||||
uint64_t GetExpirationTimepointInSeconds() const noexcept;
|
||||
|
||||
/**
|
||||
* Validity check - returns true if the instance is valid, false otherwise
|
||||
*/
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the underlying credentials implementation.
|
||||
*/
|
||||
const aws_credentials *GetUnderlyingHandle() const noexcept { return m_credentials; }
|
||||
|
||||
private:
|
||||
const aws_credentials *m_credentials;
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback invoked by credentials providers when resolution succeeds (credentials will be non-null)
|
||||
* or fails (credentials will be null)
|
||||
*/
|
||||
using OnCredentialsResolved = std::function<void(std::shared_ptr<Credentials>, int errorCode)>;
|
||||
|
||||
/**
|
||||
* Invoked when the native delegate credentials provider needs to fetch a credential.
|
||||
*/
|
||||
using GetCredentialsHandler = std::function<std::shared_ptr<Credentials>()>;
|
||||
|
||||
/**
|
||||
* Base interface for all credentials providers. Credentials providers are objects that
|
||||
* retrieve AWS credentials from some source.
|
||||
*/
|
||||
class AWS_CRT_CPP_API ICredentialsProvider : public std::enable_shared_from_this<ICredentialsProvider>
|
||||
{
|
||||
public:
|
||||
virtual ~ICredentialsProvider() = default;
|
||||
|
||||
/**
|
||||
* Asynchronous method to query for AWS credentials based on the internal provider implementation.
|
||||
*/
|
||||
virtual bool GetCredentials(const OnCredentialsResolved &onCredentialsResolved) const = 0;
|
||||
|
||||
/**
|
||||
* Returns the underlying credentials provider implementation. Support for credentials providers
|
||||
* not based on a C implementation is theoretically possible, but requires some re-implementation to
|
||||
* support provider chains and caching (whose implementations rely on links to C implementation
|
||||
* providers)
|
||||
*/
|
||||
virtual aws_credentials_provider *GetUnderlyingHandle() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Validity check method
|
||||
*/
|
||||
virtual bool IsValid() const noexcept = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration options for the static credentials provider
|
||||
*/
|
||||
struct AWS_CRT_CPP_API CredentialsProviderStaticConfig
|
||||
{
|
||||
CredentialsProviderStaticConfig()
|
||||
{
|
||||
AWS_ZERO_STRUCT(AccessKeyId);
|
||||
AWS_ZERO_STRUCT(SecretAccessKey);
|
||||
AWS_ZERO_STRUCT(SessionToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the access key component for the provider's static aws credentials
|
||||
*/
|
||||
ByteCursor AccessKeyId;
|
||||
|
||||
/**
|
||||
* The value of the secret access key component for the provider's static aws credentials
|
||||
*/
|
||||
ByteCursor SecretAccessKey;
|
||||
|
||||
/**
|
||||
* The value of the session token for the provider's static aws credentials
|
||||
*/
|
||||
ByteCursor SessionToken;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration options for the profile credentials provider
|
||||
*/
|
||||
struct AWS_CRT_CPP_API CredentialsProviderProfileConfig
|
||||
{
|
||||
CredentialsProviderProfileConfig() : Bootstrap(nullptr), TlsContext(nullptr)
|
||||
{
|
||||
AWS_ZERO_STRUCT(ProfileNameOverride);
|
||||
AWS_ZERO_STRUCT(ConfigFileNameOverride);
|
||||
AWS_ZERO_STRUCT(CredentialsFileNameOverride);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override profile name to use (instead of default) when the provider sources credentials
|
||||
*/
|
||||
ByteCursor ProfileNameOverride;
|
||||
|
||||
/**
|
||||
* Override file path (instead of '~/.aws/config' for the aws config file to use during
|
||||
* credential sourcing
|
||||
*/
|
||||
ByteCursor ConfigFileNameOverride;
|
||||
|
||||
/**
|
||||
* Override file path (instead of '~/.aws/credentials' for the aws credentials file to use during
|
||||
* credential sourcing
|
||||
*/
|
||||
ByteCursor CredentialsFileNameOverride;
|
||||
|
||||
/**
|
||||
* Connection bootstrap to use for any network connections made while sourcing credentials.
|
||||
* (for example, a profile that uses assume-role will need to query STS).
|
||||
*/
|
||||
Io::ClientBootstrap *Bootstrap;
|
||||
|
||||
/**
|
||||
* Client TLS context to use for any secure network connections made while sourcing credentials
|
||||
* (for example, a profile that uses assume-role will need to query STS).
|
||||
*
|
||||
* If a TLS context is needed, and you did not pass one in, it will be created automatically.
|
||||
* However, you are encouraged to pass in a shared one since these are expensive objects.
|
||||
* If using BYO_CRYPTO, you must provide the TLS context since it cannot be created automatically.
|
||||
*/
|
||||
Io::TlsContext *TlsContext;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration options for the Ec2 instance metadata service credentials provider
|
||||
*/
|
||||
struct AWS_CRT_CPP_API CredentialsProviderImdsConfig
|
||||
{
|
||||
CredentialsProviderImdsConfig() : Bootstrap(nullptr) {}
|
||||
|
||||
/**
|
||||
* Connection bootstrap to use to create the http connection required to
|
||||
* query credentials from the Ec2 instance metadata service
|
||||
*
|
||||
* Note: If null, then the default ClientBootstrap is used
|
||||
* (see Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap)
|
||||
*/
|
||||
Io::ClientBootstrap *Bootstrap;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration options for a chain-of-responsibility-based credentials provider.
|
||||
* This provider works by traversing the chain and returning the first positive
|
||||
* result.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API CredentialsProviderChainConfig
|
||||
{
|
||||
CredentialsProviderChainConfig() : Providers() {}
|
||||
|
||||
/**
|
||||
* The sequence of providers that make up the chain.
|
||||
*/
|
||||
Vector<std::shared_ptr<ICredentialsProvider>> Providers;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration options for a provider that caches the results of another provider
|
||||
*/
|
||||
struct AWS_CRT_CPP_API CredentialsProviderCachedConfig
|
||||
{
|
||||
CredentialsProviderCachedConfig() : Provider(), CachedCredentialTTL() {}
|
||||
|
||||
/**
|
||||
* The provider to cache credentials from
|
||||
*/
|
||||
std::shared_ptr<ICredentialsProvider> Provider;
|
||||
|
||||
/**
|
||||
* How long a cached credential set will be used for
|
||||
*/
|
||||
std::chrono::milliseconds CachedCredentialTTL;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration options for a provider that implements a cached provider chain
|
||||
* based on the AWS SDK defaults:
|
||||
*
|
||||
* Cache-Of(Environment -> Profile -> IMDS)
|
||||
*/
|
||||
struct AWS_CRT_CPP_API CredentialsProviderChainDefaultConfig
|
||||
{
|
||||
CredentialsProviderChainDefaultConfig() : Bootstrap(nullptr), TlsContext(nullptr) {}
|
||||
|
||||
/**
|
||||
* Connection bootstrap to use for any network connections made while sourcing credentials.
|
||||
*
|
||||
* Note: If null, then the default ClientBootstrap is used
|
||||
* (see Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap)
|
||||
*/
|
||||
Io::ClientBootstrap *Bootstrap;
|
||||
|
||||
/**
|
||||
* Client TLS context to use for any secure network connections made while sourcing credentials.
|
||||
*
|
||||
* If not provided the default chain will construct a new one, but these
|
||||
* are expensive objects so you are encouraged to pass in a shared one.
|
||||
* Must be provided if using BYO_CRYPTO.
|
||||
*/
|
||||
Io::TlsContext *TlsContext;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration options for the X509 credentials provider
|
||||
*/
|
||||
struct AWS_CRT_CPP_API CredentialsProviderX509Config
|
||||
{
|
||||
CredentialsProviderX509Config()
|
||||
: Bootstrap(nullptr), TlsOptions(), ThingName(), RoleAlias(), Endpoint(), ProxyOptions()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection bootstrap to use to create the http connection required to
|
||||
* query credentials from the x509 provider
|
||||
*
|
||||
* Note: If null, then the default ClientBootstrap is used
|
||||
* (see Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap)
|
||||
*/
|
||||
Io::ClientBootstrap *Bootstrap;
|
||||
|
||||
/* TLS connection options that have been initialized with your x509 certificate and private key */
|
||||
Io::TlsConnectionOptions TlsOptions;
|
||||
|
||||
/* IoT thing name you registered with AWS IOT for your device, it will be used in http request header */
|
||||
String ThingName;
|
||||
|
||||
/* Iot role alias you created with AWS IoT for your IAM role, it will be used in http request path */
|
||||
String RoleAlias;
|
||||
|
||||
/**
|
||||
* AWS account specific endpoint that can be acquired using AWS CLI following instructions from the demo
|
||||
* example: c2sakl5huz0afv.credentials.iot.us-east-1.amazonaws.com
|
||||
*
|
||||
* This a different endpoint than the IoT data mqtt broker endpoint.
|
||||
*/
|
||||
String Endpoint;
|
||||
|
||||
/**
|
||||
* (Optional) Http proxy configuration for the http request that fetches credentials
|
||||
*/
|
||||
Optional<Http::HttpClientConnectionProxyOptions> ProxyOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration options for the delegate credentials provider
|
||||
*/
|
||||
struct AWS_CRT_CPP_API CredentialsProviderDelegateConfig
|
||||
{
|
||||
/* handler to provider credentials */
|
||||
GetCredentialsHandler Handler;
|
||||
};
|
||||
|
||||
/**
|
||||
* A pair defining an identity provider and a valid login token sourced from it.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API CognitoLoginPair
|
||||
{
|
||||
|
||||
/**
|
||||
* Name of an identity provider
|
||||
*/
|
||||
String IdentityProviderName;
|
||||
|
||||
/**
|
||||
* Valid login token source from the identity provider
|
||||
*/
|
||||
String IdentityProviderToken;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration options for the Cognito credentials provider
|
||||
*/
|
||||
struct AWS_CRT_CPP_API CredentialsProviderCognitoConfig
|
||||
{
|
||||
CredentialsProviderCognitoConfig();
|
||||
|
||||
/**
|
||||
* Cognito service regional endpoint to source credentials from.
|
||||
*/
|
||||
String Endpoint;
|
||||
|
||||
/**
|
||||
* Cognito identity to fetch credentials relative to.
|
||||
*/
|
||||
String Identity;
|
||||
|
||||
/**
|
||||
* Optional set of identity provider token pairs to allow for authenticated identity access.
|
||||
*/
|
||||
Optional<Vector<CognitoLoginPair>> Logins;
|
||||
|
||||
/**
|
||||
* Optional ARN of the role to be assumed when multiple roles were received in the token from the
|
||||
* identity provider.
|
||||
*/
|
||||
Optional<String> CustomRoleArn;
|
||||
|
||||
/**
|
||||
* Connection bootstrap to use to create the http connection required to
|
||||
* query credentials from the cognito provider
|
||||
*
|
||||
* Note: If null, then the default ClientBootstrap is used
|
||||
* (see Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap)
|
||||
*/
|
||||
Io::ClientBootstrap *Bootstrap;
|
||||
|
||||
/**
|
||||
* TLS configuration for secure socket connections.
|
||||
*/
|
||||
Io::TlsContext TlsCtx;
|
||||
|
||||
/**
|
||||
* (Optional) Http proxy configuration for the http request that fetches credentials
|
||||
*/
|
||||
Optional<Http::HttpClientConnectionProxyOptions> ProxyOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration options for the STS credentials provider
|
||||
*/
|
||||
struct AWS_CRT_CPP_API CredentialsProviderSTSConfig
|
||||
{
|
||||
CredentialsProviderSTSConfig();
|
||||
|
||||
/**
|
||||
* Credentials provider to be used to sign the requests made to STS to fetch credentials.
|
||||
*/
|
||||
std::shared_ptr<ICredentialsProvider> Provider;
|
||||
|
||||
/**
|
||||
* Arn of the role to assume by fetching credentials for
|
||||
*/
|
||||
String RoleArn;
|
||||
|
||||
/**
|
||||
* Assumed role session identifier to be associated with the sourced credentials
|
||||
*/
|
||||
String SessionName;
|
||||
|
||||
/**
|
||||
* How long sourced credentials should remain valid for, in seconds. 900 is the minimum allowed value.
|
||||
*/
|
||||
uint16_t DurationSeconds;
|
||||
|
||||
/**
|
||||
* Connection bootstrap to use to create the http connection required to
|
||||
* query credentials from the STS provider
|
||||
*
|
||||
* Note: If null, then the default ClientBootstrap is used
|
||||
* (see Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap)
|
||||
*/
|
||||
Io::ClientBootstrap *Bootstrap;
|
||||
|
||||
/**
|
||||
* TLS configuration for secure socket connections.
|
||||
*/
|
||||
Io::TlsContext TlsCtx;
|
||||
|
||||
/**
|
||||
* (Optional) Http proxy configuration for the http request that fetches credentials
|
||||
*/
|
||||
Optional<Http::HttpClientConnectionProxyOptions> ProxyOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple credentials provider implementation that wraps one of the internal C-based implementations.
|
||||
*
|
||||
* Contains a set of static factory methods for building each supported provider, as well as one for the
|
||||
* default provider chain.
|
||||
*/
|
||||
class AWS_CRT_CPP_API CredentialsProvider : public ICredentialsProvider
|
||||
{
|
||||
public:
|
||||
CredentialsProvider(aws_credentials_provider *provider, Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
virtual ~CredentialsProvider();
|
||||
|
||||
CredentialsProvider(const CredentialsProvider &) = delete;
|
||||
CredentialsProvider(CredentialsProvider &&) = delete;
|
||||
CredentialsProvider &operator=(const CredentialsProvider &) = delete;
|
||||
CredentialsProvider &operator=(CredentialsProvider &&) = delete;
|
||||
|
||||
/**
|
||||
* Asynchronous method to query for AWS credentials based on the internal provider implementation.
|
||||
*/
|
||||
virtual bool GetCredentials(const OnCredentialsResolved &onCredentialsResolved) const override;
|
||||
|
||||
/**
|
||||
* Returns the underlying credentials provider implementation.
|
||||
*/
|
||||
virtual aws_credentials_provider *GetUnderlyingHandle() const noexcept override { return m_provider; }
|
||||
|
||||
/**
|
||||
* Validity check method
|
||||
*/
|
||||
virtual bool IsValid() const noexcept override { return m_provider != nullptr; }
|
||||
|
||||
/*
|
||||
* Factory methods for all of the basic credentials provider types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a provider that returns a fixed set of credentials
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderStatic(
|
||||
const CredentialsProviderStaticConfig &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Creates an anonymous provider that have anonymous credentials
|
||||
* Use anonymous credentials when you want to skip signing
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderAnonymous(
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Creates a provider that returns credentials sourced from environment variables
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderEnvironment(
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Creates a provider that returns credentials sourced from config files
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderProfile(
|
||||
const CredentialsProviderProfileConfig &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Creates a provider that returns credentials sourced from Ec2 instance metadata service
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderImds(
|
||||
const CredentialsProviderImdsConfig &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Creates a provider that sources credentials by querying a series of providers and
|
||||
* returning the first valid credential set encountered
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderChain(
|
||||
const CredentialsProviderChainConfig &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/*
|
||||
* Creates a provider that puts a simple time-based cache in front of its queries
|
||||
* to a subordinate provider.
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderCached(
|
||||
const CredentialsProviderCachedConfig &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Creates the SDK-standard default credentials provider which is a cache-fronted chain of:
|
||||
*
|
||||
* Environment -> Profile -> IMDS/ECS
|
||||
*
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderChainDefault(
|
||||
const CredentialsProviderChainDefaultConfig &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Creates a provider that sources credentials from the IoT X509 provider service
|
||||
*
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderX509(
|
||||
const CredentialsProviderX509Config &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Creates a provider that sources credentials from the provided function.
|
||||
*
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderDelegate(
|
||||
const CredentialsProviderDelegateConfig &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Creates a provider that sources credentials from the Cognito Identity service
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderCognito(
|
||||
const CredentialsProviderCognitoConfig &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Creates a provider that sources credentials from STS
|
||||
*/
|
||||
static std::shared_ptr<ICredentialsProvider> CreateCredentialsProviderSTS(
|
||||
const CredentialsProviderSTSConfig &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
private:
|
||||
static void s_onCredentialsResolved(aws_credentials *credentials, int error_code, void *user_data);
|
||||
|
||||
Allocator *m_allocator;
|
||||
aws_credentials_provider *m_provider;
|
||||
};
|
||||
} // namespace Auth
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Exports.h>
|
||||
|
||||
#include <aws/auth/signing_config.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Http
|
||||
{
|
||||
class HttpRequest;
|
||||
}
|
||||
|
||||
namespace Auth
|
||||
{
|
||||
/**
|
||||
* RTTI indicator for signing configuration. We currently only support a single type (AWS), but
|
||||
* we could expand to others in the future if needed.
|
||||
*/
|
||||
enum class SigningConfigType
|
||||
{
|
||||
Aws = AWS_SIGNING_CONFIG_AWS
|
||||
};
|
||||
|
||||
/**
|
||||
* HTTP signing callback. The second parameter is an aws error code, The signing was successful
|
||||
* if the error code is AWS_ERROR_SUCCESS.
|
||||
*/
|
||||
using OnHttpRequestSigningComplete =
|
||||
std::function<void(const std::shared_ptr<Aws::Crt::Http::HttpRequest> &, int)>;
|
||||
|
||||
/**
|
||||
* Base class for all different signing configurations. Type functions as a
|
||||
* primitive RTTI for downcasting.
|
||||
*/
|
||||
class AWS_CRT_CPP_API ISigningConfig
|
||||
{
|
||||
public:
|
||||
ISigningConfig() = default;
|
||||
ISigningConfig(const ISigningConfig &) = delete;
|
||||
ISigningConfig(ISigningConfig &&) = delete;
|
||||
ISigningConfig &operator=(const ISigningConfig &) = delete;
|
||||
ISigningConfig &operator=(ISigningConfig &&) = delete;
|
||||
|
||||
virtual ~ISigningConfig() = default;
|
||||
|
||||
/**
|
||||
* RTTI query for the SigningConfig hierarchy
|
||||
* @return the type of signing configuration
|
||||
*/
|
||||
virtual SigningConfigType GetType(void) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract base for all http request signers. Asynchronous interface. Intended to
|
||||
* be a tight wrapper around aws-c-* signer implementations.
|
||||
*/
|
||||
class AWS_CRT_CPP_API IHttpRequestSigner
|
||||
{
|
||||
public:
|
||||
IHttpRequestSigner() = default;
|
||||
IHttpRequestSigner(const IHttpRequestSigner &) = delete;
|
||||
IHttpRequestSigner(IHttpRequestSigner &&) = delete;
|
||||
IHttpRequestSigner &operator=(const IHttpRequestSigner &) = delete;
|
||||
IHttpRequestSigner &operator=(IHttpRequestSigner &&) = delete;
|
||||
|
||||
virtual ~IHttpRequestSigner() = default;
|
||||
|
||||
/**
|
||||
* Signs an http request based on the signing implementation and supplied configuration
|
||||
* @param request http request to sign
|
||||
* @param config base signing configuration. Actual type should match the configuration expected
|
||||
* by the signer implementation
|
||||
* @param completionCallback completion function to invoke when signing has completed or failed
|
||||
* @return true if the signing process was kicked off, false if there was a synchronous failure.
|
||||
*/
|
||||
virtual bool SignRequest(
|
||||
const std::shared_ptr<Aws::Crt::Http::HttpRequest> &request,
|
||||
const ISigningConfig &config,
|
||||
const OnHttpRequestSigningComplete &completionCallback) = 0;
|
||||
|
||||
/**
|
||||
* @return Whether or not the signer is in a valid state
|
||||
*/
|
||||
virtual bool IsValid() const = 0;
|
||||
};
|
||||
|
||||
} // namespace Auth
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,352 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Exports.h>
|
||||
|
||||
#include <aws/crt/DateTime.h>
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/crt/auth/Signing.h>
|
||||
|
||||
struct aws_signing_config_aws;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Auth
|
||||
{
|
||||
class Credentials;
|
||||
class ICredentialsProvider;
|
||||
|
||||
/**
|
||||
* Enumeration indicating what version of the AWS signing process we should use.
|
||||
*/
|
||||
enum class SigningAlgorithm
|
||||
{
|
||||
/**
|
||||
* Standard AWS Sigv4 signing using a symmetric secret, per
|
||||
* https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
|
||||
*/
|
||||
SigV4 = AWS_SIGNING_ALGORITHM_V4,
|
||||
|
||||
/**
|
||||
* A variant of AWS Sigv4 signing that uses ecdsa signatures based on an ECC key, rather than relying on
|
||||
* a shared secret.
|
||||
*/
|
||||
SigV4A = AWS_SIGNING_ALGORITHM_V4_ASYMMETRIC,
|
||||
};
|
||||
|
||||
/**
|
||||
* What kind of AWS signature should be computed?
|
||||
*/
|
||||
enum class SignatureType
|
||||
{
|
||||
/**
|
||||
* A signature for a full http request should be computed, with header updates applied to the signing
|
||||
* result.
|
||||
*/
|
||||
HttpRequestViaHeaders = AWS_ST_HTTP_REQUEST_HEADERS,
|
||||
|
||||
/**
|
||||
* A signature for a full http request should be computed, with query param updates applied to the
|
||||
* signing result.
|
||||
*/
|
||||
HttpRequestViaQueryParams = AWS_ST_HTTP_REQUEST_QUERY_PARAMS,
|
||||
|
||||
/**
|
||||
* Compute a signature for a payload chunk.
|
||||
*/
|
||||
HttpRequestChunk = AWS_ST_HTTP_REQUEST_CHUNK,
|
||||
|
||||
/**
|
||||
* Compute a signature for an event stream event.
|
||||
*
|
||||
* This option is not yet supported.
|
||||
*/
|
||||
HttpRequestEvent = AWS_ST_HTTP_REQUEST_EVENT,
|
||||
};
|
||||
|
||||
/**
|
||||
* A collection of signed body constants. Some are specific to certain
|
||||
* signature types, while others are just there to save time (empty sha, for example).
|
||||
*/
|
||||
namespace SignedBodyValue
|
||||
{
|
||||
/**
|
||||
* The SHA-256 of an empty string:
|
||||
* 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
||||
* For use with `Aws::Crt::Auth::AwsSigningConfig.SetSignedBodyValue()`.
|
||||
*/
|
||||
AWS_CRT_CPP_API const char *EmptySha256Str();
|
||||
|
||||
/**
|
||||
* 'UNSIGNED-PAYLOAD'
|
||||
* For use with `Aws::Crt::Auth::AwsSigningConfig.SetSignedBodyValue()`.
|
||||
*/
|
||||
AWS_CRT_CPP_API const char *UnsignedPayloadStr();
|
||||
|
||||
/**
|
||||
* 'STREAMING-AWS4-HMAC-SHA256-PAYLOAD'
|
||||
* For use with `Aws::Crt::Auth::AwsSigningConfig.SetSignedBodyValue()`.
|
||||
*/
|
||||
AWS_CRT_CPP_API const char *StreamingAws4HmacSha256PayloadStr();
|
||||
/**
|
||||
* 'STREAMING-AWS4-HMAC-SHA256-EVENTS'
|
||||
* For use with `Aws::Crt::Auth::AwsSigningConfig.SetSignedBodyValue()`.
|
||||
*/
|
||||
AWS_CRT_CPP_API const char *StreamingAws4HmacSha256EventsStr();
|
||||
|
||||
/** @deprecated to avoid issues with /DELAYLOAD on Windows. */
|
||||
AWS_CRT_CPP_API extern const char *UnsignedPayload;
|
||||
/** @deprecated to avoid issues with /DELAYLOAD on Windows. */
|
||||
AWS_CRT_CPP_API extern const char *EmptySha256;
|
||||
/** @deprecated to avoid issues with /DELAYLOAD on Windows. */
|
||||
AWS_CRT_CPP_API extern const char *StreamingAws4HmacSha256Payload;
|
||||
/** @deprecated to avoid issues with /DELAYLOAD on Windows. */
|
||||
AWS_CRT_CPP_API extern const char *StreamingAws4HmacSha256Events;
|
||||
} // namespace SignedBodyValue
|
||||
|
||||
/**
|
||||
* Controls if signing adds a header containing the canonical request's body value
|
||||
*/
|
||||
enum class SignedBodyHeaderType
|
||||
{
|
||||
/**
|
||||
* Do not add a header
|
||||
*/
|
||||
None = AWS_SBHT_NONE,
|
||||
|
||||
/**
|
||||
* Add the "x-amz-content-sha256" header with the canonical request's body value
|
||||
*/
|
||||
XAmzContentSha256 = AWS_SBHT_X_AMZ_CONTENT_SHA256,
|
||||
};
|
||||
|
||||
using ShouldSignHeaderCb = bool (*)(const Crt::ByteCursor *, void *);
|
||||
|
||||
/**
|
||||
* Wrapper around the configuration structure specific to the AWS
|
||||
* Sigv4 signing process
|
||||
*/
|
||||
class AWS_CRT_CPP_API AwsSigningConfig : public ISigningConfig
|
||||
{
|
||||
public:
|
||||
AwsSigningConfig(Allocator *allocator = ApiAllocator());
|
||||
virtual ~AwsSigningConfig();
|
||||
|
||||
virtual SigningConfigType GetType() const noexcept override { return SigningConfigType::Aws; }
|
||||
|
||||
/**
|
||||
* @return the signing process we want to invoke
|
||||
*/
|
||||
SigningAlgorithm GetSigningAlgorithm() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the signing process we want to invoke
|
||||
*/
|
||||
void SetSigningAlgorithm(SigningAlgorithm algorithm) noexcept;
|
||||
|
||||
/**
|
||||
* @return the type of signature we want to calculate
|
||||
*/
|
||||
SignatureType GetSignatureType() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the type of signature we want to calculate
|
||||
*/
|
||||
void SetSignatureType(SignatureType signatureType) noexcept;
|
||||
|
||||
/**
|
||||
* @return the AWS region to sign against
|
||||
*/
|
||||
const Crt::String &GetRegion() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the AWS region to sign against
|
||||
*/
|
||||
void SetRegion(const Crt::String ®ion) noexcept;
|
||||
|
||||
/**
|
||||
* @return the (signing) name of the AWS service to sign a request for
|
||||
*/
|
||||
const Crt::String &GetService() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the (signing) name of the AWS service to sign a request for
|
||||
*/
|
||||
void SetService(const Crt::String &service) noexcept;
|
||||
|
||||
/**
|
||||
* @return the timestamp to use during the signing process.
|
||||
*/
|
||||
DateTime GetSigningTimepoint() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the timestamp to use during the signing process.
|
||||
*/
|
||||
void SetSigningTimepoint(const DateTime &date) noexcept;
|
||||
|
||||
/*
|
||||
* We assume the uri will be encoded once in preparation for transmission. Certain services
|
||||
* do not decode before checking signature, requiring us to actually double-encode the uri in the
|
||||
* canonical request in order to pass a signature check.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return whether or not the signing process should perform a uri encode step before creating the
|
||||
* canonical request.
|
||||
*/
|
||||
bool GetUseDoubleUriEncode() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets whether or not the signing process should perform a uri encode step before creating the
|
||||
* canonical request.
|
||||
*/
|
||||
void SetUseDoubleUriEncode(bool useDoubleUriEncode) noexcept;
|
||||
|
||||
/**
|
||||
* @return whether or not the uri paths should be normalized when building the canonical request
|
||||
*/
|
||||
bool GetShouldNormalizeUriPath() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets whether or not the uri paths should be normalized when building the canonical request
|
||||
*/
|
||||
void SetShouldNormalizeUriPath(bool shouldNormalizeUriPath) noexcept;
|
||||
|
||||
/**
|
||||
* @return whether or not to omit the session token during signing. Only set to true when performing
|
||||
* a websocket handshake with IoT Core.
|
||||
*/
|
||||
bool GetOmitSessionToken() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets whether or not to omit the session token during signing. Only set to true when performing
|
||||
* a websocket handshake with IoT Core.
|
||||
*/
|
||||
void SetOmitSessionToken(bool omitSessionToken) noexcept;
|
||||
|
||||
/**
|
||||
* @return the ShouldSignHeadersCb from the underlying config.
|
||||
*/
|
||||
ShouldSignHeaderCb GetShouldSignHeaderCallback() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets a callback invoked during the signing process for white-listing headers that can be signed.
|
||||
* If you do not set this, all headers will be signed.
|
||||
*/
|
||||
void SetShouldSignHeaderCallback(ShouldSignHeaderCb shouldSignHeaderCb) noexcept;
|
||||
|
||||
/**
|
||||
* @return the should_sign_header_ud from the underlying config.
|
||||
*/
|
||||
void *GetShouldSignHeaderUserData() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the userData you could get from the ShouldSignHeaderCb callback function.
|
||||
*/
|
||||
void SetShouldSignHeaderUserData(void *userData) noexcept;
|
||||
|
||||
/**
|
||||
* @return the string used as the canonical request's body value.
|
||||
* If string is empty, a value is be calculated from the payload during signing.
|
||||
*/
|
||||
const Crt::String &GetSignedBodyValue() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the string to use as the canonical request's body value.
|
||||
* If an empty string is set (the default), a value will be calculated from the payload during signing.
|
||||
* Typically, this is the SHA-256 of the (request/chunk/event) payload, written as lowercase hex.
|
||||
* If this has been precalculated, it can be set here.
|
||||
* Special values used by certain services can also be set (see Aws::Crt::Auth::SignedBodyValue).
|
||||
*/
|
||||
void SetSignedBodyValue(const Crt::String &signedBodyValue) noexcept;
|
||||
|
||||
/**
|
||||
* @return the name of the header to add that stores the signed body value
|
||||
*/
|
||||
SignedBodyHeaderType GetSignedBodyHeader() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the name of the header to add that stores the signed body value
|
||||
*/
|
||||
void SetSignedBodyHeader(SignedBodyHeaderType signedBodyHeader) noexcept;
|
||||
|
||||
/**
|
||||
* @return (Query param signing only) Gets the amount of time, in seconds, the (pre)signed URI will be
|
||||
* good for
|
||||
*/
|
||||
uint64_t GetExpirationInSeconds() const noexcept;
|
||||
|
||||
/**
|
||||
* (Query param signing only) Sets the amount of time, in seconds, the (pre)signed URI will be good for
|
||||
*/
|
||||
void SetExpirationInSeconds(uint64_t expirationInSeconds) noexcept;
|
||||
|
||||
/*
|
||||
* For Sigv4 signing, either the credentials provider or the credentials must be set.
|
||||
* Credentials, if set, takes precedence over the provider.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return the credentials provider to use for signing.
|
||||
*/
|
||||
const std::shared_ptr<ICredentialsProvider> &GetCredentialsProvider() const noexcept;
|
||||
|
||||
/**
|
||||
* Set the credentials provider to use for signing.
|
||||
*/
|
||||
void SetCredentialsProvider(const std::shared_ptr<ICredentialsProvider> &credsProvider) noexcept;
|
||||
|
||||
/**
|
||||
* @return the credentials to use for signing.
|
||||
*/
|
||||
const std::shared_ptr<Credentials> &GetCredentials() const noexcept;
|
||||
|
||||
/**
|
||||
* Set the credentials to use for signing.
|
||||
*/
|
||||
void SetCredentials(const std::shared_ptr<Credentials> &credentials) noexcept;
|
||||
|
||||
/// @private
|
||||
const struct aws_signing_config_aws *GetUnderlyingHandle() const noexcept;
|
||||
|
||||
private:
|
||||
Allocator *m_allocator;
|
||||
std::shared_ptr<ICredentialsProvider> m_credentialsProvider;
|
||||
std::shared_ptr<Credentials> m_credentials;
|
||||
struct aws_signing_config_aws m_config;
|
||||
Crt::String m_signingRegion;
|
||||
Crt::String m_serviceName;
|
||||
Crt::String m_signedBodyValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Http request signer that performs Aws Sigv4 signing. Expects the signing configuration to be and
|
||||
* instance of AwsSigningConfig
|
||||
*/
|
||||
class AWS_CRT_CPP_API Sigv4HttpRequestSigner : public IHttpRequestSigner
|
||||
{
|
||||
public:
|
||||
Sigv4HttpRequestSigner(Allocator *allocator = ApiAllocator());
|
||||
virtual ~Sigv4HttpRequestSigner() = default;
|
||||
|
||||
bool IsValid() const override { return true; }
|
||||
|
||||
/**
|
||||
* Signs an http request with AWS-auth sigv4. OnCompletionCallback will be invoked upon completion.
|
||||
*/
|
||||
virtual bool SignRequest(
|
||||
const std::shared_ptr<Aws::Crt::Http::HttpRequest> &request,
|
||||
const ISigningConfig &config,
|
||||
const OnHttpRequestSigningComplete &completionCallback) override;
|
||||
|
||||
private:
|
||||
Allocator *m_allocator;
|
||||
};
|
||||
} // namespace Auth
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
367
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/cbor/Cbor.h
Normal file
367
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/cbor/Cbor.h
Normal file
@@ -0,0 +1,367 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/common/cbor.h>
|
||||
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Cbor
|
||||
{
|
||||
/**
|
||||
* The types used by APIs, not 1:1 with major types.
|
||||
* It's an extension for CBOR major type in RFC8949 section 3.1.
|
||||
* Major type 0 - UInt
|
||||
* Major type 1 - NegInt
|
||||
* Major type 2 - Bytes / IndefBytesStart
|
||||
* Major type 3 - Text / IndefTextStart
|
||||
* Major type 4 - ArrayStart / IndefArrayStart
|
||||
* Major type 5 - MapStart / IndefMapStart
|
||||
* Major type 6 - Tag
|
||||
* Major type 7:
|
||||
* - 20/21 - Bool
|
||||
* - 22 - Null
|
||||
* - 23 - Undefined
|
||||
* - 25/26/27 - Float
|
||||
* - 31 - Break
|
||||
* - Rest of the values are not supported.
|
||||
*/
|
||||
enum class CborType
|
||||
{
|
||||
Unknown = AWS_CBOR_TYPE_UNKNOWN,
|
||||
UInt = AWS_CBOR_TYPE_UINT,
|
||||
NegInt = AWS_CBOR_TYPE_NEGINT,
|
||||
Float = AWS_CBOR_TYPE_FLOAT,
|
||||
Bytes = AWS_CBOR_TYPE_BYTES,
|
||||
Text = AWS_CBOR_TYPE_TEXT,
|
||||
ArrayStart = AWS_CBOR_TYPE_ARRAY_START,
|
||||
MapStart = AWS_CBOR_TYPE_MAP_START,
|
||||
Tag = AWS_CBOR_TYPE_TAG,
|
||||
Bool = AWS_CBOR_TYPE_BOOL,
|
||||
Null = AWS_CBOR_TYPE_NULL,
|
||||
Undefined = AWS_CBOR_TYPE_UNDEFINED,
|
||||
Break = AWS_CBOR_TYPE_BREAK,
|
||||
IndefBytesStart = AWS_CBOR_TYPE_INDEF_BYTES_START,
|
||||
IndefTextStart = AWS_CBOR_TYPE_INDEF_TEXT_START,
|
||||
IndefArrayStart = AWS_CBOR_TYPE_INDEF_ARRAY_START,
|
||||
IndefMapStart = AWS_CBOR_TYPE_INDEF_MAP_START,
|
||||
};
|
||||
|
||||
class AWS_CRT_CPP_API CborEncoder final
|
||||
{
|
||||
public:
|
||||
CborEncoder(const CborEncoder &) = delete;
|
||||
CborEncoder(CborEncoder &&) = delete;
|
||||
CborEncoder &operator=(const CborEncoder &) = delete;
|
||||
CborEncoder &operator=(CborEncoder &&) = delete;
|
||||
|
||||
CborEncoder(Allocator *allocator = ApiAllocator()) noexcept;
|
||||
~CborEncoder() noexcept;
|
||||
|
||||
/**
|
||||
* Get the current encoded data from encoder. The encoded data has the same lifetime as the encoder,
|
||||
* and once any other function call invoked for the encoder, the encoded data is no longer valid.
|
||||
*
|
||||
* @return the current encoded data
|
||||
*/
|
||||
ByteCursor GetEncodedData() noexcept;
|
||||
|
||||
/**
|
||||
* Clear the current encoded buffer from encoder.
|
||||
*/
|
||||
void Reset() noexcept;
|
||||
|
||||
/**
|
||||
* Encode a AWS_CBOR_TYPE_UINT value to "smallest possible" in encoder's buffer.
|
||||
* Referring to RFC8949 section 4.2.1
|
||||
*
|
||||
* @param value value to encode.
|
||||
*/
|
||||
void WriteUInt(uint64_t value) noexcept;
|
||||
|
||||
/**
|
||||
* Encode a AWS_CBOR_TYPE_NEGINT value to "smallest possible" in encoder's buffer.
|
||||
* It represents (-1 - value).
|
||||
* Referring to RFC8949 section 4.2.1
|
||||
*
|
||||
* @param value value to encode, which is (-1 - represented value)
|
||||
*/
|
||||
void WriteNegInt(uint64_t value) noexcept;
|
||||
|
||||
/**
|
||||
* Encode a AWS_CBOR_TYPE_FLOAT value to "smallest possible", but will not be encoded into
|
||||
* half-precision float, as it's not well supported cross languages.
|
||||
*
|
||||
* To be more specific, it will be encoded into integer/negative/float
|
||||
* (Order with priority) when the conversion will not cause precision loss.
|
||||
*
|
||||
* @param value value to encode.
|
||||
*/
|
||||
void WriteFloat(double value) noexcept;
|
||||
|
||||
/**
|
||||
* Encode a Bytes value to "smallest possible" in encoder's buffer.
|
||||
* Referring to RFC8949 section 4.2.1, the length of "value" will be encoded first and then the value of
|
||||
* "value" will be followed.
|
||||
*
|
||||
* @param value value to encode.
|
||||
*/
|
||||
void WriteBytes(ByteCursor value) noexcept;
|
||||
|
||||
/**
|
||||
* Encode a Text value to "smallest possible" in encoder's buffer.
|
||||
* Referring to RFC8949 section 4.2.1, the length of "value" will be encoded first and then the value of
|
||||
* "value" will be followed.
|
||||
*
|
||||
* @param value value to encode.
|
||||
*/
|
||||
void WriteText(ByteCursor value) noexcept;
|
||||
|
||||
/**
|
||||
* Encode an ArrayStart value to "smallest possible" in encoder's buffer.
|
||||
* Referring to RFC8949 section 4.2.1
|
||||
* Notes: it's user's responsibility to keep the integrity of the array to be encoded.
|
||||
*
|
||||
* @param number_entries the number of CBOR data items to be followed as the content of the array.
|
||||
*/
|
||||
void WriteArrayStart(size_t number_entries) noexcept;
|
||||
|
||||
/**
|
||||
* Encode a MapStart value to "smallest possible" in encoder's buffer.
|
||||
* Referring to RFC8949 section 4.2.1
|
||||
*
|
||||
* Notes: it's user's responsibility to keep the integrity of the map to be encoded.
|
||||
*
|
||||
* @param number_entries the number of pair of CBOR data items as key and value to be followed as
|
||||
* the content of the map.
|
||||
*/
|
||||
void WriteMapStart(size_t number_entries) noexcept;
|
||||
|
||||
/**
|
||||
* Encode a Tag value to "smallest possible" in encoder's buffer.
|
||||
* Referring to RFC8949 section 4.2.1
|
||||
* The following CBOR data item will be the content of the tagged value.
|
||||
* Notes: it's user's responsibility to keep the integrity of the tagged value to follow the RFC8949
|
||||
* section 3.4
|
||||
*
|
||||
* @param tag_number The tag value to encode.
|
||||
*/
|
||||
void WriteTag(uint64_t tag_number) noexcept;
|
||||
|
||||
/**
|
||||
* Encode a simple value Null
|
||||
*/
|
||||
void WriteNull() noexcept;
|
||||
|
||||
/**
|
||||
* Encode a simple value Undefined
|
||||
*/
|
||||
void WriteUndefined() noexcept;
|
||||
|
||||
/**
|
||||
* Encode a simple value Bool
|
||||
*/
|
||||
void WriteBool(bool value) noexcept;
|
||||
|
||||
/**
|
||||
* Encode a simple value Break
|
||||
* Notes: no error checking, it's user's responsibility to track the break to close the corresponding
|
||||
* indef_start
|
||||
*/
|
||||
void WriteBreak() noexcept;
|
||||
|
||||
/**
|
||||
* Encode an IndefBytesStart
|
||||
* Notes: no error checking, it's user's responsibility to add corresponding data and the break to close
|
||||
* the indef_start
|
||||
*/
|
||||
void WriteIndefBytesStart() noexcept;
|
||||
|
||||
/**
|
||||
* Encode an IndefTextStart
|
||||
* Notes: no error checking, it's user's responsibility to add corresponding data and the break to close
|
||||
* the indef_start
|
||||
*/
|
||||
void WriteIndefTextStart() noexcept;
|
||||
|
||||
/**
|
||||
* Encode an IndefArrayStart
|
||||
* Notes: no error checking, it's user's responsibility to add corresponding data and the break to close
|
||||
* the indef_start
|
||||
*/
|
||||
void WriteIndefArrayStart() noexcept;
|
||||
|
||||
/**
|
||||
* Encode an IndefMapStart
|
||||
* Notes: no error checking, it's user's responsibility to add corresponding data and the break to close
|
||||
* the indef_start
|
||||
*/
|
||||
void WriteIndefMapStart() noexcept;
|
||||
|
||||
private:
|
||||
struct aws_cbor_encoder *m_encoder;
|
||||
};
|
||||
|
||||
class AWS_CRT_CPP_API CborDecoder final
|
||||
{
|
||||
|
||||
public:
|
||||
CborDecoder(const CborDecoder &) = delete;
|
||||
CborDecoder(CborDecoder &&) = delete;
|
||||
CborDecoder &operator=(const CborDecoder &) = delete;
|
||||
CborDecoder &operator=(CborDecoder &&) = delete;
|
||||
|
||||
/**
|
||||
* Construct a new Cbor Decoder object
|
||||
*
|
||||
* @param allocator
|
||||
* @param src The src data to decode from.
|
||||
*/
|
||||
CborDecoder(ByteCursor src, Allocator *allocator = ApiAllocator()) noexcept;
|
||||
~CborDecoder() noexcept;
|
||||
|
||||
/**
|
||||
* Get the length of the remaining bytes of the source. Once the source was decoded, it will be
|
||||
* consumed, and result in decrease of the remaining length of bytes.
|
||||
*
|
||||
* @return The length of bytes remaining of the decoder source.
|
||||
*/
|
||||
size_t GetRemainingLength() noexcept;
|
||||
|
||||
/**
|
||||
* Decode the next element and store it in the decoder cache if there was no element cached.
|
||||
* If there was an element cached, just return the type of the cached element.
|
||||
*
|
||||
* @return If successful, return the type of next element
|
||||
* If not, return will be none and LastError() can be
|
||||
* used to retrieve CRT error code.
|
||||
*/
|
||||
Optional<CborType> PeekType() noexcept;
|
||||
|
||||
/**
|
||||
* Consume the next data item, includes all the content within the data item.
|
||||
*
|
||||
* As an example for the following CBOR, this function will consume all the data
|
||||
* as it's only one CBOR data item, an indefinite map with 2 key, value pair:
|
||||
* 0xbf6346756ef563416d7421ff
|
||||
* BF -- Start indefinite-length map
|
||||
* 63 -- First key, UTF-8 string length 3
|
||||
* 46756e -- "Fun"
|
||||
* F5 -- First value, true
|
||||
* 63 -- Second key, UTF-8 string length 3
|
||||
* 416d74 -- "Amt"
|
||||
* 21 -- Second value, -2
|
||||
* FF -- "break"
|
||||
*
|
||||
* Notes: this function will not ensure the data item is well-formed.
|
||||
*
|
||||
* @return true if the operation succeed, false otherwise and LastError() will contain the errorCode.
|
||||
*/
|
||||
bool ConsumeNextWholeDataItem() noexcept;
|
||||
|
||||
/**
|
||||
* Consume the next single element, without the content followed by the element.
|
||||
*
|
||||
* As an example for the following CBOR, this function will only consume the
|
||||
* 0xBF, "Start indefinite-length map", not any content of the map represented.
|
||||
* The next element to decode will start from 0x63.
|
||||
* 0xbf6346756ef563416d7421ff
|
||||
* BF -- Start indefinite-length map
|
||||
* 63 -- First key, UTF-8 string length 3
|
||||
* 46756e -- "Fun"
|
||||
* F5 -- First value, true
|
||||
* 63 -- Second key, UTF-8 string length 3
|
||||
* 416d74 -- "Amt"
|
||||
* 21 -- Second value, -2
|
||||
* FF -- "break"
|
||||
*
|
||||
* @return true if the operation succeed, false otherwise and LastError() will contain the errorCode.
|
||||
*/
|
||||
bool ConsumeNextSingleElement() noexcept;
|
||||
|
||||
/**
|
||||
* Get the next element based on the type. If the next element doesn't match the expected type, an error
|
||||
* will be raised. If the next element has already been cached, it will consume the cached item when no
|
||||
* error was returned. Specifically:
|
||||
* - UInt - PopNextUnsignedIntVal
|
||||
* - NegInt - PopNextNegativeIntVal, it represents (-1 - &out)
|
||||
* - Float - PopNextFloatVal
|
||||
* - Bytes - PopNextBytesVal
|
||||
* - Text - PopNextTextVal
|
||||
*
|
||||
* @return If successful, return the next element
|
||||
* If not, return will be none and LastError() can be
|
||||
* used to retrieve CRT error code.
|
||||
*/
|
||||
Optional<uint64_t> PopNextUnsignedIntVal() noexcept;
|
||||
Optional<uint64_t> PopNextNegativeIntVal() noexcept;
|
||||
Optional<double> PopNextFloatVal() noexcept;
|
||||
Optional<bool> PopNextBooleanVal() noexcept;
|
||||
Optional<ByteCursor> PopNextBytesVal() noexcept;
|
||||
Optional<ByteCursor> PopNextTextVal() noexcept;
|
||||
|
||||
/**
|
||||
* Get the next ArrayStart element. Only consume the ArrayStart element and set the size of array to
|
||||
* &out_size, not the content of the array. The next &out_size CBOR data items will be the content of
|
||||
* the array for a valid CBOR data.
|
||||
*
|
||||
* Notes: For indefinite-length, this function will fail with "AWS_ERROR_CBOR_UNEXPECTED_TYPE". The
|
||||
* designed way to handle indefinite-length is:
|
||||
* - Get IndefArrayStart from PeekType
|
||||
* - Call ConsumeNextSingleElement to pop the indefinite-length start.
|
||||
* - Decode the next data item until Break is read.
|
||||
*
|
||||
* @return If successful, return the size of array
|
||||
* If not, return will be none and LastError() can be
|
||||
* used to retrieve CRT error code.
|
||||
*/
|
||||
Optional<uint64_t> PopNextArrayStart() noexcept;
|
||||
|
||||
/**
|
||||
* Get the next MapStart element. Only consume the MapStart element and set the size of array to
|
||||
* &out_size, not the content of the map. The next &out_size pair of CBOR data items as key and value
|
||||
* will be the content of the array for a valid CBOR data.
|
||||
*
|
||||
* Notes: For indefinite-length, this function will fail with "AWS_ERROR_CBOR_UNEXPECTED_TYPE". The
|
||||
* designed way to handle indefinite-length is:
|
||||
* - Get IndefMapStart from PeekType
|
||||
* - Call ConsumeNextSingleElement to pop the indefinite-length start.
|
||||
* - Decode the next data item until Break is read.
|
||||
*
|
||||
* @return If successful, return the size of map
|
||||
* If not, return will be none and LastError() can be
|
||||
* used to retrieve CRT error code.
|
||||
*/
|
||||
Optional<uint64_t> PopNextMapStart() noexcept;
|
||||
|
||||
/**
|
||||
* Get the next Tag element. Only consume the Tag element and set the tag value to out_tag_val,
|
||||
* not the content of the tagged value. The next CBOR data item will be the content of the tagged value
|
||||
* for a valid CBOR data.
|
||||
*
|
||||
* @return If successful, return the tag value
|
||||
* If not, return will be none and LastError() can be
|
||||
* used to retrieve CRT error code.
|
||||
*/
|
||||
Optional<uint64_t> PopNextTagVal() noexcept;
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int LastError() const noexcept { return m_lastError ? m_lastError : AWS_ERROR_UNKNOWN; }
|
||||
|
||||
private:
|
||||
struct aws_cbor_decoder *m_decoder;
|
||||
/* Error */
|
||||
int m_lastError;
|
||||
};
|
||||
} // namespace Cbor
|
||||
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Checksum
|
||||
{
|
||||
/**
|
||||
* The entry point function to perform a CRC32 (Ethernet, gzip) computation.
|
||||
* Selects a suitable implementation based on hardware capabilities.
|
||||
* Pass previousCRC32 if updating a running checksum.
|
||||
*/
|
||||
uint32_t AWS_CRT_CPP_API ComputeCRC32(ByteCursor input, uint32_t previousCRC32 = 0) noexcept;
|
||||
|
||||
/**
|
||||
* The entry point function to perform a Castagnoli CRC32c (iSCSI) computation.
|
||||
* Selects a suitable implementation based on hardware capabilities.
|
||||
* Pass previousCRC32C if updating a running checksum.
|
||||
*/
|
||||
uint32_t AWS_CRT_CPP_API ComputeCRC32C(ByteCursor input, uint32_t previousCRC32C = 0) noexcept;
|
||||
|
||||
/**
|
||||
* The entry point function to perform a CRC64-NVME (a.k.a. CRC64-Rocksoft) computation.
|
||||
* Selects a suitable implementation based on hardware capabilities.
|
||||
* Pass previousCRC64NVME if updating a running checksum.
|
||||
* There are many variants of CRC64 algorithms. This CRC64 variant is bit-reflected (based on
|
||||
* the non bit-reflected polynomial 0xad93d23594c93659) and inverts the CRC input and output bits.
|
||||
*/
|
||||
uint64_t AWS_CRT_CPP_API ComputeCRC64NVME(ByteCursor input, uint64_t previousCRC64NVME = 0) noexcept;
|
||||
} // namespace Checksum
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,168 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/cal/hmac.h>
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
struct aws_hmac;
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Crypto
|
||||
{
|
||||
static const size_t SHA256_HMAC_DIGEST_SIZE = 32;
|
||||
|
||||
/**
|
||||
* Computes a SHA256 HMAC with secret over input, and writes the digest to output. If truncateTo is
|
||||
* non-zero, the digest will be truncated to the value of truncateTo. Returns true on success. If this
|
||||
* function fails, Aws::Crt::LastError() will contain the error that occurred. Unless you're using
|
||||
* 'truncateTo', output should have a minimum capacity of SHA256_HMAC_DIGEST_SIZE.
|
||||
*/
|
||||
bool AWS_CRT_CPP_API ComputeSHA256HMAC(
|
||||
Allocator *allocator,
|
||||
const ByteCursor &secret,
|
||||
const ByteCursor &input,
|
||||
ByteBuf &output,
|
||||
size_t truncateTo = 0) noexcept;
|
||||
|
||||
/**
|
||||
* Computes a SHA256 HMAC using the default allocator with secret over input, and writes the digest to
|
||||
* output. If truncateTo is non-zero, the digest will be truncated to the value of truncateTo. Returns true
|
||||
* on success. If this function fails, Aws::Crt::LastError() will contain the error that occurred. Unless
|
||||
* you're using 'truncateTo', output should have a minimum capacity of SHA256_HMAC_DIGEST_SIZE.
|
||||
*/
|
||||
bool AWS_CRT_CPP_API ComputeSHA256HMAC(
|
||||
const ByteCursor &secret,
|
||||
const ByteCursor &input,
|
||||
ByteBuf &output,
|
||||
size_t truncateTo = 0) noexcept;
|
||||
/**
|
||||
* Streaming HMAC object. The typical use case is for computing the HMAC of an object that is too large to
|
||||
* load into memory. You can call Update() multiple times as you load chunks of data into memory. When
|
||||
* you're finished simply call Digest(). After Digest() is called, this object is no longer usable.
|
||||
*/
|
||||
class AWS_CRT_CPP_API HMAC final
|
||||
{
|
||||
public:
|
||||
~HMAC();
|
||||
HMAC(const HMAC &) = delete;
|
||||
HMAC &operator=(const HMAC &) = delete;
|
||||
HMAC(HMAC &&toMove);
|
||||
HMAC &operator=(HMAC &&toMove);
|
||||
|
||||
/**
|
||||
* Returns true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
inline operator bool() const noexcept { return m_good; }
|
||||
|
||||
/**
|
||||
* Returns the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
inline int LastError() const noexcept { return m_lastError; }
|
||||
|
||||
/**
|
||||
* Creates an instance of a Streaming SHA256 HMAC.
|
||||
*/
|
||||
static HMAC CreateSHA256HMAC(Allocator *allocator, const ByteCursor &secret) noexcept;
|
||||
|
||||
/**
|
||||
* Creates an instance of a Streaming SHA256 HMAC using the Default Allocator.
|
||||
*/
|
||||
static HMAC CreateSHA256HMAC(const ByteCursor &secret) noexcept;
|
||||
|
||||
/**
|
||||
* Updates the running HMAC object with data in toHMAC. Returns true on success. Call
|
||||
* LastError() for the reason this call failed.
|
||||
*/
|
||||
bool Update(const ByteCursor &toHMAC) noexcept;
|
||||
|
||||
/**
|
||||
* Finishes the running HMAC operation and writes the digest into output. The available capacity of
|
||||
* output must be large enough for the digest. See: SHA256_DIGEST_SIZE and MD5_DIGEST_SIZE for size
|
||||
* hints. 'truncateTo' is for if you want truncated output (e.g. you only want the first 16 bytes of a
|
||||
* SHA256 digest. Returns true on success. Call LastError() for the reason this call failed.
|
||||
*/
|
||||
bool Digest(ByteBuf &output, size_t truncateTo = 0) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the size of the digest for this hmac algorithm. If this object is not valid, it will
|
||||
* return 0 instead.
|
||||
*/
|
||||
size_t DigestSize() const noexcept;
|
||||
|
||||
/**
|
||||
* Computes the running HMAC and finishes the running HMAC operation and writes the digest into output.
|
||||
* The available capacity of output must be large enough for the digest.
|
||||
* See: SHA256_DIGEST_SIZE and MD5_DIGEST_SIZE for size
|
||||
* hints. 'truncateTo' is for if you want truncated output (e.g. you only want the first 16 bytes of a
|
||||
* SHA256 HMAC digest. Returns true on success. Call LastError() for the reason this call failed.
|
||||
*
|
||||
* This is an API a user would use for smaller size inputs. For larger, streaming inputs, use
|
||||
* multiple calls to Update() for each buffer, followed by a single call to Digest().
|
||||
*/
|
||||
bool ComputeOneShot(const ByteCursor &input, ByteBuf &output, size_t truncateTo = 0) noexcept;
|
||||
|
||||
private:
|
||||
HMAC(aws_hmac *hmac) noexcept;
|
||||
HMAC() = delete;
|
||||
|
||||
aws_hmac *m_hmac;
|
||||
bool m_good;
|
||||
int m_lastError;
|
||||
};
|
||||
|
||||
/**
|
||||
* BYO_CRYPTO: Base class for custom HMAC implementations.
|
||||
*
|
||||
* If using BYO_CRYPTO, you must define concrete implementations for the required HMAC algorithms
|
||||
* and set their creation callbacks via functions like ApiHandle.SetBYOCryptoNewSHA256HMACCallback().
|
||||
*/
|
||||
class AWS_CRT_CPP_API ByoHMAC
|
||||
{
|
||||
public:
|
||||
virtual ~ByoHMAC() = default;
|
||||
|
||||
/** @private
|
||||
* this is called by the framework. If you're trying to create instances of this class manually,
|
||||
* please don't. But if you do. Look at the other factory functions for reference.
|
||||
*/
|
||||
aws_hmac *SeatForCInterop(const std::shared_ptr<ByoHMAC> &selfRef);
|
||||
|
||||
protected:
|
||||
ByoHMAC(size_t digestSize, const ByteCursor &secret, Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Updates the running HMAC with to_hash.
|
||||
* This can be called multiple times.
|
||||
* Raise an AWS error and return false to indicate failure.
|
||||
*/
|
||||
virtual bool UpdateInternal(const ByteCursor &toHash) noexcept = 0;
|
||||
|
||||
/**
|
||||
* Complete the HMAC computation and write the final digest to output.
|
||||
* This cannote be called more than once.
|
||||
* If truncate_to is something other than 0, the output must be truncated to that number of bytes.
|
||||
* Raise an AWS error and return false to indicate failure.
|
||||
*/
|
||||
virtual bool DigestInternal(ByteBuf &output, size_t truncateTo = 0) noexcept = 0;
|
||||
|
||||
private:
|
||||
static void s_Destroy(struct aws_hmac *hmac);
|
||||
static int s_Update(struct aws_hmac *hmac, const struct aws_byte_cursor *buf);
|
||||
static int s_Finalize(struct aws_hmac *hmac, struct aws_byte_buf *out);
|
||||
|
||||
static aws_hmac_vtable s_Vtable;
|
||||
aws_hmac m_hmacValue;
|
||||
std::shared_ptr<ByoHMAC> m_selfReference;
|
||||
};
|
||||
|
||||
using CreateHMACCallback =
|
||||
std::function<std::shared_ptr<ByoHMAC>(size_t digestSize, const ByteCursor &secret, Allocator *)>;
|
||||
|
||||
} // namespace Crypto
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,212 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
#include <aws/cal/hash.h>
|
||||
|
||||
struct aws_hash;
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Crypto
|
||||
{
|
||||
static const size_t SHA1_DIGEST_SIZE = AWS_SHA1_LEN;
|
||||
static const size_t SHA256_DIGEST_SIZE = AWS_SHA256_LEN;
|
||||
static const size_t MD5_DIGEST_SIZE = AWS_MD5_LEN;
|
||||
|
||||
/**
|
||||
* Computes a SHA256 Hash over input, and writes the digest to output. If truncateTo is non-zero, the digest
|
||||
* will be truncated to the value of truncateTo. Returns true on success. If this function fails,
|
||||
* Aws::Crt::LastError() will contain the error that occurred. Unless you're using 'truncateTo', output
|
||||
* should have a minimum capacity of SHA256_DIGEST_SIZE.
|
||||
*/
|
||||
bool AWS_CRT_CPP_API ComputeSHA256(
|
||||
Allocator *allocator,
|
||||
const ByteCursor &input,
|
||||
ByteBuf &output,
|
||||
size_t truncateTo = 0) noexcept;
|
||||
|
||||
/**
|
||||
* Computes a SHA256 Hash using the default allocator over input, and writes the digest to output. If
|
||||
* truncateTo is non-zero, the digest will be truncated to the value of truncateTo. Returns true on success.
|
||||
* If this function fails, Aws::Crt::LastError() will contain the error that occurred. Unless you're using
|
||||
* 'truncateTo', output should have a minimum capacity of SHA256_DIGEST_SIZE.
|
||||
*/
|
||||
bool AWS_CRT_CPP_API
|
||||
ComputeSHA256(const ByteCursor &input, ByteBuf &output, size_t truncateTo = 0) noexcept;
|
||||
|
||||
/**
|
||||
* Computes a MD5 Hash over input, and writes the digest to output. If truncateTo is non-zero, the digest
|
||||
* will be truncated to the value of truncateTo. Returns true on success. If this function fails,
|
||||
* Aws::Crt::LastError() will contain the error that occurred. Unless you're using 'truncateTo',
|
||||
* output should have a minimum capacity of MD5_DIGEST_SIZE.
|
||||
*/
|
||||
bool AWS_CRT_CPP_API ComputeMD5(
|
||||
Allocator *allocator,
|
||||
const ByteCursor &input,
|
||||
ByteBuf &output,
|
||||
size_t truncateTo = 0) noexcept;
|
||||
|
||||
/**
|
||||
* Computes a MD5 Hash using the default allocator over input, and writes the digest to output. If
|
||||
* truncateTo is non-zero, the digest will be truncated to the value of truncateTo. Returns true on success.
|
||||
* If this function fails, Aws::Crt::LastError() will contain the error that occurred. Unless you're using
|
||||
* 'truncateTo', output should have a minimum capacity of MD5_DIGEST_SIZE.
|
||||
*/
|
||||
bool AWS_CRT_CPP_API ComputeMD5(const ByteCursor &input, ByteBuf &output, size_t truncateTo = 0) noexcept;
|
||||
|
||||
/**
|
||||
* Computes a SHA1 Hash over input, and writes the digest to output. If truncateTo is non-zero, the digest
|
||||
* will be truncated to the value of truncateTo. Returns true on success. If this function fails,
|
||||
* Aws::Crt::LastError() will contain the error that occurred. Unless you're using 'truncateTo',
|
||||
* output should have a minimum capacity of MD5_DIGEST_SIZE.
|
||||
*/
|
||||
bool AWS_CRT_CPP_API ComputeSHA1(
|
||||
Allocator *allocator,
|
||||
const ByteCursor &input,
|
||||
ByteBuf &output,
|
||||
size_t truncateTo = 0) noexcept;
|
||||
|
||||
/**
|
||||
* Computes a SHA1 Hash using the default allocator over input, and writes the digest to output. If
|
||||
* truncateTo is non-zero, the digest will be truncated to the value of truncateTo. Returns true on success.
|
||||
* If this function fails, Aws::Crt::LastError() will contain the error that occurred. Unless you're using
|
||||
* 'truncateTo', output should have a minimum capacity of SHA1_DIGEST_SIZE.
|
||||
*/
|
||||
bool AWS_CRT_CPP_API ComputeSHA1(const ByteCursor &input, ByteBuf &output, size_t truncateTo = 0) noexcept;
|
||||
|
||||
/**
|
||||
* Streaming Hash object. The typical use case is for computing the hash of an object that is too large to
|
||||
* load into memory. You can call Update() multiple times as you load chunks of data into memory. When
|
||||
* you're finished simply call Digest(). After Digest() is called, this object is no longer usable.
|
||||
*/
|
||||
class AWS_CRT_CPP_API Hash final
|
||||
{
|
||||
public:
|
||||
~Hash();
|
||||
Hash(const Hash &) = delete;
|
||||
Hash &operator=(const Hash &) = delete;
|
||||
Hash(Hash &&toMove);
|
||||
Hash &operator=(Hash &&toMove);
|
||||
|
||||
/**
|
||||
* Returns true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
inline int LastError() const noexcept { return m_lastError; }
|
||||
|
||||
/**
|
||||
* Creates an instance of a Streaming SHA256 Hash.
|
||||
*/
|
||||
static Hash CreateSHA256(Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Creates an instance of a Stream SHA1 Hash.
|
||||
*/
|
||||
static Hash CreateSHA1(Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Creates an instance of a Streaming MD5 Hash.
|
||||
*/
|
||||
static Hash CreateMD5(Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Updates the running hash object with data in toHash. Returns true on success. Call
|
||||
* LastError() for the reason this call failed.
|
||||
*/
|
||||
bool Update(const ByteCursor &toHash) noexcept;
|
||||
|
||||
/**
|
||||
* Finishes the running hash operation and writes the digest into output. The available capacity of
|
||||
* output must be large enough for the digest. See: SHA1_DIGEST_SIZE, SHA256_DIGEST_SIZE and
|
||||
* MD5_DIGEST_SIZE for size hints. 'truncateTo' is for if you want truncated output (e.g. you only want
|
||||
* the first 16 bytes of a SHA256 digest. Returns true on success. Call LastError() for the reason this
|
||||
* call failed.
|
||||
*/
|
||||
bool Digest(ByteBuf &output, size_t truncateTo = 0) noexcept;
|
||||
|
||||
/**
|
||||
* Computes the hash of input and writes the digest into output. The available capacity of
|
||||
* output must be large enough for the digest. See: SHA1_DIGEST_SIZE, SHA256_DIGEST_SIZE and
|
||||
* MD5_DIGEST_SIZE for size hints. 'truncateTo' is for if you want truncated output (e.g. you only want
|
||||
* the first 16 bytes of a SHA256 digest. Returns true on success. Call LastError() for the reason this
|
||||
* call failed.
|
||||
*
|
||||
* This is an API a user would use for smaller size inputs. For larger, streaming inputs, use
|
||||
* multiple calls to Update() for each buffer, followed by a single call to Digest().
|
||||
*/
|
||||
bool ComputeOneShot(const ByteCursor &input, ByteBuf &output, size_t truncateTo = 0) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the size of the digest for this hash algorithm. If this object is not valid, it will
|
||||
* return 0 instead.
|
||||
*/
|
||||
size_t DigestSize() const noexcept;
|
||||
|
||||
private:
|
||||
Hash(aws_hash *hash) noexcept;
|
||||
Hash() = delete;
|
||||
|
||||
aws_hash *m_hash;
|
||||
int m_lastError;
|
||||
};
|
||||
|
||||
/**
|
||||
* BYO_CRYPTO: Base class for custom hash implementations.
|
||||
*
|
||||
* If using BYO_CRYPTO, you must define concrete implementations for the required hash algorithms
|
||||
* and set their creation callbacks via functions like ApiHandle.SetBYOCryptoNewMD5Callback().
|
||||
*/
|
||||
class AWS_CRT_CPP_API ByoHash
|
||||
{
|
||||
public:
|
||||
virtual ~ByoHash();
|
||||
|
||||
/** @private
|
||||
* this is called by the framework. If you're trying to create instances of this class manually,
|
||||
* please don't. But if you do. Look at the other factory functions for reference.
|
||||
*/
|
||||
aws_hash *SeatForCInterop(const std::shared_ptr<ByoHash> &selfRef);
|
||||
|
||||
protected:
|
||||
ByoHash(size_t digestSize, Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Update the running hash with to_hash.
|
||||
* This can be called multiple times.
|
||||
* Raise an AWS error and return false to indicate failure.
|
||||
*/
|
||||
virtual bool UpdateInternal(const ByteCursor &toHash) noexcept = 0;
|
||||
|
||||
/**
|
||||
* Complete the hash computation and write the final digest to output.
|
||||
* This cannot be called more than once.
|
||||
* If truncate_to is something other than 0, the output must be truncated to that number of bytes.
|
||||
* Raise an AWS error and return false to indicate failure.
|
||||
*/
|
||||
virtual bool DigestInternal(ByteBuf &output, size_t truncateTo = 0) noexcept = 0;
|
||||
|
||||
private:
|
||||
static void s_Destroy(struct aws_hash *hash);
|
||||
static int s_Update(struct aws_hash *hash, const struct aws_byte_cursor *buf);
|
||||
static int s_Finalize(struct aws_hash *hash, struct aws_byte_buf *out);
|
||||
|
||||
static aws_hash_vtable s_Vtable;
|
||||
aws_hash m_hashValue;
|
||||
std::shared_ptr<ByoHash> m_selfReference;
|
||||
};
|
||||
|
||||
using CreateHashCallback = std::function<std::shared_ptr<ByoHash>(size_t digestSize, Allocator *)>;
|
||||
|
||||
} // namespace Crypto
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Crypto
|
||||
{
|
||||
bool AWS_CRT_CPP_API GenerateRandomBytes(ByteBuf &output, size_t lengthToGenerate);
|
||||
}
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,166 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/cal/symmetric_cipher.h>
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
struct aws_symmetric_cipher;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Crypto
|
||||
{
|
||||
static const size_t AES_256_CIPHER_BLOCK_SIZE = 16u;
|
||||
static const size_t AES_256_KEY_SIZE_BYTES = 32u;
|
||||
|
||||
enum class SymmetricCipherState
|
||||
{
|
||||
Ready = AWS_SYMMETRIC_CIPHER_READY,
|
||||
Finalized = AWS_SYMMETRIC_CIPHER_FINALIZED,
|
||||
Error = AWS_SYMMETRIC_CIPHER_ERROR,
|
||||
};
|
||||
|
||||
class AWS_CRT_CPP_API SymmetricCipher final
|
||||
{
|
||||
public:
|
||||
SymmetricCipher(const SymmetricCipher &) = delete;
|
||||
SymmetricCipher &operator=(const SymmetricCipher &) = delete;
|
||||
SymmetricCipher(SymmetricCipher &&) noexcept = default;
|
||||
SymmetricCipher &operator=(SymmetricCipher &&) noexcept = default;
|
||||
|
||||
/**
|
||||
* Creates an AES 256 CBC mode cipher using a provided key and iv.
|
||||
* Key must be 32 bytes. If key or iv are not provided, they will be generated.
|
||||
*/
|
||||
static SymmetricCipher CreateAES_256_CBC_Cipher(
|
||||
const Optional<ByteCursor> &key = Optional<ByteCursor>(),
|
||||
const Optional<ByteCursor> &iv = Optional<ByteCursor>(),
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Creates an AES 256 CTR mode cipher using a provided key and iv.
|
||||
* If key and iv are not provided, they will be generated.
|
||||
*/
|
||||
static SymmetricCipher CreateAES_256_CTR_Cipher(
|
||||
const Optional<ByteCursor> &key = Optional<ByteCursor>(),
|
||||
const Optional<ByteCursor> &iv = Optional<ByteCursor>(),
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Creates an AES 256 GCM mode cipher using a provided key, iv, tag, and aad if provided.
|
||||
* Key and iv will be generated if not provided.
|
||||
* AAD values are not generated.
|
||||
* Provide AAD if you need to provide additional auth info.
|
||||
*/
|
||||
static SymmetricCipher CreateAES_256_GCM_Cipher(
|
||||
const Optional<ByteCursor> &key = Optional<ByteCursor>(),
|
||||
const Optional<ByteCursor> &iv = Optional<ByteCursor>(),
|
||||
const Optional<ByteCursor> &aad = Optional<ByteCursor>(),
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Creates an AES 256 Keywrap mode cipher using key if provided.
|
||||
* If a key is not provided, one will be generated.
|
||||
*/
|
||||
static SymmetricCipher CreateAES_256_KeyWrap_Cipher(
|
||||
const Optional<ByteCursor> &key = Optional<ByteCursor>(),
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Returns true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const noexcept;
|
||||
|
||||
/**
|
||||
* Returns current state of the cipher instance. ready to be used, finalized, or in a error state.
|
||||
* If the cipher is in a finalized or error state it may not be used anymore
|
||||
**/
|
||||
SymmetricCipherState GetState() const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
inline int LastError() const noexcept { return m_lastError; }
|
||||
|
||||
/**
|
||||
* Encrypts the value in toEncrypt and stores any immediate results in out. Out can be dynamically
|
||||
* re-sized if out is a dynamic byte buf. Otherwise, make sure the size of out is at least 2 blocks
|
||||
* larger than the input to allow for padding.
|
||||
*
|
||||
* Returns true on success. Call
|
||||
* LastError() for the reason this call failed.
|
||||
*/
|
||||
bool Encrypt(const ByteCursor &toEncrypt, ByteBuf &out) noexcept;
|
||||
|
||||
/**
|
||||
* Encrypts any remaining data on the cipher and stores the output in out. Out can be dynamically
|
||||
* re-sized if out is a dynamic byte buf. Otherwise, make sure the size of out is at least 2 blocks
|
||||
* for CBC, CTR, and GCM modes and 40 bytes for KeyWrap.
|
||||
*
|
||||
* Returns true on success. Call
|
||||
* LastError() for the reason this call failed.
|
||||
*/
|
||||
bool FinalizeEncryption(ByteBuf &out) noexcept;
|
||||
|
||||
/**
|
||||
* Decrypts the value in toEncrypt and stores any immediate results in out. Out can be dynamically
|
||||
* re-sized if out is a dynamic byte buf. Otherwise, make sure the size of out is at least 1 block
|
||||
* larger than the input to allow for padding. Returns true on success. Call LastError() for the reason
|
||||
* this call failed.
|
||||
*/
|
||||
bool Decrypt(const ByteCursor &toDecrypt, ByteBuf &out) noexcept;
|
||||
|
||||
/**
|
||||
* Decrypts any remaining data on the cipher and stores the output in out. Out can be dynamically
|
||||
* re-sized if out is a dynamic byte buf. Otherwise, make sure the size of out is at least 2 blocks
|
||||
* for CBC, CTR, GCM, and Keywrap modes.
|
||||
*
|
||||
* Returns true on success. Call
|
||||
* LastError() for the reason this call failed.
|
||||
*/
|
||||
bool FinalizeDecryption(ByteBuf &out) noexcept;
|
||||
|
||||
/**
|
||||
* Reset to cipher to new state.
|
||||
*/
|
||||
bool Reset() noexcept;
|
||||
|
||||
/**
|
||||
* Returns the key used for this cipher. This key is not copied from the cipher so do not mutate this
|
||||
* data. Copy if you need to pass it around anywhere.
|
||||
*/
|
||||
ByteCursor GetKey() const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the initialization vector used for this cipher.
|
||||
* This IV is not copied from the cipher so do not mutate this
|
||||
* data. Copy if you need to pass it around anywhere.
|
||||
*/
|
||||
ByteCursor GetIV() const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the encryption tag generated during encryption operations for this cipher in GCM mode.
|
||||
* This tag is not copied from the cipher so do not mutate this
|
||||
* data. Copy if you need to pass it around anywhere.
|
||||
*/
|
||||
ByteCursor GetTag() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the tag used during decryption operations for this cipher in GCM mode.
|
||||
* No-op outside of GCM mode. In GCM mode, encrypt operation overrides the value of the tag.
|
||||
*/
|
||||
void SetTag(ByteCursor tag) const noexcept;
|
||||
|
||||
private:
|
||||
SymmetricCipher(aws_symmetric_cipher *cipher) noexcept;
|
||||
ScopedResource<struct aws_symmetric_cipher> m_cipher;
|
||||
int m_lastError;
|
||||
};
|
||||
} // namespace Crypto
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,162 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
struct aws_endpoints_rule_engine;
|
||||
struct aws_endpoints_request_context;
|
||||
struct aws_endpoints_resolved_endpoint;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Endpoints
|
||||
{
|
||||
/*
|
||||
* Add parameter to the context.
|
||||
* Only string and boolean values are supported.
|
||||
* Adding parameter several times with the same name will overwrite
|
||||
* previous values.
|
||||
*/
|
||||
class AWS_CRT_CPP_API RequestContext final
|
||||
{
|
||||
public:
|
||||
RequestContext(Allocator *allocator = ApiAllocator()) noexcept;
|
||||
~RequestContext();
|
||||
|
||||
/* TODO: move/copy semantics */
|
||||
RequestContext(const RequestContext &) = delete;
|
||||
RequestContext &operator=(const RequestContext &) = delete;
|
||||
RequestContext(RequestContext &&) = delete;
|
||||
RequestContext &operator=(RequestContext &&) = delete;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const noexcept { return m_requestContext != nullptr; }
|
||||
|
||||
/*
|
||||
* Add string parameter.
|
||||
* True if added successfully and false if failed.
|
||||
* Aws::Crt::LastError() can be used to retrieve failure error code.
|
||||
*/
|
||||
bool AddString(const ByteCursor &name, const ByteCursor &value);
|
||||
|
||||
/*
|
||||
* Add boolean parameter.
|
||||
* True if added successfully and false if failed.
|
||||
* Aws::Crt::LastError() can be used to retrieve failure error code.
|
||||
*/
|
||||
bool AddBoolean(const ByteCursor &name, bool value);
|
||||
|
||||
/*
|
||||
* Add string array parameter.
|
||||
* True if added successfully and false if failed.
|
||||
* Aws::Crt::LastError() can be used to retrieve failure error code.
|
||||
*/
|
||||
bool AddStringArray(const ByteCursor &name, const Vector<ByteCursor> &value);
|
||||
|
||||
/// @private
|
||||
aws_endpoints_request_context *GetNativeHandle() const noexcept { return m_requestContext; }
|
||||
|
||||
private:
|
||||
Allocator *m_allocator;
|
||||
aws_endpoints_request_context *m_requestContext;
|
||||
};
|
||||
|
||||
/*
|
||||
* Outcome of Endpoint Resolution.
|
||||
* Outcome can be either endpoint (IsEndpoint) or error (IsError).
|
||||
* Endpoint outcome means that engine was able to resolve context to
|
||||
* an endpoint and outcome can have the following fields defined:
|
||||
* - Url (required) - resolved url
|
||||
* - Headers (optional) - additional headers to be included with request
|
||||
* - Properties (optional) - custom list of properties associated
|
||||
* with request (json blob to be interpreted by the caller.)
|
||||
*
|
||||
* Error outcome means that context could not be resolved to an endpoint.
|
||||
* Outcome will have following fields:
|
||||
* - Error (required) - error message providing more info on why
|
||||
* endpoint could not be resolved.
|
||||
*/
|
||||
class AWS_CRT_CPP_API ResolutionOutcome final
|
||||
{
|
||||
public:
|
||||
~ResolutionOutcome();
|
||||
|
||||
/* TODO: move/copy semantics */
|
||||
ResolutionOutcome(const ResolutionOutcome &) = delete;
|
||||
ResolutionOutcome &operator=(const ResolutionOutcome &) = delete;
|
||||
ResolutionOutcome(ResolutionOutcome &&toMove) noexcept;
|
||||
ResolutionOutcome &operator=(ResolutionOutcome &&);
|
||||
|
||||
bool IsEndpoint() const noexcept;
|
||||
bool IsError() const noexcept;
|
||||
|
||||
/*
|
||||
* Endpoint properties.
|
||||
* Note: following fields are none if outcome is error.
|
||||
* Headers and Properties are optional and could also be None.
|
||||
*/
|
||||
Optional<StringView> GetUrl() const;
|
||||
Optional<StringView> GetProperties() const;
|
||||
Optional<UnorderedMap<StringView, Vector<StringView>>> GetHeaders() const;
|
||||
|
||||
/*
|
||||
* Error properties.
|
||||
* Note: following fields are none if outcome is error.
|
||||
*/
|
||||
Optional<StringView> GetError() const;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const noexcept { return m_resolvedEndpoint != nullptr; }
|
||||
|
||||
/// @private For use by rule engine.
|
||||
ResolutionOutcome(aws_endpoints_resolved_endpoint *impl);
|
||||
|
||||
private:
|
||||
aws_endpoints_resolved_endpoint *m_resolvedEndpoint;
|
||||
};
|
||||
|
||||
/**
|
||||
* Endpoints Rule Engine.
|
||||
*/
|
||||
class AWS_CRT_CPP_API RuleEngine final
|
||||
{
|
||||
public:
|
||||
RuleEngine(
|
||||
const ByteCursor &rulesetCursor,
|
||||
const ByteCursor &partitionsCursor,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
~RuleEngine();
|
||||
|
||||
RuleEngine(const RuleEngine &) = delete;
|
||||
RuleEngine &operator=(const RuleEngine &) = delete;
|
||||
RuleEngine(RuleEngine &&) = delete;
|
||||
RuleEngine &operator=(RuleEngine &&) = delete;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const noexcept { return m_ruleEngine != nullptr; }
|
||||
|
||||
/*
|
||||
* Resolves rules against the provided context.
|
||||
* If successful return will have resolution outcome.
|
||||
* If not, return will be none and Aws::Crt::LastError() can be
|
||||
* used to retrieve CRT error code.
|
||||
*/
|
||||
Optional<ResolutionOutcome> Resolve(const RequestContext &context) const;
|
||||
|
||||
private:
|
||||
aws_endpoints_rule_engine *m_ruleEngine;
|
||||
};
|
||||
} // namespace Endpoints
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,514 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/http/connection.h>
|
||||
#include <aws/http/proxy.h>
|
||||
#include <aws/http/request_response.h>
|
||||
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/crt/io/Bootstrap.h>
|
||||
#include <aws/crt/io/SocketOptions.h>
|
||||
#include <aws/crt/io/TlsOptions.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
class ClientBootstrap;
|
||||
}
|
||||
|
||||
namespace Http
|
||||
{
|
||||
class HttpClientConnection;
|
||||
class HttpStream;
|
||||
class HttpClientStream;
|
||||
class HttpRequest;
|
||||
class HttpProxyStrategy;
|
||||
using HttpHeader = aws_http_header;
|
||||
|
||||
/**
|
||||
* Invoked upon connection setup, whether it was successful or not. If the connection was
|
||||
* successfully established, `connection` will be valid and errorCode will be AWS_ERROR_SUCCESS.
|
||||
* Upon an error, `connection` will not be valid, and errorCode will contain the cause of the connection
|
||||
* failure.
|
||||
*/
|
||||
using OnConnectionSetup =
|
||||
std::function<void(const std::shared_ptr<HttpClientConnection> &connection, int errorCode)>;
|
||||
|
||||
/**
|
||||
* Invoked upon connection shutdown. `connection` will always be a valid pointer. `errorCode` will specify
|
||||
* shutdown reason. A graceful connection close will set `errorCode` to AWS_ERROR_SUCCESS.
|
||||
* Internally, the connection pointer will be unreferenced immediately after this call; if you took a
|
||||
* reference to it in OnConnectionSetup(), you'll need to release your reference before the underlying
|
||||
* memory is released. If you never took a reference to it, the resources for the connection will be
|
||||
* immediately released after completion of this callback.
|
||||
*/
|
||||
using OnConnectionShutdown = std::function<void(HttpClientConnection &connection, int errorCode)>;
|
||||
|
||||
/**
|
||||
* Called as headers are received from the peer. `headersArray` will contain the header value
|
||||
* read from the wire. The number of entries in `headersArray` are specified in `headersCount`.
|
||||
*
|
||||
* Keep in mind that this function will likely be called multiple times until all headers are received.
|
||||
*
|
||||
* On HttpStream, this function must be set.
|
||||
*/
|
||||
using OnIncomingHeaders = std::function<void(
|
||||
HttpStream &stream,
|
||||
enum aws_http_header_block headerBlock,
|
||||
const HttpHeader *headersArray,
|
||||
std::size_t headersCount)>;
|
||||
|
||||
/**
|
||||
* Invoked when the headers portion of the message has been completely received. `hasBody` will indicate
|
||||
* if there is an incoming body.
|
||||
*
|
||||
* On HttpStream, this function can be empty.
|
||||
*/
|
||||
using OnIncomingHeadersBlockDone =
|
||||
std::function<void(HttpStream &stream, enum aws_http_header_block block)>;
|
||||
|
||||
/**
|
||||
* Invoked as chunks of the body are read. `data` contains the data read from the wire. If chunked encoding
|
||||
* was used, it will already be decoded (TBD).
|
||||
*
|
||||
* On HttpStream, this function can be empty if you are not expecting a body (e.g. a HEAD request).
|
||||
*/
|
||||
using OnIncomingBody = std::function<void(HttpStream &stream, const ByteCursor &data)>;
|
||||
|
||||
/**
|
||||
* Invoked upon completion of the stream. This means the request has been sent and a completed response
|
||||
* has been received (in client mode), or the request has been received and the response has been completed.
|
||||
*
|
||||
* In H2, this will mean RST_STREAM state has been reached for the stream.
|
||||
*
|
||||
* On HttpStream, this function must be set.
|
||||
*/
|
||||
using OnStreamComplete = std::function<void(HttpStream &stream, int errorCode)>;
|
||||
|
||||
/**
|
||||
* POD structure used for setting up an Http Request
|
||||
*/
|
||||
struct AWS_CRT_CPP_API HttpRequestOptions
|
||||
{
|
||||
/**
|
||||
* The actual http request
|
||||
*/
|
||||
HttpRequest *request;
|
||||
|
||||
/**
|
||||
* See `OnIncomingHeaders` for more info. This value must be set.
|
||||
*/
|
||||
OnIncomingHeaders onIncomingHeaders;
|
||||
OnIncomingHeadersBlockDone onIncomingHeadersBlockDone;
|
||||
|
||||
/**
|
||||
* See `OnIncomingBody` for more info. This value can be empty if you will not be receiving a body.
|
||||
*/
|
||||
OnIncomingBody onIncomingBody;
|
||||
|
||||
/**
|
||||
* See `OnStreamComplete` for more info. This value can be empty.
|
||||
*/
|
||||
OnStreamComplete onStreamComplete;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a single http message exchange (request/response) or in H2, it can also represent
|
||||
* a PUSH_PROMISE followed by the accompanying Response.
|
||||
*/
|
||||
class AWS_CRT_CPP_API HttpStream : public std::enable_shared_from_this<HttpStream>
|
||||
{
|
||||
public:
|
||||
virtual ~HttpStream();
|
||||
HttpStream(const HttpStream &) = delete;
|
||||
HttpStream(HttpStream &&) = delete;
|
||||
HttpStream &operator=(const HttpStream &) = delete;
|
||||
HttpStream &operator=(HttpStream &&) = delete;
|
||||
|
||||
/**
|
||||
* Get the underlying connection for the stream.
|
||||
*/
|
||||
HttpClientConnection &GetConnection() const noexcept;
|
||||
|
||||
/**
|
||||
* @return request's Http Response Code. Requires response headers to have been processed first. *
|
||||
*/
|
||||
virtual int GetResponseStatusCode() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Updates the read window on the connection. In Http 1.1 this relieves TCP back pressure, in H2
|
||||
* this will trigger two WINDOW_UPDATE frames, one for the connection and one for the stream.
|
||||
*
|
||||
* You do not need to call this unless you utilized the `outWindowUpdateSize` in `OnIncomingBody`.
|
||||
* See `OnIncomingBody` for more information.
|
||||
*
|
||||
* `incrementSize` is the amount to update the read window by.
|
||||
*/
|
||||
void UpdateWindow(std::size_t incrementSize) noexcept;
|
||||
|
||||
protected:
|
||||
aws_http_stream *m_stream;
|
||||
std::shared_ptr<HttpClientConnection> m_connection;
|
||||
HttpStream(const std::shared_ptr<HttpClientConnection> &connection) noexcept;
|
||||
|
||||
private:
|
||||
OnIncomingHeaders m_onIncomingHeaders;
|
||||
OnIncomingHeadersBlockDone m_onIncomingHeadersBlockDone;
|
||||
OnIncomingBody m_onIncomingBody;
|
||||
OnStreamComplete m_onStreamComplete;
|
||||
|
||||
static int s_onIncomingHeaders(
|
||||
struct aws_http_stream *stream,
|
||||
enum aws_http_header_block headerBlock,
|
||||
const struct aws_http_header *headerArray,
|
||||
size_t numHeaders,
|
||||
void *userData) noexcept;
|
||||
static int s_onIncomingHeaderBlockDone(
|
||||
struct aws_http_stream *stream,
|
||||
enum aws_http_header_block headerBlock,
|
||||
void *userData) noexcept;
|
||||
static int s_onIncomingBody(
|
||||
struct aws_http_stream *stream,
|
||||
const struct aws_byte_cursor *data,
|
||||
void *userData) noexcept;
|
||||
static void s_onStreamComplete(struct aws_http_stream *stream, int errorCode, void *userData) noexcept;
|
||||
|
||||
friend class HttpClientConnection;
|
||||
};
|
||||
|
||||
struct ClientStreamCallbackData
|
||||
{
|
||||
ClientStreamCallbackData() : allocator(nullptr), stream(nullptr) {}
|
||||
Allocator *allocator;
|
||||
std::shared_ptr<HttpStream> stream;
|
||||
};
|
||||
|
||||
/**
|
||||
* Subclass that represents an http client's view of an HttpStream.
|
||||
*/
|
||||
class AWS_CRT_CPP_API HttpClientStream final : public HttpStream
|
||||
{
|
||||
public:
|
||||
~HttpClientStream();
|
||||
HttpClientStream(const HttpClientStream &) = delete;
|
||||
HttpClientStream(HttpClientStream &&) = delete;
|
||||
HttpClientStream &operator=(const HttpClientStream &) = delete;
|
||||
HttpClientStream &operator=(HttpClientStream &&) = delete;
|
||||
|
||||
/**
|
||||
* If this stream was initiated as a request, assuming the headers of the response has been
|
||||
* received, this value contains the Http Response Code. *
|
||||
*/
|
||||
virtual int GetResponseStatusCode() const noexcept override;
|
||||
|
||||
/**
|
||||
* Activates the request's outgoing stream processing.
|
||||
*
|
||||
* Returns true on success, false otherwise.
|
||||
*/
|
||||
bool Activate() noexcept;
|
||||
|
||||
private:
|
||||
HttpClientStream(const std::shared_ptr<HttpClientConnection> &connection) noexcept;
|
||||
|
||||
ClientStreamCallbackData m_callbackData;
|
||||
friend class HttpClientConnection;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated enum that designates what kind of authentication, if any, to use when connecting to a
|
||||
* proxy server.
|
||||
*
|
||||
* Here for backwards compatibility. Has been superceded by proxy strategies.
|
||||
*/
|
||||
enum class AwsHttpProxyAuthenticationType
|
||||
{
|
||||
None,
|
||||
Basic,
|
||||
};
|
||||
|
||||
/**
|
||||
* Mirror of aws_http_proxy_connection_type enum. Indicates the basic http proxy behavior of the
|
||||
* proxy we're connecting to.
|
||||
*/
|
||||
enum class AwsHttpProxyConnectionType
|
||||
{
|
||||
/**
|
||||
* Deprecated, but 0-valued for backwards compatibility
|
||||
*
|
||||
* If tls options are provided (for the main connection) then treat the proxy as a tunneling proxy
|
||||
* If tls options are not provided (for the main connection), then treat the proxy as a forwarding
|
||||
* proxy
|
||||
*/
|
||||
Legacy = AWS_HPCT_HTTP_LEGACY,
|
||||
|
||||
/**
|
||||
* Use the proxy to forward http requests. Attempting to use both this mode and TLS to the destination
|
||||
* is a configuration error.
|
||||
*/
|
||||
Forwarding = AWS_HPCT_HTTP_FORWARD,
|
||||
|
||||
/**
|
||||
* Use the proxy to establish an http connection via a CONNECT request to the proxy. Works for both
|
||||
* plaintext and tls connections.
|
||||
*/
|
||||
Tunneling = AWS_HPCT_HTTP_TUNNEL,
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration structure that holds all proxy-related http connection options
|
||||
*/
|
||||
class AWS_CRT_CPP_API HttpClientConnectionProxyOptions
|
||||
{
|
||||
public:
|
||||
HttpClientConnectionProxyOptions();
|
||||
HttpClientConnectionProxyOptions(const HttpClientConnectionProxyOptions &rhs) = default;
|
||||
HttpClientConnectionProxyOptions(HttpClientConnectionProxyOptions &&rhs) = default;
|
||||
|
||||
HttpClientConnectionProxyOptions &operator=(const HttpClientConnectionProxyOptions &rhs) = default;
|
||||
HttpClientConnectionProxyOptions &operator=(HttpClientConnectionProxyOptions &&rhs) = default;
|
||||
|
||||
~HttpClientConnectionProxyOptions() = default;
|
||||
|
||||
/**
|
||||
* Intended for internal use only. Initializes the C proxy configuration structure,
|
||||
* aws_http_proxy_options, from an HttpClientConnectionProxyOptions instance.
|
||||
*
|
||||
* @param raw_options - output parameter containing low level proxy options to be passed to the C
|
||||
* interface
|
||||
*
|
||||
*/
|
||||
void InitializeRawProxyOptions(struct aws_http_proxy_options &raw_options) const;
|
||||
|
||||
/**
|
||||
* The name of the proxy server to connect through.
|
||||
* Required.
|
||||
*/
|
||||
String HostName;
|
||||
|
||||
/**
|
||||
* The port of the proxy server to connect to.
|
||||
* Required.
|
||||
*/
|
||||
uint32_t Port;
|
||||
|
||||
/**
|
||||
* Sets the TLS options for the connection to the proxy.
|
||||
* Optional.
|
||||
*/
|
||||
Optional<Io::TlsConnectionOptions> TlsOptions;
|
||||
|
||||
/**
|
||||
* What kind of proxy connection to make
|
||||
*/
|
||||
AwsHttpProxyConnectionType ProxyConnectionType;
|
||||
|
||||
/**
|
||||
* Proxy strategy to use while negotiating the connection. Use null for no additional
|
||||
* steps.
|
||||
*/
|
||||
std::shared_ptr<HttpProxyStrategy> ProxyStrategy;
|
||||
|
||||
/**
|
||||
* @deprecated What kind of authentication approach to use when connecting to the proxy
|
||||
* Replaced by proxy strategy
|
||||
*
|
||||
* Backwards compatibility achieved by invoking CreateBasicHttpProxyStrategy if
|
||||
* (1) ProxyStrategy is null
|
||||
* (2) AuthType is AwsHttpProxyAuthenticationType::Basic
|
||||
*/
|
||||
AwsHttpProxyAuthenticationType AuthType;
|
||||
|
||||
/**
|
||||
* @deprecated The username to use if connecting to the proxy via basic authentication
|
||||
* Replaced by using the result of CreateBasicHttpProxyStrategy()
|
||||
*/
|
||||
String BasicAuthUsername;
|
||||
|
||||
/**
|
||||
* @deprecated The password to use if connecting to the proxy via basic authentication
|
||||
* Replaced by using the result of CreateBasicHttpProxyStrategy()
|
||||
*/
|
||||
String BasicAuthPassword;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration structure holding all options relating to http connection establishment
|
||||
*/
|
||||
class AWS_CRT_CPP_API HttpClientConnectionOptions
|
||||
{
|
||||
public:
|
||||
HttpClientConnectionOptions();
|
||||
HttpClientConnectionOptions(const HttpClientConnectionOptions &rhs) = default;
|
||||
HttpClientConnectionOptions(HttpClientConnectionOptions &&rhs) = default;
|
||||
|
||||
~HttpClientConnectionOptions() = default;
|
||||
|
||||
HttpClientConnectionOptions &operator=(const HttpClientConnectionOptions &rhs) = default;
|
||||
HttpClientConnectionOptions &operator=(HttpClientConnectionOptions &&rhs) = default;
|
||||
|
||||
/**
|
||||
* The client bootstrap to use for setting up and tearing down connections.
|
||||
* Note: If null, then the default ClientBootstrap is used
|
||||
* (see Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap)
|
||||
*/
|
||||
Io::ClientBootstrap *Bootstrap;
|
||||
|
||||
/**
|
||||
* The TCP read window allowed for Http 1.1 connections and Initial Windows for H2 connections.
|
||||
*/
|
||||
size_t InitialWindowSize;
|
||||
|
||||
/**
|
||||
* The callback invoked on connection establishment, whether success or failure.
|
||||
* See `OnConnectionSetup` for more info.
|
||||
* Required.
|
||||
*/
|
||||
OnConnectionSetup OnConnectionSetupCallback;
|
||||
|
||||
/**
|
||||
* The callback invoked on connection shutdown.
|
||||
* See `OnConnectionShutdown` for more info.
|
||||
* Required.
|
||||
*/
|
||||
OnConnectionShutdown OnConnectionShutdownCallback;
|
||||
|
||||
/**
|
||||
* The name of the http server to connect to.
|
||||
* Required.
|
||||
*/
|
||||
String HostName;
|
||||
|
||||
/**
|
||||
* The port of the http server to connect to.
|
||||
* Required.
|
||||
*/
|
||||
uint32_t Port;
|
||||
|
||||
/**
|
||||
* The socket options of the connection.
|
||||
* Required.
|
||||
*/
|
||||
Io::SocketOptions SocketOptions;
|
||||
|
||||
/**
|
||||
* The TLS options for the http connection.
|
||||
* Optional.
|
||||
*/
|
||||
Optional<Io::TlsConnectionOptions> TlsOptions;
|
||||
|
||||
/**
|
||||
* The proxy options for the http connection.
|
||||
* Optional.
|
||||
*/
|
||||
Optional<HttpClientConnectionProxyOptions> ProxyOptions;
|
||||
|
||||
/**
|
||||
* If set to true, then the TCP read back pressure mechanism will be enabled. You should
|
||||
* only use this if you're allowing http response body data to escape the callbacks. E.g. you're
|
||||
* putting the data into a queue for another thread to process and need to make sure the memory
|
||||
* usage is bounded. If this is enabled, you must call HttpStream::UpdateWindow() for every
|
||||
* byte read from the OnIncomingBody callback.
|
||||
*/
|
||||
bool ManualWindowManagement;
|
||||
};
|
||||
|
||||
enum class HttpVersion
|
||||
{
|
||||
Unknown = AWS_HTTP_VERSION_UNKNOWN,
|
||||
Http1_0 = AWS_HTTP_VERSION_1_0,
|
||||
Http1_1 = AWS_HTTP_VERSION_1_1,
|
||||
Http2 = AWS_HTTP_VERSION_2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a connection from a Http Client to a Server.
|
||||
*/
|
||||
class AWS_CRT_CPP_API HttpClientConnection : public std::enable_shared_from_this<HttpClientConnection>
|
||||
{
|
||||
public:
|
||||
virtual ~HttpClientConnection() = default;
|
||||
HttpClientConnection(const HttpClientConnection &) = delete;
|
||||
HttpClientConnection(HttpClientConnection &&) = delete;
|
||||
HttpClientConnection &operator=(const HttpClientConnection &) = delete;
|
||||
HttpClientConnection &operator=(HttpClientConnection &&) = delete;
|
||||
|
||||
/**
|
||||
* Make a new client initiated request on this connection.
|
||||
*
|
||||
* If you take a reference to the return value, the memory and resources for the connection
|
||||
* and stream will not be cleaned up until you release it. You can however, release the reference
|
||||
* as soon as you don't need it anymore. The internal reference count ensures the resources will
|
||||
* not be freed until the stream is completed.
|
||||
*
|
||||
* Returns an instance of HttpStream upon success and nullptr on failure.
|
||||
*
|
||||
* You must call HttpClientStream::Activate() to begin outgoing processing of the stream.
|
||||
*/
|
||||
std::shared_ptr<HttpClientStream> NewClientStream(const HttpRequestOptions &requestOptions) noexcept;
|
||||
|
||||
/**
|
||||
* @return true unless the connection is closed or closing.
|
||||
*/
|
||||
bool IsOpen() const noexcept;
|
||||
|
||||
/**
|
||||
* Initiate a shutdown of the connection. Sometimes, connections are persistent and you want
|
||||
* to close them before shutting down your application or whatever is consuming this interface.
|
||||
*
|
||||
* Assuming `OnConnectionShutdown` has not already been invoked, it will be invoked as a result of this
|
||||
* call.
|
||||
*/
|
||||
void Close() noexcept;
|
||||
|
||||
/**
|
||||
* @return protocol version the connection used
|
||||
*/
|
||||
HttpVersion GetVersion() noexcept;
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int LastError() const noexcept { return m_lastError; }
|
||||
|
||||
/**
|
||||
* Create a new Https Connection to hostName:port, using `socketOptions` for tcp options and
|
||||
* `tlsConnOptions` for TLS/SSL options. If `tlsConnOptions` is null http (plain-text) will be used.
|
||||
*
|
||||
* returns true on success, and false on failure. If false is returned, `onConnectionSetup` will not
|
||||
* be invoked. On success, `onConnectionSetup` will be called, either with a connection, or an
|
||||
* errorCode.
|
||||
*/
|
||||
static bool CreateConnection(
|
||||
const HttpClientConnectionOptions &connectionOptions,
|
||||
Allocator *allocator) noexcept;
|
||||
|
||||
protected:
|
||||
HttpClientConnection(aws_http_connection *m_connection, Allocator *allocator) noexcept;
|
||||
aws_http_connection *m_connection;
|
||||
|
||||
private:
|
||||
Allocator *m_allocator;
|
||||
int m_lastError;
|
||||
|
||||
static void s_onClientConnectionSetup(
|
||||
struct aws_http_connection *connection,
|
||||
int error_code,
|
||||
void *user_data) noexcept;
|
||||
static void s_onClientConnectionShutdown(
|
||||
struct aws_http_connection *connection,
|
||||
int error_code,
|
||||
void *user_data) noexcept;
|
||||
};
|
||||
|
||||
} // namespace Http
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/http/HttpConnection.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <future>
|
||||
#include <mutex>
|
||||
|
||||
struct aws_http_connection_manager;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Http
|
||||
{
|
||||
/**
|
||||
* Invoked when a connection from the pool is available. If a connection was successfully obtained
|
||||
* the connection shared_ptr can be seated into your own copy of connection. If it failed, errorCode
|
||||
* will be non-zero.
|
||||
*/
|
||||
using OnClientConnectionAvailable =
|
||||
std::function<void(std::shared_ptr<HttpClientConnection>, int errorCode)>;
|
||||
|
||||
/**
|
||||
* Configuration struct containing all options related to connection manager behavior
|
||||
*/
|
||||
class AWS_CRT_CPP_API HttpClientConnectionManagerOptions
|
||||
{
|
||||
public:
|
||||
HttpClientConnectionManagerOptions() noexcept;
|
||||
HttpClientConnectionManagerOptions(const HttpClientConnectionManagerOptions &rhs) = default;
|
||||
HttpClientConnectionManagerOptions(HttpClientConnectionManagerOptions &&rhs) = default;
|
||||
|
||||
HttpClientConnectionManagerOptions &operator=(const HttpClientConnectionManagerOptions &rhs) = default;
|
||||
HttpClientConnectionManagerOptions &operator=(HttpClientConnectionManagerOptions &&rhs) = default;
|
||||
|
||||
/**
|
||||
* The http connection options to use for each connection created by the manager
|
||||
*/
|
||||
HttpClientConnectionOptions ConnectionOptions;
|
||||
|
||||
/**
|
||||
* The maximum number of connections the manager is allowed to create/manage
|
||||
*/
|
||||
size_t MaxConnections;
|
||||
|
||||
/** If set, initiate shutdown will return a future that will allow a user to block until the
|
||||
* connection manager has completely released all resources. This isn't necessary during the normal
|
||||
* flow of an application, but it is useful for scenarios, such as tests, that need deterministic
|
||||
* shutdown ordering. Be aware, if you use this anywhere other than the main thread, you will most
|
||||
* likely cause a deadlock. If this is set, you MUST call InitiateShutdown() before releasing your last
|
||||
* reference to the connection manager.
|
||||
*/
|
||||
bool EnableBlockingShutdown;
|
||||
};
|
||||
|
||||
/**
|
||||
* Manages a pool of connections to a specific endpoint using the same socket and tls options.
|
||||
*/
|
||||
class AWS_CRT_CPP_API HttpClientConnectionManager final
|
||||
: public std::enable_shared_from_this<HttpClientConnectionManager>
|
||||
{
|
||||
public:
|
||||
~HttpClientConnectionManager();
|
||||
|
||||
/**
|
||||
* Acquires a connection from the pool. onClientConnectionAvailable will be invoked upon an available
|
||||
* connection. Returns true if the connection request was successfully queued, returns false if it
|
||||
* failed. On failure, onClientConnectionAvailable will not be invoked. After receiving a connection, it
|
||||
* will automatically be cleaned up when your last reference to the shared_ptr is released.
|
||||
*
|
||||
* @param onClientConnectionAvailable callback to invoke when a connection becomes available or the
|
||||
* acquisition attempt terminates
|
||||
* @return true if the acquisition was successfully kicked off, false otherwise (no callback)
|
||||
*/
|
||||
bool AcquireConnection(const OnClientConnectionAvailable &onClientConnectionAvailable) noexcept;
|
||||
|
||||
/**
|
||||
* Starts shutdown of the connection manager. Returns a future to the connection manager's shutdown
|
||||
* process. If EnableBlockingDestruct was enabled on the connection manager options, calling get() on
|
||||
* the returned future will block until the last connection is released. If the option is not set, get()
|
||||
* will immediately return.
|
||||
* @return future which will complete when shutdown has completed
|
||||
*/
|
||||
std::future<void> InitiateShutdown() noexcept;
|
||||
|
||||
/**
|
||||
* Factory function for connection managers
|
||||
*
|
||||
* @param connectionManagerOptions connection manager configuration data
|
||||
* @param allocator allocator to use
|
||||
* @return a new connection manager instance
|
||||
*/
|
||||
static std::shared_ptr<HttpClientConnectionManager> NewClientConnectionManager(
|
||||
const HttpClientConnectionManagerOptions &connectionManagerOptions,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
private:
|
||||
HttpClientConnectionManager(
|
||||
const HttpClientConnectionManagerOptions &options,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
Allocator *m_allocator;
|
||||
|
||||
aws_http_connection_manager *m_connectionManager;
|
||||
|
||||
HttpClientConnectionManagerOptions m_options;
|
||||
std::promise<void> m_shutdownPromise;
|
||||
std::atomic<bool> m_releaseInvoked;
|
||||
|
||||
static void s_onConnectionSetup(
|
||||
aws_http_connection *connection,
|
||||
int errorCode,
|
||||
void *userData) noexcept;
|
||||
|
||||
static void s_shutdownCompleted(void *userData) noexcept;
|
||||
|
||||
friend class ManagedConnection;
|
||||
};
|
||||
} // namespace Http
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,116 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
struct aws_http_proxy_strategy;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Http
|
||||
{
|
||||
enum class AwsHttpProxyConnectionType;
|
||||
|
||||
/**
|
||||
* Configuration for a proxy strategy that performs basic authentication
|
||||
*/
|
||||
struct AWS_CRT_CPP_API HttpProxyStrategyBasicAuthConfig
|
||||
{
|
||||
HttpProxyStrategyBasicAuthConfig();
|
||||
|
||||
/**
|
||||
* Basic auth can be applied either to forwarding or tunneling proxy connections, but we need
|
||||
* to know the type ahead of time
|
||||
*/
|
||||
AwsHttpProxyConnectionType ConnectionType;
|
||||
|
||||
/**
|
||||
* Username to apply to the basic authentication process
|
||||
*/
|
||||
String Username;
|
||||
|
||||
/**
|
||||
* Password to apply to the basic authentication process
|
||||
*/
|
||||
String Password;
|
||||
};
|
||||
|
||||
using KerberosGetTokenFunction = std::function<bool(String &)>;
|
||||
using NtlmGetTokenFunction = std::function<bool(const String &, String &)>;
|
||||
|
||||
/**
|
||||
* Configuration for a proxy strategy that attempts to use kerberos and ntlm, based on authentication
|
||||
* failure feedback from the proxy's responses to CONNECT attempts. The kerberos/ntlm callbacks are
|
||||
* currently synchronous but invoked potentially from within event loop threads. This is not optimal
|
||||
* but transitioning to fully async hasn't been a need yet.
|
||||
*
|
||||
* The adapative strategy will skip an authentication method whose callbacks are not supplied, so you
|
||||
* can use this for purely kerberos or ntlm as well.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API HttpProxyStrategyAdaptiveConfig
|
||||
{
|
||||
HttpProxyStrategyAdaptiveConfig() : KerberosGetToken(), NtlmGetCredential(), NtlmGetToken() {}
|
||||
|
||||
/**
|
||||
* User-supplied callback for fetching kerberos tokens
|
||||
*/
|
||||
KerberosGetTokenFunction KerberosGetToken;
|
||||
|
||||
/**
|
||||
* User-supplied callback for fetching an ntlm credential
|
||||
*/
|
||||
KerberosGetTokenFunction NtlmGetCredential;
|
||||
|
||||
/**
|
||||
* User-supplied callback for fetching an ntlm token
|
||||
*/
|
||||
NtlmGetTokenFunction NtlmGetToken;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wrapper class for a C-level proxy strategy - an object that allows the user to transform or modify
|
||||
* the authentication logic when connecting to a proxy.
|
||||
*/
|
||||
class AWS_CRT_CPP_API HttpProxyStrategy
|
||||
{
|
||||
public:
|
||||
HttpProxyStrategy(struct aws_http_proxy_strategy *strategy);
|
||||
virtual ~HttpProxyStrategy();
|
||||
|
||||
/// @private
|
||||
struct aws_http_proxy_strategy *GetUnderlyingHandle() const noexcept { return m_strategy; }
|
||||
|
||||
/**
|
||||
* Creates a proxy strategy that performs basic authentication
|
||||
* @param config basic authentication configuration options
|
||||
* @param allocator allocator to use
|
||||
* @return a new basic authentication proxy strategy
|
||||
*/
|
||||
static std::shared_ptr<HttpProxyStrategy> CreateBasicHttpProxyStrategy(
|
||||
const HttpProxyStrategyBasicAuthConfig &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Creates a proxy strategy that, depending on configuration, can attempt kerberos and/or ntlm
|
||||
* authentication when connecting to the proxy
|
||||
* @param config the adaptive strategy configuration options
|
||||
* @param allocator allocator to use
|
||||
* @return a new adaptive proxy strategy
|
||||
*/
|
||||
static std::shared_ptr<HttpProxyStrategy> CreateAdaptiveHttpProxyStrategy(
|
||||
const HttpProxyStrategyAdaptiveConfig &config,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
protected:
|
||||
struct aws_http_proxy_strategy *m_strategy;
|
||||
};
|
||||
} // namespace Http
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,161 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/crt/io/Stream.h>
|
||||
|
||||
struct aws_http_header;
|
||||
struct aws_http_message;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Mqtt
|
||||
{
|
||||
class MqttConnection;
|
||||
class MqttConnectionCore;
|
||||
} // namespace Mqtt
|
||||
namespace Mqtt5
|
||||
{
|
||||
class Mqtt5ClientCore;
|
||||
}
|
||||
namespace Http
|
||||
{
|
||||
using HttpHeader = aws_http_header;
|
||||
|
||||
/**
|
||||
* Base class representing a mutable http request or response.
|
||||
*/
|
||||
class AWS_CRT_CPP_API HttpMessage
|
||||
{
|
||||
public:
|
||||
virtual ~HttpMessage();
|
||||
|
||||
HttpMessage(const HttpMessage &) = delete;
|
||||
HttpMessage(HttpMessage &&) = delete;
|
||||
HttpMessage &operator=(const HttpMessage &) = delete;
|
||||
HttpMessage &operator=(HttpMessage &&) = delete;
|
||||
|
||||
/**
|
||||
* Gets the input stream representing the message body
|
||||
*/
|
||||
std::shared_ptr<Aws::Crt::Io::InputStream> GetBody() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the input stream representing the message body
|
||||
* @param body the input stream representing the message body
|
||||
* @return success/failure
|
||||
*/
|
||||
bool SetBody(const std::shared_ptr<Aws::Crt::Io::IStream> &body) noexcept;
|
||||
|
||||
/**
|
||||
* Sets the input stream representing the message body
|
||||
* @param body the input stream representing the message body
|
||||
* @return success/failure
|
||||
*/
|
||||
bool SetBody(const std::shared_ptr<Aws::Crt::Io::InputStream> &body) noexcept;
|
||||
|
||||
/**
|
||||
* Gets the number of headers contained in this request
|
||||
* @return the number of headers contained in this request
|
||||
*/
|
||||
size_t GetHeaderCount() const noexcept;
|
||||
|
||||
/**
|
||||
* Gets a particular header in the request
|
||||
* @param index index of the header to fetch
|
||||
* @return an option containing the requested header if the index is in bounds
|
||||
*/
|
||||
Optional<HttpHeader> GetHeader(size_t index) const noexcept;
|
||||
|
||||
/**
|
||||
* Adds a header to the request
|
||||
* @param header header to add
|
||||
* @return success/failure
|
||||
*/
|
||||
bool AddHeader(const HttpHeader &header) noexcept;
|
||||
|
||||
/**
|
||||
* Removes a header from the request
|
||||
* @param index index of the header to remove
|
||||
* @return success/failure
|
||||
*/
|
||||
bool EraseHeader(size_t index) noexcept;
|
||||
|
||||
/**
|
||||
* @return true/false if the underlying object is valid
|
||||
*/
|
||||
operator bool() const noexcept { return m_message != nullptr; }
|
||||
|
||||
/// @private
|
||||
struct aws_http_message *GetUnderlyingMessage() const noexcept { return m_message; }
|
||||
|
||||
protected:
|
||||
HttpMessage(Allocator *allocator, struct aws_http_message *message) noexcept;
|
||||
|
||||
Allocator *m_allocator;
|
||||
struct aws_http_message *m_message;
|
||||
std::shared_ptr<Aws::Crt::Io::InputStream> m_bodyStream;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class representing a mutable http request.
|
||||
*/
|
||||
class AWS_CRT_CPP_API HttpRequest : public HttpMessage
|
||||
{
|
||||
friend class Mqtt::MqttConnectionCore;
|
||||
friend class Mqtt5::Mqtt5ClientCore;
|
||||
|
||||
public:
|
||||
HttpRequest(Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* @return the value of the Http method associated with this request
|
||||
*/
|
||||
Optional<ByteCursor> GetMethod() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the value of the Http method associated with this request
|
||||
*/
|
||||
bool SetMethod(ByteCursor method) noexcept;
|
||||
|
||||
/**
|
||||
* @return the value of the URI-path associated with this request
|
||||
*/
|
||||
Optional<ByteCursor> GetPath() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the value of the URI-path associated with this request
|
||||
*/
|
||||
bool SetPath(ByteCursor path) noexcept;
|
||||
|
||||
protected:
|
||||
HttpRequest(Allocator *allocator, struct aws_http_message *message);
|
||||
};
|
||||
|
||||
/**
|
||||
* Class representing a mutable http response.
|
||||
*/
|
||||
class AWS_CRT_CPP_API HttpResponse : public HttpMessage
|
||||
{
|
||||
public:
|
||||
HttpResponse(Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* @return the integral Http response code associated with this response
|
||||
*/
|
||||
Optional<int> GetResponseCode() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the integral Http response code associated with this response
|
||||
*/
|
||||
bool SetResponseCode(int response) noexcept;
|
||||
};
|
||||
} // namespace Http
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,104 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/crt/io/EventLoopGroup.h>
|
||||
#include <aws/crt/io/HostResolver.h>
|
||||
|
||||
#include <aws/io/channel_bootstrap.h>
|
||||
#include <aws/io/host_resolver.h>
|
||||
|
||||
#include <future>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
using OnClientBootstrapShutdownComplete = std::function<void()>;
|
||||
|
||||
/**
|
||||
* A ClientBootstrap handles creation and setup of socket connections
|
||||
* to specific endpoints.
|
||||
*
|
||||
* Note that ClientBootstrap may not clean up all its behind-the-scenes
|
||||
* resources immediately upon destruction. If you need to know when
|
||||
* behind-the-scenes shutdown is complete, use SetShutdownCompleteCallback()
|
||||
* or EnableBlockingShutdown() (only safe on main thread).
|
||||
*/
|
||||
class AWS_CRT_CPP_API ClientBootstrap final
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param elGroup: EventLoopGroup to use.
|
||||
* @param resolver: DNS host resolver to use.
|
||||
* @param allocator memory allocator to use
|
||||
*/
|
||||
ClientBootstrap(
|
||||
EventLoopGroup &elGroup,
|
||||
HostResolver &resolver,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Uses the default EventLoopGroup and HostResolver.
|
||||
* See Aws::Crt::ApiHandle::GetOrCreateStaticDefaultEventLoopGroup
|
||||
* and Aws::Crt::ApiHandle::GetOrCreateStaticDefaultHostResolver
|
||||
*/
|
||||
ClientBootstrap(Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
~ClientBootstrap();
|
||||
ClientBootstrap(const ClientBootstrap &) = delete;
|
||||
ClientBootstrap &operator=(const ClientBootstrap &) = delete;
|
||||
ClientBootstrap(ClientBootstrap &&) = delete;
|
||||
ClientBootstrap &operator=(ClientBootstrap &&) = delete;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const noexcept;
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int LastError() const noexcept;
|
||||
|
||||
/**
|
||||
* Set function to invoke when ClientBootstrap's behind-the-scenes
|
||||
* resources finish shutting down. This function may be invoked
|
||||
* on any thread. Shutdown begins when the ClientBootstrap's
|
||||
* destructor runs.
|
||||
*/
|
||||
void SetShutdownCompleteCallback(OnClientBootstrapShutdownComplete callback);
|
||||
|
||||
/**
|
||||
* Force the ClientBootstrap's destructor to block until all
|
||||
* behind-the-scenes resources finish shutting down.
|
||||
*
|
||||
* This isn't necessary during the normal flow of an application,
|
||||
* but it is useful for scenarios, such as tests, that need deterministic
|
||||
* shutdown ordering. Be aware, if you use this anywhere other
|
||||
* than the main thread, YOU WILL MOST LIKELY CAUSE A DEADLOCK.
|
||||
*
|
||||
* Use SetShutdownCompleteCallback() for a thread-safe way to
|
||||
* know when shutdown is complete.
|
||||
*/
|
||||
void EnableBlockingShutdown() noexcept;
|
||||
|
||||
/// @private
|
||||
aws_client_bootstrap *GetUnderlyingHandle() const noexcept;
|
||||
|
||||
private:
|
||||
aws_client_bootstrap *m_bootstrap;
|
||||
int m_lastError;
|
||||
std::unique_ptr<class ClientBootstrapCallbackData> m_callbackData;
|
||||
std::future<void> m_shutdownFuture;
|
||||
bool m_enableBlockingShutdown;
|
||||
};
|
||||
} // namespace Io
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,238 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/io/channel.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
|
||||
struct aws_array_list;
|
||||
struct aws_io_message;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
enum class ChannelDirection
|
||||
{
|
||||
Read,
|
||||
Write,
|
||||
};
|
||||
|
||||
enum class MessageType
|
||||
{
|
||||
ApplicationData,
|
||||
};
|
||||
|
||||
enum class TaskStatus
|
||||
{
|
||||
RunReady,
|
||||
Canceled,
|
||||
};
|
||||
|
||||
/**
|
||||
* Wrapper for aws-c-io channel handlers. The semantics are identical as the functions on
|
||||
* aws_channel_handler.
|
||||
*
|
||||
* All virtual calls are made from the same thread (the channel's thread).
|
||||
*/
|
||||
class AWS_CRT_CPP_API ChannelHandler
|
||||
{
|
||||
public:
|
||||
virtual ~ChannelHandler() = default;
|
||||
|
||||
ChannelHandler(const ChannelHandler &) = delete;
|
||||
ChannelHandler &operator=(const ChannelHandler &) = delete;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Called by the channel when a message is available for processing in the read direction. It is your
|
||||
* responsibility to call aws_mem_release(message->allocator, message); on message when you are finished
|
||||
* with it.
|
||||
*
|
||||
* Also keep in mind that your slot's internal window has been decremented. You'll want to call
|
||||
* aws_channel_slot_increment_read_window() at some point in the future if you want to keep receiving
|
||||
* data.
|
||||
*
|
||||
* @return AWS_OP_SUCCESS if the message is being processed.
|
||||
* If the message cannot be processed raise an error and return AWS_OP_ERR
|
||||
* and do NOT release the message, it will be released by the caller.
|
||||
*/
|
||||
virtual int ProcessReadMessage(struct aws_io_message *message) = 0;
|
||||
|
||||
/**
|
||||
* Called by the channel when a message is available for processing in the write direction. It is your
|
||||
* responsibility to call aws_mem_release(message->allocator, message); on message when you are finished
|
||||
* with it.
|
||||
*
|
||||
* @return AWS_OP_SUCCESS if the message is being processed.
|
||||
* If the message cannot be processed raise an error and return AWS_OP_ERR
|
||||
* and do NOT release the message, it will be released by the caller.
|
||||
*/
|
||||
virtual int ProcessWriteMessage(struct aws_io_message *message) = 0;
|
||||
|
||||
/**
|
||||
* Called by the channel when a downstream handler has issued a window increment. You'll want to update
|
||||
* your internal state and likely propagate a window increment message of your own by calling
|
||||
* IncrementUpstreamReadWindow()
|
||||
*
|
||||
* @return AWS_OP_SUCCESS if successful.
|
||||
* Otherwise, raise an error and return AWS_OP_ERR.
|
||||
*/
|
||||
virtual int IncrementReadWindow(size_t size) = 0;
|
||||
|
||||
/**
|
||||
* The channel calls shutdown on all handlers twice, once to shut down reading, and once to shut down
|
||||
* writing. Shutdown always begins with the left-most handler, and proceeds to the right with dir set to
|
||||
* ChannelDirection::Read. Then shutdown is called on handlers from right to left with dir set to
|
||||
* ChannelDirection::Write.
|
||||
*
|
||||
* The shutdown process does not need to complete immediately and may rely on scheduled tasks.
|
||||
* The handler MUST call OnShutdownComplete() when it is finished,
|
||||
* which propagates shutdown to the next handler. If 'freeScarceResourcesImmediately' is true,
|
||||
* then resources vulnerable to denial-of-service attacks (such as sockets and file handles)
|
||||
* must be closed immediately before the shutdown process complete.
|
||||
*/
|
||||
virtual void ProcessShutdown(
|
||||
ChannelDirection dir,
|
||||
int errorCode,
|
||||
bool freeScarceResourcesImmediately) = 0;
|
||||
|
||||
/**
|
||||
* Called by the channel when the handler is added to a slot, to get the initial window size.
|
||||
*/
|
||||
virtual size_t InitialWindowSize() = 0;
|
||||
|
||||
/**
|
||||
* Called by the channel anytime a handler is added or removed, provides a hint for downstream
|
||||
* handlers to avoid message fragmentation due to message overhead.
|
||||
*/
|
||||
virtual size_t MessageOverhead() = 0;
|
||||
|
||||
/**
|
||||
* Directs the channel handler to reset all of the internal statistics it tracks about itself.
|
||||
*/
|
||||
virtual void ResetStatistics() {};
|
||||
|
||||
/**
|
||||
* Adds a pointer to the handler's internal statistics (if they exist) to a list of statistics
|
||||
* structures associated with the channel's handler chain.
|
||||
*/
|
||||
virtual void GatherStatistics(struct aws_array_list *) {}
|
||||
|
||||
public:
|
||||
/// @private
|
||||
struct aws_channel_handler *SeatForCInterop(const std::shared_ptr<ChannelHandler> &selfRef);
|
||||
|
||||
/**
|
||||
* Return whether the caller is on the same thread as the handler's channel.
|
||||
*/
|
||||
bool ChannelsThreadIsCallersThread() const;
|
||||
|
||||
/**
|
||||
* Initiate a shutdown of the handler's channel.
|
||||
*
|
||||
* If the channel is already shutting down, this call has no effect.
|
||||
*/
|
||||
void ShutDownChannel(int errorCode);
|
||||
|
||||
/**
|
||||
* Schedule a task to run on the next "tick" of the event loop.
|
||||
* If the channel is completely shut down, the task will run with the 'Canceled' status.
|
||||
*/
|
||||
void ScheduleTask(std::function<void(TaskStatus)> &&task);
|
||||
|
||||
/**
|
||||
* Schedule a task to run after a desired length of time has passed.
|
||||
* The task will run with the 'Canceled' status if the channel completes shutdown
|
||||
* before that length of time elapses.
|
||||
*/
|
||||
void ScheduleTask(std::function<void(TaskStatus)> &&task, std::chrono::nanoseconds run_in);
|
||||
|
||||
protected:
|
||||
ChannelHandler(Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Acquire an aws_io_message from the channel's pool.
|
||||
*/
|
||||
struct aws_io_message *AcquireMessageFromPool(MessageType messageType, size_t sizeHint);
|
||||
|
||||
/**
|
||||
* Convenience function that invokes AcquireMessageFromPool(),
|
||||
* asking for the largest reasonable DATA message that can be sent in the write direction,
|
||||
* with upstream overhead accounted for.
|
||||
*/
|
||||
struct aws_io_message *AcquireMaxSizeMessageForWrite();
|
||||
|
||||
/**
|
||||
* Send a message in the read or write direction.
|
||||
* Returns true if message successfully sent.
|
||||
* If false is returned, you must release the message yourself.
|
||||
*/
|
||||
bool SendMessage(struct aws_io_message *message, ChannelDirection direction);
|
||||
|
||||
/**
|
||||
* Issue a window update notification upstream.
|
||||
* Returns true if successful.
|
||||
*/
|
||||
bool IncrementUpstreamReadWindow(size_t windowUpdateSize);
|
||||
|
||||
/**
|
||||
* Must be called by a handler once they have finished their shutdown in the 'dir' direction.
|
||||
* Propagates the shutdown process to the next handler in the channel.
|
||||
*/
|
||||
void OnShutdownComplete(ChannelDirection direction, int errorCode, bool freeScarceResourcesImmediately);
|
||||
|
||||
/**
|
||||
* Fetches the downstream read window.
|
||||
* This gives you the information necessary to honor the read window.
|
||||
* If you call send_message() and it exceeds this window, the message will be rejected.
|
||||
*/
|
||||
size_t DownstreamReadWindow() const;
|
||||
|
||||
/**
|
||||
* Fetches the current overhead of upstream handlers.
|
||||
* This provides a hint to avoid fragmentation if you care.
|
||||
*/
|
||||
size_t UpstreamMessageOverhead() const;
|
||||
|
||||
struct aws_channel_slot *GetSlot() const;
|
||||
|
||||
struct aws_channel_handler m_handler;
|
||||
Allocator *m_allocator;
|
||||
|
||||
private:
|
||||
std::shared_ptr<ChannelHandler> m_selfReference;
|
||||
static struct aws_channel_handler_vtable s_vtable;
|
||||
|
||||
static void s_Destroy(struct aws_channel_handler *handler);
|
||||
static int s_ProcessReadMessage(
|
||||
struct aws_channel_handler *,
|
||||
struct aws_channel_slot *,
|
||||
struct aws_io_message *);
|
||||
static int s_ProcessWriteMessage(
|
||||
struct aws_channel_handler *,
|
||||
struct aws_channel_slot *,
|
||||
struct aws_io_message *);
|
||||
static int s_IncrementReadWindow(struct aws_channel_handler *, struct aws_channel_slot *, size_t size);
|
||||
static int s_ProcessShutdown(
|
||||
struct aws_channel_handler *,
|
||||
struct aws_channel_slot *,
|
||||
enum aws_channel_direction,
|
||||
int errorCode,
|
||||
bool freeScarceResourcesImmediately);
|
||||
static size_t s_InitialWindowSize(struct aws_channel_handler *);
|
||||
static size_t s_MessageOverhead(struct aws_channel_handler *);
|
||||
static void s_ResetStatistics(struct aws_channel_handler *);
|
||||
static void s_GatherStatistics(struct aws_channel_handler *, struct aws_array_list *statsList);
|
||||
};
|
||||
} // namespace Io
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
#include <aws/io/event_loop.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
/**
|
||||
* A collection of event loops.
|
||||
*
|
||||
* An event-loop is a thread for doing async work, such as I/O. Classes that need to do async work will ask
|
||||
* the EventLoopGroup for an event-loop to use.
|
||||
*
|
||||
* The number of threads used depends on your use-case. IF you
|
||||
* have a maximum of less than a few hundred connections 1 thread is the ideal
|
||||
* threadCount.
|
||||
*
|
||||
* There should only be one instance of an EventLoopGroup per application and it
|
||||
* should be passed to all network clients. One exception to this is if you
|
||||
* want to peg different types of IO to different threads. In that case, you
|
||||
* may want to have one event loop group dedicated to one IO activity and another
|
||||
* dedicated to another type.
|
||||
*/
|
||||
class AWS_CRT_CPP_API EventLoopGroup final
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param threadCount: The number of event-loops to create, default will be 0, which will create one for
|
||||
* each processor on the machine.
|
||||
* @param allocator memory allocator to use.
|
||||
*/
|
||||
EventLoopGroup(uint16_t threadCount = 0, Allocator *allocator = ApiAllocator()) noexcept;
|
||||
/**
|
||||
* @param cpuGroup: The CPU group (e.g. NUMA nodes) that all hardware threads are pinned to.
|
||||
* @param threadCount: The number of event-loops to create, default will be 0, which will create one for
|
||||
* each processor on the machine.
|
||||
* @param allocator memory allocator to use.
|
||||
*/
|
||||
EventLoopGroup(uint16_t cpuGroup, uint16_t threadCount, Allocator *allocator = ApiAllocator()) noexcept;
|
||||
~EventLoopGroup();
|
||||
EventLoopGroup(const EventLoopGroup &) = delete;
|
||||
EventLoopGroup(EventLoopGroup &&) noexcept;
|
||||
EventLoopGroup &operator=(const EventLoopGroup &) = delete;
|
||||
EventLoopGroup &operator=(EventLoopGroup &&) noexcept;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const;
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int LastError() const;
|
||||
|
||||
/// @private
|
||||
aws_event_loop_group *GetUnderlyingHandle() noexcept;
|
||||
|
||||
private:
|
||||
aws_event_loop_group *m_eventLoopGroup;
|
||||
int m_lastError;
|
||||
};
|
||||
} // namespace Io
|
||||
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,123 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
#include <aws/io/host_resolver.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
class EventLoopGroup;
|
||||
class HostResolver;
|
||||
|
||||
using HostAddress = aws_host_address;
|
||||
|
||||
/**
|
||||
* Invoked upon resolution of an address. You do not own the memory pointed to in addresses, if you persist
|
||||
* the data, copy it first. If errorCode is AWS_ERROR_SUCCESS, the operation succeeded. Otherwise, the
|
||||
* operation failed.
|
||||
*/
|
||||
using OnHostResolved =
|
||||
std::function<void(HostResolver &resolver, const Vector<HostAddress> &addresses, int errorCode)>;
|
||||
|
||||
/**
|
||||
* Simple interface for DNS name lookup implementations
|
||||
*/
|
||||
class AWS_CRT_CPP_API HostResolver
|
||||
{
|
||||
public:
|
||||
virtual ~HostResolver();
|
||||
virtual bool ResolveHost(const String &host, const OnHostResolved &onResolved) noexcept = 0;
|
||||
|
||||
/// @private
|
||||
virtual aws_host_resolver *GetUnderlyingHandle() noexcept = 0;
|
||||
/// @private
|
||||
virtual aws_host_resolution_config *GetConfig() noexcept = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A wrapper around the CRT default host resolution system that uses getaddrinfo() farmed off
|
||||
* to separate threads in order to resolve names.
|
||||
*/
|
||||
class AWS_CRT_CPP_API DefaultHostResolver final : public HostResolver
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Resolves DNS addresses.
|
||||
*
|
||||
* @param elGroup: EventLoopGroup to use.
|
||||
* @param maxHosts: the number of unique hosts to maintain in the cache.
|
||||
* @param maxTTL: how long to keep an address in the cache before evicting it.
|
||||
* @param allocator memory allocator to use.
|
||||
*/
|
||||
DefaultHostResolver(
|
||||
EventLoopGroup &elGroup,
|
||||
size_t maxHosts,
|
||||
size_t maxTTL,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Resolves DNS addresses using the default EventLoopGroup.
|
||||
*
|
||||
* For more information on the default EventLoopGroup see
|
||||
* Aws::Crt::ApiHandle::GetOrCreateStaticDefaultEventLoopGroup
|
||||
*
|
||||
* @param maxHosts: the number of unique hosts to maintain in the cache.
|
||||
* @param maxTTL: how long to keep an address in the cache before evicting it.
|
||||
* @param allocator memory allocator to use.
|
||||
*/
|
||||
DefaultHostResolver(size_t maxHosts, size_t maxTTL, Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
~DefaultHostResolver();
|
||||
DefaultHostResolver(const DefaultHostResolver &) = delete;
|
||||
DefaultHostResolver &operator=(const DefaultHostResolver &) = delete;
|
||||
DefaultHostResolver(DefaultHostResolver &&) = delete;
|
||||
DefaultHostResolver &operator=(DefaultHostResolver &&) = delete;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const noexcept { return m_initialized; }
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int LastError() const noexcept { return aws_last_error(); }
|
||||
|
||||
/**
|
||||
* Kicks off an asynchronous resolution of host. onResolved will be invoked upon completion of the
|
||||
* resolution.
|
||||
* @return False, the resolution was not attempted. True, onResolved will be
|
||||
* called with the result.
|
||||
*/
|
||||
bool ResolveHost(const String &host, const OnHostResolved &onResolved) noexcept override;
|
||||
|
||||
/// @private
|
||||
aws_host_resolver *GetUnderlyingHandle() noexcept override { return m_resolver; }
|
||||
/// @private
|
||||
aws_host_resolution_config *GetConfig() noexcept override { return &m_config; }
|
||||
|
||||
private:
|
||||
aws_host_resolver *m_resolver;
|
||||
aws_host_resolution_config m_config;
|
||||
Allocator *m_allocator;
|
||||
bool m_initialized;
|
||||
|
||||
static void s_onHostResolved(
|
||||
struct aws_host_resolver *resolver,
|
||||
const struct aws_string *host_name,
|
||||
int err_code,
|
||||
const struct aws_array_list *host_addresses,
|
||||
void *user_data);
|
||||
};
|
||||
} // namespace Io
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
116
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/io/Pkcs11.h
Normal file
116
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/io/Pkcs11.h
Normal file
@@ -0,0 +1,116 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
struct aws_pkcs11_lib;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
/**
|
||||
* Handle to a loaded PKCS#11 library.
|
||||
*
|
||||
* For most use cases, a single instance of Pkcs11Lib should be used for the
|
||||
* lifetime of your application.
|
||||
*/
|
||||
class AWS_CRT_CPP_API Pkcs11Lib
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Controls how Pkcs11Lib calls `C_Initialize()` and `C_Finalize()`
|
||||
* on the PKCS#11 library.
|
||||
*/
|
||||
enum class InitializeFinalizeBehavior
|
||||
{
|
||||
/**
|
||||
* Default behavior that accommodates most use cases.
|
||||
*
|
||||
* `C_Initialize()` is called on creation, and "already-initialized"
|
||||
* errors are ignored. `C_Finalize()` is never called, just in case
|
||||
* another part of your application is still using the PKCS#11 library.
|
||||
*/
|
||||
Default,
|
||||
|
||||
/**
|
||||
* Skip calling `C_Initialize()` and `C_Finalize()`.
|
||||
*
|
||||
* Use this if your application has already initialized the PKCS#11 library, and
|
||||
* you do not want `C_Initialize()` called again.
|
||||
*/
|
||||
Omit,
|
||||
|
||||
/**
|
||||
* `C_Initialize()` is called on creation and `C_Finalize()` is
|
||||
* called on cleanup.
|
||||
*
|
||||
* If `C_Initialize()` reports that's it's already initialized, this is
|
||||
* treated as an error. Use this if you need perfect cleanup (ex: running
|
||||
* valgrind with --leak-check).
|
||||
*/
|
||||
Strict,
|
||||
};
|
||||
|
||||
/**
|
||||
* Load and initialize a PKCS#11 library.
|
||||
*
|
||||
* `C_Initialize()` and `C_Finalize()` are called on the PKCS#11
|
||||
* library in the InitializeFinalizeBehavior::Default way.
|
||||
*
|
||||
* @param filename Name or path of PKCS#11 library file to load (UTF-8).
|
||||
* Pass an empty string if your application already has PKCS#11 symbols linked in.
|
||||
*
|
||||
* @param allocator Memory allocator to use.
|
||||
*
|
||||
* @return If successful a `shared_ptr` containing the Pkcs11Lib is returned.
|
||||
* If unsuccessful the `shared_ptr` will be empty, and Aws::Crt::LastError()
|
||||
* will contain the error that occurred.
|
||||
*/
|
||||
static std::shared_ptr<Pkcs11Lib> Create(const String &filename, Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Load a PKCS#11 library, specifying how `C_Initialize()` and `C_Finalize()` will be called.
|
||||
*
|
||||
* @param filename Name or path of PKCS#11 library file to load (UTF-8).
|
||||
* Pass an empty string if your application already has PKCS#11 symbols linked in.
|
||||
*
|
||||
* @param initializeFinalizeBehavior Specifies how `C_Initialize()` and
|
||||
* `C_Finalize()` will be called on the
|
||||
* PKCS#11 library.
|
||||
* @param allocator Memory allocator to use.
|
||||
*
|
||||
* @return If successful a `shared_ptr` containing the Pkcs11Lib is returned.
|
||||
* If unsuccessful the `shared_ptr` will be empty, and Aws::Crt::LastError()
|
||||
* will contain the error that occurred.
|
||||
*/
|
||||
static std::shared_ptr<Pkcs11Lib> Create(
|
||||
const String &filename,
|
||||
InitializeFinalizeBehavior initializeFinalizeBehavior,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
~Pkcs11Lib();
|
||||
|
||||
/// @private
|
||||
aws_pkcs11_lib *GetNativeHandle() { return impl; }
|
||||
|
||||
/// @private Use Create(...), this constructor is for internal use only
|
||||
explicit Pkcs11Lib(aws_pkcs11_lib &impl);
|
||||
|
||||
private:
|
||||
// no copy/move
|
||||
Pkcs11Lib(const Pkcs11Lib &) = delete;
|
||||
Pkcs11Lib(Pkcs11Lib &&) = delete;
|
||||
Pkcs11Lib &operator=(const Pkcs11Lib &) = delete;
|
||||
Pkcs11Lib &operator=(Pkcs11Lib &&) = delete;
|
||||
|
||||
aws_pkcs11_lib *impl = nullptr;
|
||||
};
|
||||
} // namespace Io
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,157 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Exports.h>
|
||||
|
||||
#include <aws/io/socket.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
enum class SocketType
|
||||
{
|
||||
/**
|
||||
* A streaming socket sends reliable messages over a two-way connection.
|
||||
* This means TCP when used with IPV4/6, and Unix domain sockets, when used with
|
||||
* AWS_SOCKET_LOCAL
|
||||
*/
|
||||
Stream = AWS_SOCKET_STREAM,
|
||||
|
||||
/**
|
||||
* A datagram socket is connectionless and sends unreliable messages.
|
||||
* This means UDP when used with IPV4/6.
|
||||
* LOCAL sockets are not compatible with DGRAM.
|
||||
*/
|
||||
Dgram = AWS_SOCKET_DGRAM,
|
||||
};
|
||||
|
||||
enum class SocketDomain
|
||||
{
|
||||
IPv4 = AWS_SOCKET_IPV4,
|
||||
IPv6 = AWS_SOCKET_IPV6,
|
||||
/**
|
||||
* Unix domain sockets (or at least something like them)
|
||||
*/
|
||||
Local = AWS_SOCKET_LOCAL,
|
||||
};
|
||||
|
||||
/**
|
||||
* Socket configuration options
|
||||
*/
|
||||
class AWS_CRT_CPP_API SocketOptions
|
||||
{
|
||||
public:
|
||||
SocketOptions();
|
||||
SocketOptions(const SocketOptions &rhs) = default;
|
||||
SocketOptions(SocketOptions &&rhs) = default;
|
||||
|
||||
SocketOptions &operator=(const SocketOptions &rhs) = default;
|
||||
SocketOptions &operator=(SocketOptions &&rhs) = default;
|
||||
|
||||
/**
|
||||
* Set socket type
|
||||
* @param type: SocketType object.
|
||||
*/
|
||||
void SetSocketType(SocketType type) { options.type = (enum aws_socket_type)type; }
|
||||
|
||||
/**
|
||||
* @return the type of socket to use
|
||||
*/
|
||||
SocketType GetSocketType() const { return (SocketType)options.type; }
|
||||
|
||||
/**
|
||||
* Set socket domain
|
||||
* @param domain: SocketDomain object.
|
||||
*/
|
||||
void SetSocketDomain(SocketDomain domain) { options.domain = (enum aws_socket_domain)domain; }
|
||||
|
||||
/**
|
||||
* @return the domain type to use with the socket
|
||||
*/
|
||||
SocketDomain GetSocketDomain() const { return (SocketDomain)options.domain; }
|
||||
|
||||
/**
|
||||
* Set connection timeout
|
||||
* @param timeout: connection timeout in milliseconds.
|
||||
*/
|
||||
void SetConnectTimeoutMs(uint32_t timeout) { options.connect_timeout_ms = timeout; }
|
||||
|
||||
/**
|
||||
* @return the connection timeout in milliseconds to use with the socket
|
||||
*/
|
||||
uint32_t GetConnectTimeoutMs() const { return options.connect_timeout_ms; }
|
||||
|
||||
/**
|
||||
* Set keep alive interval seconds.
|
||||
* @param keepAliveInterval: Duration, in seconds, between keepalive probes. If 0, then a default value
|
||||
* is used.
|
||||
*/
|
||||
void SetKeepAliveIntervalSec(uint16_t keepAliveInterval)
|
||||
{
|
||||
options.keep_alive_interval_sec = keepAliveInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the (tcp) keep alive interval to use with the socket, in seconds
|
||||
*/
|
||||
uint16_t GetKeepAliveIntervalSec() const { return options.keep_alive_interval_sec; }
|
||||
|
||||
/**
|
||||
* Set keep alive time out seconds.
|
||||
* @param keepAliveTimeout: interval, in seconds, that a connection must be idle for before keep alive
|
||||
* probes begin to get sent out
|
||||
*/
|
||||
void SetKeepAliveTimeoutSec(uint16_t keepAliveTimeout)
|
||||
{
|
||||
options.keep_alive_timeout_sec = keepAliveTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return interval, in seconds, that a connection must be idle for before keep alive probes begin
|
||||
* to get sent out
|
||||
*/
|
||||
uint16_t GetKeepAliveTimeoutSec() const { return options.keep_alive_timeout_sec; }
|
||||
|
||||
/**
|
||||
* Set keep alive max failed probes.
|
||||
* @param maxProbes: The number of keepalive probes allowed to fail before a connection is considered
|
||||
* lost.
|
||||
*/
|
||||
void SetKeepAliveMaxFailedProbes(uint16_t maxProbes)
|
||||
{
|
||||
options.keep_alive_max_failed_probes = maxProbes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of keepalive probes allowed to fail before a connection is considered lost.
|
||||
*/
|
||||
uint16_t GetKeepAliveMaxFailedProbes() const { return options.keep_alive_max_failed_probes; }
|
||||
|
||||
/**
|
||||
* Set keep alive option.
|
||||
* @param keepAlive: True, periodically transmit keepalive messages for detecting a disconnected peer.
|
||||
*/
|
||||
void SetKeepAlive(bool keepAlive) { options.keepalive = keepAlive; }
|
||||
|
||||
/**
|
||||
* @return true/false if the socket implementation should use TCP keepalive
|
||||
*/
|
||||
bool GetKeepAlive() const { return options.keepalive; }
|
||||
|
||||
/// @private
|
||||
aws_socket_options &GetImpl() { return options; }
|
||||
/// @private
|
||||
const aws_socket_options &GetImpl() const { return options; }
|
||||
|
||||
private:
|
||||
aws_socket_options options;
|
||||
};
|
||||
} // namespace Io
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
197
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/io/Stream.h
Normal file
197
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/io/Stream.h
Normal file
@@ -0,0 +1,197 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/RefCounted.h>
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/io/stream.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
using StreamStatus = aws_stream_status;
|
||||
|
||||
/**
|
||||
* @deprecated Use int64_t instead for offsets in public APIs.
|
||||
*/
|
||||
using OffsetType = aws_off_t;
|
||||
|
||||
/**
|
||||
* Controls the direction to seek from
|
||||
*/
|
||||
enum class StreamSeekBasis
|
||||
{
|
||||
Begin = AWS_SSB_BEGIN,
|
||||
End = AWS_SSB_END,
|
||||
};
|
||||
|
||||
/***
|
||||
* Interface for building an Object oriented stream that will be honored by the CRT's low-level
|
||||
* aws_input_stream interface. To use, create a subclass of InputStream and define the abstract
|
||||
* functions.
|
||||
*/
|
||||
class AWS_CRT_CPP_API InputStream : public std::enable_shared_from_this<InputStream>,
|
||||
public RefCounted<InputStream>
|
||||
{
|
||||
public:
|
||||
virtual ~InputStream();
|
||||
|
||||
InputStream(const InputStream &) = delete;
|
||||
InputStream &operator=(const InputStream &) = delete;
|
||||
InputStream(InputStream &&) = delete;
|
||||
InputStream &operator=(InputStream &&) = delete;
|
||||
|
||||
explicit operator bool() const noexcept { return IsValid(); }
|
||||
|
||||
/**
|
||||
* @return true/false if this object is in a valid state
|
||||
*/
|
||||
virtual bool IsValid() const noexcept = 0;
|
||||
|
||||
/// @private
|
||||
aws_input_stream *GetUnderlyingStream() noexcept { return &m_underlying_stream; }
|
||||
|
||||
/**
|
||||
* Reads data from the stream into a buffer
|
||||
* @param dest buffer to add the read data into
|
||||
* @return success/failure
|
||||
*/
|
||||
bool Read(ByteBuf &dest) { return aws_input_stream_read(&m_underlying_stream, &dest) == 0; }
|
||||
|
||||
/**
|
||||
* Moves the head of the stream to a new location
|
||||
* @param offset how far to move, in bytes
|
||||
* @param seekBasis what direction to move the head of stream
|
||||
* @return success/failure
|
||||
*/
|
||||
bool Seek(int64_t offset, StreamSeekBasis seekBasis)
|
||||
{
|
||||
return aws_input_stream_seek(&m_underlying_stream, offset, (aws_stream_seek_basis)seekBasis) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stream's current status
|
||||
* @param status output parameter for the stream's status
|
||||
* @return success/failure
|
||||
*/
|
||||
bool GetStatus(StreamStatus &status)
|
||||
{
|
||||
return aws_input_stream_get_status(&m_underlying_stream, &status) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stream's length. Some streams may not be able to answer this.
|
||||
* @param length output parameter for the length of the stream
|
||||
* @return success/failure
|
||||
*/
|
||||
bool GetLength(int64_t &length)
|
||||
{
|
||||
return aws_input_stream_get_length(&m_underlying_stream, &length) == 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
Allocator *m_allocator;
|
||||
aws_input_stream m_underlying_stream;
|
||||
|
||||
InputStream(Aws::Crt::Allocator *allocator = ApiAllocator());
|
||||
|
||||
/***
|
||||
* Read up-to buffer::capacity - buffer::len into buffer::buffer
|
||||
* Increment buffer::len by the amount you read in.
|
||||
*
|
||||
* @return true if nothing went wrong.
|
||||
* Return true even if you read 0 bytes because the end-of-file has been reached.
|
||||
* Return true even if you read 0 bytes because data is not currently available.
|
||||
*
|
||||
* Return false if an actual failure condition occurs,
|
||||
* you SHOULD also raise an error via aws_raise_error().
|
||||
*/
|
||||
virtual bool ReadImpl(ByteBuf &buffer) noexcept = 0;
|
||||
|
||||
/***
|
||||
* Read up-to buffer::capacity - buffer::len immediately available bytes into buffer::buffer
|
||||
* Increment buffer::len by the amount you read in.
|
||||
*
|
||||
* @return true if nothing went wrong.
|
||||
* Return true even if you read 0 bytes because the end-of-file has been reached.
|
||||
* Return true even if you read 0 bytes because data is not currently available.
|
||||
*
|
||||
* Return false if an actual failure condition occurs,
|
||||
* you SHOULD also raise an error via aws_raise_error().
|
||||
*/
|
||||
virtual bool ReadSomeImpl(ByteBuf &buffer) noexcept = 0;
|
||||
|
||||
/**
|
||||
* @return the current status of the stream.
|
||||
*/
|
||||
virtual StreamStatus GetStatusImpl() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* @return the total length of the available data for the stream.
|
||||
* @return -1 if not available.
|
||||
*/
|
||||
virtual int64_t GetLengthImpl() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Seek's the stream to seekBasis based offset bytes.
|
||||
*
|
||||
* It is expected, that if seeking to the beginning of a stream,
|
||||
* all error's are cleared if possible.
|
||||
*
|
||||
* @return true on success, false otherwise. You SHOULD raise an error via aws_raise_error()
|
||||
* if a failure occurs.
|
||||
*/
|
||||
virtual bool SeekImpl(int64_t offset, StreamSeekBasis seekBasis) noexcept = 0;
|
||||
|
||||
/**
|
||||
* Peeks the stream
|
||||
*
|
||||
* Essentially calls peek on the underlying istream
|
||||
*
|
||||
* @return return value of the underlying istream::peek
|
||||
*/
|
||||
virtual int64_t PeekImpl() const noexcept = 0;
|
||||
|
||||
private:
|
||||
static int s_Seek(aws_input_stream *stream, int64_t offset, enum aws_stream_seek_basis basis);
|
||||
static int s_Read(aws_input_stream *stream, aws_byte_buf *dest);
|
||||
static int s_GetStatus(aws_input_stream *stream, aws_stream_status *status);
|
||||
static int s_GetLength(struct aws_input_stream *stream, int64_t *out_length);
|
||||
static void s_Acquire(aws_input_stream *stream);
|
||||
static void s_Release(aws_input_stream *stream);
|
||||
|
||||
static aws_input_stream_vtable s_vtable;
|
||||
};
|
||||
|
||||
/***
|
||||
* Implementation of Aws::Crt::Io::InputStream that wraps a std::input_stream.
|
||||
*/
|
||||
class AWS_CRT_CPP_API StdIOStreamInputStream : public InputStream
|
||||
{
|
||||
public:
|
||||
StdIOStreamInputStream(
|
||||
std::shared_ptr<Aws::Crt::Io::IStream> stream,
|
||||
Aws::Crt::Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
bool IsValid() const noexcept override;
|
||||
|
||||
protected:
|
||||
bool ReadImpl(ByteBuf &buffer) noexcept override;
|
||||
bool ReadSomeImpl(ByteBuf &buffer) noexcept override;
|
||||
StreamStatus GetStatusImpl() const noexcept override;
|
||||
int64_t GetLengthImpl() const noexcept override;
|
||||
bool SeekImpl(OffsetType offsetType, StreamSeekBasis seekBasis) noexcept override;
|
||||
int64_t PeekImpl() const noexcept override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Aws::Crt::Io::IStream> m_stream;
|
||||
};
|
||||
} // namespace Io
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,453 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/crt/io/ChannelHandler.h>
|
||||
#include <aws/io/tls_channel_handler.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
struct aws_tls_ctx_options;
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
class Pkcs11Lib;
|
||||
class TlsContextPkcs11Options;
|
||||
|
||||
enum class TlsMode
|
||||
{
|
||||
CLIENT,
|
||||
SERVER,
|
||||
};
|
||||
|
||||
/**
|
||||
* Top-level tls configuration options. These options are used to create a context from which
|
||||
* per-connection TLS contexts can be created.
|
||||
*/
|
||||
class AWS_CRT_CPP_API TlsContextOptions
|
||||
{
|
||||
friend class TlsContext;
|
||||
|
||||
public:
|
||||
TlsContextOptions() noexcept;
|
||||
virtual ~TlsContextOptions();
|
||||
TlsContextOptions(const TlsContextOptions &) noexcept = delete;
|
||||
TlsContextOptions &operator=(const TlsContextOptions &) noexcept = delete;
|
||||
TlsContextOptions(TlsContextOptions &&) noexcept;
|
||||
TlsContextOptions &operator=(TlsContextOptions &&) noexcept;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
explicit operator bool() const noexcept { return m_isInit; }
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int LastError() const noexcept;
|
||||
|
||||
/**
|
||||
* Initializes TlsContextOptions with secure by default options, with
|
||||
* no client certificates.
|
||||
*/
|
||||
static TlsContextOptions InitDefaultClient(Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Initializes TlsContextOptions for mutual TLS (mTLS), with
|
||||
* client certificate and private key. These are paths to a file on disk. These files
|
||||
* must be in the PEM format.
|
||||
*
|
||||
* NOTE: This is unsupported on iOS.
|
||||
*
|
||||
* @param cert_path: Path to certificate file.
|
||||
* @param pkey_path: Path to private key file.
|
||||
* @param allocator Memory allocator to use.
|
||||
*/
|
||||
static TlsContextOptions InitClientWithMtls(
|
||||
const char *cert_path,
|
||||
const char *pkey_path,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Initializes TlsContextOptions for mutual TLS (mTLS), with
|
||||
* client certificate and private key. These are in memory buffers. These buffers
|
||||
* must be in the PEM format.
|
||||
*
|
||||
* NOTE: This is unsupported on iOS.
|
||||
*
|
||||
* @param cert: Certificate contents in memory.
|
||||
* @param pkey: Private key contents in memory.
|
||||
* @param allocator Memory allocator to use.
|
||||
*/
|
||||
static TlsContextOptions InitClientWithMtls(
|
||||
const ByteCursor &cert,
|
||||
const ByteCursor &pkey,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Initializes TlsContextOptions for mutual TLS (mTLS),
|
||||
* using a PKCS#11 library for private key operations.
|
||||
*
|
||||
* NOTE: This only works on Unix devices.
|
||||
*
|
||||
* @param pkcs11Options PKCS#11 options
|
||||
* @param allocator Memory allocator to use.
|
||||
*/
|
||||
static TlsContextOptions InitClientWithMtlsPkcs11(
|
||||
const TlsContextPkcs11Options &pkcs11Options,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Initializes TlsContextOptions for mutual TLS (mTLS), with
|
||||
* client certificate and private key in the PKCS#12 format.
|
||||
*
|
||||
* NOTE: This only works on Apple devices.
|
||||
*
|
||||
* @param pkcs12_path: Path to PKCS #12 file. The file is loaded from disk and stored internally. It
|
||||
* must remain in memory for the lifetime of the returned object.
|
||||
* @param pkcs12_pwd: Password to PKCS #12 file. It must remain in memory for the lifetime of the
|
||||
* returned object.
|
||||
* @param allocator Memory allocator to use.
|
||||
*/
|
||||
static TlsContextOptions InitClientWithMtlsPkcs12(
|
||||
const char *pkcs12_path,
|
||||
const char *pkcs12_pwd,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* @deprecated Custom keychain management is deprecated.
|
||||
*
|
||||
* By default the certificates and private keys are stored in the default keychain
|
||||
* of the account of the process. If you instead wish to provide your own keychain
|
||||
* for storing them, this makes the TlsContext to use that instead.
|
||||
* NOTE: The password of your keychain must be empty.
|
||||
*
|
||||
* NOTE: This only works on MacOS.
|
||||
*/
|
||||
bool SetKeychainPath(ByteCursor &keychain_path) noexcept;
|
||||
|
||||
/**
|
||||
* Initializes TlsContextOptions for mutual TLS (mTLS),
|
||||
* using a client certificate in a Windows certificate store.
|
||||
*
|
||||
* NOTE: This only works on Windows.
|
||||
*
|
||||
* @param windowsCertStorePath Path to certificate in a Windows certificate store.
|
||||
* The path must use backslashes and end with the certificate's thumbprint.
|
||||
* Example: `CurrentUser\MY\A11F8A9B5DF5B98BA3508FBCA575D09570E0D2C6`
|
||||
* @param allocator The memory allocator to use.
|
||||
*/
|
||||
static TlsContextOptions InitClientWithMtlsSystemPath(
|
||||
const char *windowsCertStorePath,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* @return true if alpn is supported by the underlying security provider, false
|
||||
* otherwise.
|
||||
*/
|
||||
static bool IsAlpnSupported() noexcept;
|
||||
|
||||
/**
|
||||
* Sets the list of alpn protocols.
|
||||
* @param alpnList: List of protocol names, delimited by ';'. This string must remain in memory for the
|
||||
* lifetime of this object.
|
||||
*/
|
||||
bool SetAlpnList(const char *alpnList) noexcept;
|
||||
|
||||
/**
|
||||
* In client mode, this turns off x.509 validation. Don't do this unless you're testing.
|
||||
* It's much better, to just override the default trust store and pass the self-signed
|
||||
* certificate as the caFile argument.
|
||||
*
|
||||
* In server mode, this defaults to false. If you want to support mutual TLS from the server,
|
||||
* you'll want to set this to true.
|
||||
*/
|
||||
void SetVerifyPeer(bool verifyPeer) noexcept;
|
||||
|
||||
/**
|
||||
* Sets the minimum TLS version allowed.
|
||||
* @param minimumTlsVersion: The minimum TLS version.
|
||||
*/
|
||||
void SetMinimumTlsVersion(aws_tls_versions minimumTlsVersion);
|
||||
|
||||
/**
|
||||
* Sets the preferred TLS Cipher List
|
||||
* @param cipher_pref: The preferred TLS cipher list.
|
||||
*/
|
||||
void SetTlsCipherPreference(aws_tls_cipher_pref cipher_pref);
|
||||
|
||||
/**
|
||||
* Overrides the default system trust store.
|
||||
* @param caPath: Path to directory containing trusted certificates, which will overrides the
|
||||
* default trust store. Only useful on Unix style systems where all anchors are stored in a directory
|
||||
* (like /etc/ssl/certs). This string must remain in memory for the lifetime of this object.
|
||||
* @param caFile: Path to file containing PEM armored chain of trusted CA certificates. This
|
||||
* string must remain in memory for the lifetime of this object.
|
||||
*/
|
||||
bool OverrideDefaultTrustStore(const char *caPath, const char *caFile) noexcept;
|
||||
|
||||
/**
|
||||
* Overrides the default system trust store.
|
||||
* @param ca: PEM armored chain of trusted CA certificates.
|
||||
*/
|
||||
bool OverrideDefaultTrustStore(const ByteCursor &ca) noexcept;
|
||||
|
||||
/// @private
|
||||
const aws_tls_ctx_options *GetUnderlyingHandle() const noexcept { return &m_options; }
|
||||
|
||||
private:
|
||||
aws_tls_ctx_options m_options;
|
||||
bool m_isInit;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for TLS, when using a PKCS#11 library for private key operations.
|
||||
*
|
||||
* @see TlsContextOptions::InitClientWithMtlsPkcs11()
|
||||
*/
|
||||
class AWS_CRT_CPP_API TlsContextPkcs11Options final
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param pkcs11Lib use this PKCS#11 library
|
||||
* @param allocator Memory allocator to use.
|
||||
*/
|
||||
TlsContextPkcs11Options(
|
||||
const std::shared_ptr<Pkcs11Lib> &pkcs11Lib,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Use this PIN to log the user into the PKCS#11 token.
|
||||
* Leave unspecified to log into a token with a "protected authentication path".
|
||||
*
|
||||
* @param pin PIN
|
||||
*/
|
||||
void SetUserPin(const String &pin) noexcept;
|
||||
|
||||
/**
|
||||
* Specify the slot ID containing a PKCS#11 token.
|
||||
* If not specified, the token will be chosen based on other criteria (such as token label).
|
||||
*
|
||||
* @param id slot ID
|
||||
*/
|
||||
void SetSlotId(const uint64_t id) noexcept;
|
||||
|
||||
/**
|
||||
* Specify the label of the PKCS#11 token to use.
|
||||
* If not specified, the token will be chosen based on other criteria (such as slot ID).
|
||||
*
|
||||
* @param label label of token
|
||||
*/
|
||||
void SetTokenLabel(const String &label) noexcept;
|
||||
|
||||
/**
|
||||
* Specify the label of the private key object on the PKCS#11 token.
|
||||
* If not specified, the key will be chosen based on other criteria
|
||||
* (such as being the only available private key on the token).
|
||||
*
|
||||
* @param label label of private key object
|
||||
*/
|
||||
void SetPrivateKeyObjectLabel(const String &label) noexcept;
|
||||
|
||||
/**
|
||||
* Use this X.509 certificate (file on disk).
|
||||
* The certificate may be specified by other means instead (ex: SetCertificateFileContents())
|
||||
*
|
||||
* @param path path to PEM-formatted certificate file on disk.
|
||||
*/
|
||||
void SetCertificateFilePath(const String &path) noexcept;
|
||||
|
||||
/**
|
||||
* Use this X.509 certificate (contents in memory).
|
||||
* The certificate may be specified by other means instead (ex: SetCertificateFilePath())
|
||||
*
|
||||
* @param contents contents of PEM-formatted certificate file.
|
||||
*/
|
||||
void SetCertificateFileContents(const String &contents) noexcept;
|
||||
|
||||
/// @private
|
||||
aws_tls_ctx_pkcs11_options GetUnderlyingHandle() const noexcept;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Pkcs11Lib> m_pkcs11Lib;
|
||||
Optional<uint64_t> m_slotId;
|
||||
Optional<String> m_userPin;
|
||||
Optional<String> m_tokenLabel;
|
||||
Optional<String> m_privateKeyObjectLabel;
|
||||
Optional<String> m_certificateFilePath;
|
||||
Optional<String> m_certificateFileContents;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options specific to a single connection.
|
||||
*/
|
||||
class AWS_CRT_CPP_API TlsConnectionOptions final
|
||||
{
|
||||
public:
|
||||
TlsConnectionOptions() noexcept;
|
||||
~TlsConnectionOptions();
|
||||
TlsConnectionOptions(const TlsConnectionOptions &) noexcept;
|
||||
TlsConnectionOptions &operator=(const TlsConnectionOptions &) noexcept;
|
||||
TlsConnectionOptions(TlsConnectionOptions &&options) noexcept;
|
||||
TlsConnectionOptions &operator=(TlsConnectionOptions &&options) noexcept;
|
||||
|
||||
/**
|
||||
* Sets SNI extension, and also the name used for X.509 validation. serverName is copied.
|
||||
*
|
||||
* @return true if the copy succeeded, or false otherwise.
|
||||
*/
|
||||
bool SetServerName(ByteCursor &serverName) noexcept;
|
||||
|
||||
/**
|
||||
* Sets list of protocols (semi-colon delimited in priority order) used for ALPN extension.
|
||||
* alpnList is copied.
|
||||
*
|
||||
* @return true if the copy succeeded, or false otherwise.
|
||||
*/
|
||||
bool SetAlpnList(const char *alpnList) noexcept;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
explicit operator bool() const noexcept { return isValid(); }
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int LastError() const noexcept { return m_lastError; }
|
||||
|
||||
/// @private
|
||||
const aws_tls_connection_options *GetUnderlyingHandle() const noexcept
|
||||
{
|
||||
return &m_tls_connection_options;
|
||||
}
|
||||
|
||||
private:
|
||||
bool isValid() const noexcept { return m_isInit; }
|
||||
|
||||
TlsConnectionOptions(aws_tls_ctx *ctx, Allocator *allocator) noexcept;
|
||||
aws_tls_connection_options m_tls_connection_options;
|
||||
aws_allocator *m_allocator;
|
||||
int m_lastError;
|
||||
bool m_isInit;
|
||||
|
||||
friend class TlsContext;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stateful context for TLS with a given configuration. Per-connection TLS "contexts"
|
||||
* (TlsConnectionOptions) are instantiated from this as needed.
|
||||
*/
|
||||
class AWS_CRT_CPP_API TlsContext final
|
||||
{
|
||||
public:
|
||||
TlsContext() noexcept;
|
||||
TlsContext(TlsContextOptions &options, TlsMode mode, Allocator *allocator = ApiAllocator()) noexcept;
|
||||
~TlsContext() = default;
|
||||
TlsContext(const TlsContext &) noexcept = default;
|
||||
TlsContext &operator=(const TlsContext &) noexcept = default;
|
||||
TlsContext(TlsContext &&) noexcept = default;
|
||||
TlsContext &operator=(TlsContext &&) noexcept = default;
|
||||
|
||||
/**
|
||||
* @return a new connection-specific TLS context that can be configured with per-connection options
|
||||
* (server name, peer verification, etc...)
|
||||
*/
|
||||
TlsConnectionOptions NewConnectionOptions() const noexcept;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
explicit operator bool() const noexcept { return isValid(); }
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int GetInitializationError() const noexcept { return m_initializationError; }
|
||||
|
||||
/// @private
|
||||
aws_tls_ctx *GetUnderlyingHandle() const noexcept { return m_ctx.get(); }
|
||||
|
||||
private:
|
||||
bool isValid() const noexcept { return m_ctx && m_initializationError == AWS_ERROR_SUCCESS; }
|
||||
|
||||
std::shared_ptr<aws_tls_ctx> m_ctx;
|
||||
int m_initializationError;
|
||||
};
|
||||
|
||||
using NewTlsContextImplCallback = std::function<void *(TlsContextOptions &, TlsMode, Allocator *)>;
|
||||
using DeleteTlsContextImplCallback = std::function<void(void *)>;
|
||||
using IsTlsAlpnSupportedCallback = std::function<bool()>;
|
||||
|
||||
/**
|
||||
* BYO_CRYPTO: TLS channel-handler base class.
|
||||
*/
|
||||
class AWS_CRT_CPP_API TlsChannelHandler : public ChannelHandler
|
||||
{
|
||||
public:
|
||||
virtual ~TlsChannelHandler();
|
||||
|
||||
/**
|
||||
* @return negotiated protocol (or empty string if no agreed upon protocol)
|
||||
*/
|
||||
virtual String GetProtocol() const = 0;
|
||||
|
||||
protected:
|
||||
TlsChannelHandler(
|
||||
struct aws_channel_slot *slot,
|
||||
const struct aws_tls_connection_options &options,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
|
||||
/**
|
||||
* Invoke this function from inside your handler after TLS negotiation completes. errorCode ==
|
||||
* AWS_ERROR_SUCCESS or 0 means the session was successfully established and the connection should
|
||||
* continue on.
|
||||
*/
|
||||
void CompleteTlsNegotiation(int errorCode);
|
||||
|
||||
private:
|
||||
aws_tls_on_negotiation_result_fn *m_OnNegotiationResult;
|
||||
void *m_userData;
|
||||
|
||||
aws_byte_buf m_protocolByteBuf;
|
||||
friend aws_byte_buf(::aws_tls_handler_protocol)(aws_channel_handler *);
|
||||
};
|
||||
|
||||
/**
|
||||
* BYO_CRYPTO: Client TLS channel-handler base class.
|
||||
*
|
||||
* If using BYO_CRYPTO, you must define a concrete implementation
|
||||
* and set its creation callback via ApiHandle.SetBYOCryptoClientTlsCallback().
|
||||
*/
|
||||
class AWS_CRT_CPP_API ClientTlsChannelHandler : public TlsChannelHandler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initiates the TLS session negotiation. This is called by the common runtime when it's time to start
|
||||
* a new session.
|
||||
*/
|
||||
virtual void StartNegotiation() = 0;
|
||||
|
||||
protected:
|
||||
ClientTlsChannelHandler(
|
||||
struct aws_channel_slot *slot,
|
||||
const struct aws_tls_connection_options &options,
|
||||
Allocator *allocator = ApiAllocator());
|
||||
};
|
||||
|
||||
using NewClientTlsHandlerCallback = std::function<std::shared_ptr<ClientTlsChannelHandler>(
|
||||
struct aws_channel_slot *slot,
|
||||
const struct aws_tls_connection_options &options,
|
||||
Allocator *allocator)>;
|
||||
|
||||
} // namespace Io
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
105
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/io/Uri.h
Normal file
105
Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/io/Uri.h
Normal file
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/Types.h>
|
||||
|
||||
#include <aws/io/uri.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
/**
|
||||
* Contains a URI used for networking application protocols. This type is move-only.
|
||||
*/
|
||||
class AWS_CRT_CPP_API Uri final
|
||||
{
|
||||
public:
|
||||
Uri() noexcept;
|
||||
~Uri();
|
||||
|
||||
/**
|
||||
* Parses `cursor` as a URI. Upon failure the bool() operator will return false and LastError()
|
||||
* will contain the errorCode.
|
||||
*/
|
||||
Uri(const ByteCursor &cursor, Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Builds a URI from `builderOptions`. Upon failure the bool() operator will return false and
|
||||
* LastError() will contain the errorCode.
|
||||
*/
|
||||
Uri(aws_uri_builder_options &builderOptions, Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
Uri(const Uri &);
|
||||
Uri &operator=(const Uri &);
|
||||
Uri(Uri &&uri) noexcept;
|
||||
Uri &operator=(Uri &&) noexcept;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const noexcept { return m_isInit; }
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int LastError() const noexcept { return m_lastError; }
|
||||
|
||||
/**
|
||||
* @return the scheme portion of the URI if present (e.g. https, http, ftp etc....)
|
||||
*/
|
||||
ByteCursor GetScheme() const noexcept;
|
||||
|
||||
/**
|
||||
* @return the authority portion of the URI if present. This will contain host name and port if
|
||||
* specified.
|
||||
* */
|
||||
ByteCursor GetAuthority() const noexcept;
|
||||
|
||||
/**
|
||||
* @return the path portion of the URI. If no path was present, this will be set to '/'.
|
||||
*/
|
||||
ByteCursor GetPath() const noexcept;
|
||||
|
||||
/**
|
||||
* @return the query string portion of the URI if present.
|
||||
*/
|
||||
ByteCursor GetQueryString() const noexcept;
|
||||
|
||||
/**
|
||||
* @return the host name portion of the authority. (port will not be in this value).
|
||||
*/
|
||||
ByteCursor GetHostName() const noexcept;
|
||||
|
||||
/**
|
||||
* @return the port portion of the authority if a port was specified. If it was not, this will
|
||||
* be set to 0. In that case, it is your responsibility to determine the correct port
|
||||
* based on the protocol you're using.
|
||||
*/
|
||||
uint32_t GetPort() const noexcept;
|
||||
|
||||
/** @return the Path and Query portion of the URI. In the case of Http, this likely the value for the
|
||||
* URI parameter.
|
||||
*/
|
||||
ByteCursor GetPathAndQuery() const noexcept;
|
||||
|
||||
/**
|
||||
* @return The full URI as it was passed to or parsed from the constructors.
|
||||
*/
|
||||
ByteCursor GetFullUri() const noexcept;
|
||||
|
||||
private:
|
||||
aws_uri m_uri;
|
||||
int m_lastError;
|
||||
bool m_isInit;
|
||||
};
|
||||
|
||||
AWS_CRT_CPP_API Aws::Crt::String EncodeQueryParameterValue(ByteCursor paramValue);
|
||||
|
||||
} // namespace Io
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,842 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/http/HttpConnection.h>
|
||||
#include <aws/crt/mqtt/Mqtt5Types.h>
|
||||
#include <aws/crt/mqtt/MqttClient.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Mqtt5
|
||||
{
|
||||
class ConnectPacket;
|
||||
class ConnAckPacket;
|
||||
class DisconnectPacket;
|
||||
class Mqtt5Client;
|
||||
class Mqtt5ClientOptions;
|
||||
class NegotiatedSettings;
|
||||
class PublishResult;
|
||||
class PublishPacket;
|
||||
class PubAckPacket;
|
||||
class SubscribePacket;
|
||||
class SubAckPacket;
|
||||
class UnsubscribePacket;
|
||||
class UnSubAckPacket;
|
||||
class Mqtt5ClientCore;
|
||||
|
||||
class Mqtt5to3AdapterOptions;
|
||||
|
||||
/**
|
||||
* An enumeration that controls how the client applies topic aliasing to outbound publish packets.
|
||||
*
|
||||
* Topic alias behavior is described in
|
||||
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901113
|
||||
*/
|
||||
enum class OutboundTopicAliasBehaviorType
|
||||
{
|
||||
|
||||
/**
|
||||
* Maps to Disabled. This keeps the client from being broken (by default) if the broker
|
||||
* topic aliasing implementation has a problem.
|
||||
*/
|
||||
Default = AWS_MQTT5_COTABT_DEFAULT,
|
||||
|
||||
/**
|
||||
* Outbound aliasing is the user's responsibility. Client will cache and use
|
||||
* previously-established aliases if they fall within the negotiated limits of the connection.
|
||||
*
|
||||
* The user must still always submit a full topic in their publishes because disconnections disrupt
|
||||
* topic alias mappings unpredictably. The client will properly use a requested alias when the
|
||||
* most-recently-seen binding for a topic alias value matches the alias and topic in the publish packet.
|
||||
*/
|
||||
Manual = AWS_MQTT5_COTABT_MANUAL,
|
||||
|
||||
/**
|
||||
* (Recommended) The client will ignore any user-specified topic aliasing and instead use an LRU cache
|
||||
* to drive alias usage.
|
||||
*/
|
||||
LRU = AWS_MQTT5_COTABT_LRU,
|
||||
|
||||
/**
|
||||
* Completely disable outbound topic aliasing.
|
||||
*/
|
||||
Disabled = AWS_MQTT5_COTABT_DISABLED,
|
||||
};
|
||||
|
||||
/**
|
||||
* An enumeration that controls whether or not the client allows the broker to send publishes that use topic
|
||||
* aliasing.
|
||||
*
|
||||
* Topic alias behavior is described in
|
||||
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901113
|
||||
*/
|
||||
enum class InboundTopicAliasBehaviorType
|
||||
{
|
||||
|
||||
/**
|
||||
* Maps to Disabled. This keeps the client from being broken (by default) if the broker
|
||||
* topic aliasing implementation has a problem.
|
||||
*/
|
||||
Default = AWS_MQTT5_CITABT_DEFAULT,
|
||||
|
||||
/**
|
||||
* Allow the server to send PUBLISH packets to the client that use topic aliasing
|
||||
*/
|
||||
Enabled = AWS_MQTT5_CITABT_ENABLED,
|
||||
|
||||
/**
|
||||
* Forbid the server from sending PUBLISH packets to the client that use topic aliasing
|
||||
*/
|
||||
Disabled = AWS_MQTT5_CITABT_DISABLED,
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration for all client topic aliasing behavior.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API TopicAliasingOptions
|
||||
{
|
||||
|
||||
/**
|
||||
* Controls what kind of outbound topic aliasing behavior the client should attempt to use.
|
||||
*
|
||||
* If topic aliasing is not supported by the server, this setting has no effect and any attempts to
|
||||
* directly manipulate the topic alias id in outbound publishes will be ignored.
|
||||
*
|
||||
* If left undefined, then outbound topic aliasing is disabled.
|
||||
*/
|
||||
Crt::Optional<OutboundTopicAliasBehaviorType> m_outboundBehavior;
|
||||
|
||||
/**
|
||||
* If outbound topic aliasing is set to LRU, this controls the maximum size of the cache. If outbound
|
||||
* topic aliasing is set to LRU and this is zero or undefined, a sensible default is used (25). If
|
||||
* outbound topic aliasing is not set to LRU, then this setting has no effect.
|
||||
*
|
||||
* The final size of the cache is determined by the minimum of this setting and the value of the
|
||||
* topic_alias_maximum property of the received CONNACK. If the received CONNACK does not have an
|
||||
* explicit positive value for that field, outbound topic aliasing is disabled for the duration of that
|
||||
* connection.
|
||||
*/
|
||||
Crt::Optional<uint16_t> m_outboundCacheMaxSize;
|
||||
|
||||
/**
|
||||
* Controls whether or not the client allows the broker to use topic aliasing when sending publishes.
|
||||
* Even if inbound topic aliasing is enabled, it is up to the server to choose whether or not to use it.
|
||||
*
|
||||
* If left undefined, then inbound topic aliasing is disabled.
|
||||
*/
|
||||
Crt::Optional<InboundTopicAliasBehaviorType> m_inboundBehavior;
|
||||
|
||||
/**
|
||||
* If inbound topic aliasing is enabled, this will control the size of the inbound alias cache. If
|
||||
* inbound aliases are enabled and this is zero or undefined, then a sensible default will be used (25).
|
||||
* If inbound aliases are disabled, this setting has no effect.
|
||||
*
|
||||
* Behaviorally, this value overrides anything present in the topic_alias_maximum field of
|
||||
* the CONNECT packet options.
|
||||
*/
|
||||
Crt::Optional<uint16_t> m_inboundCacheMaxSize;
|
||||
};
|
||||
|
||||
struct AWS_CRT_CPP_API ReconnectOptions
|
||||
{
|
||||
/**
|
||||
* Controls how the reconnect delay is modified in order to smooth out the distribution of reconnection
|
||||
* attempt timepoints for a large set of reconnecting clients.
|
||||
*/
|
||||
ExponentialBackoffJitterMode m_reconnectMode;
|
||||
|
||||
/**
|
||||
* Minimum amount of time to wait to reconnect after a disconnect. Exponential backoff is performed
|
||||
* with jitter after each connection failure.
|
||||
*/
|
||||
uint64_t m_minReconnectDelayMs;
|
||||
|
||||
/**
|
||||
* Maximum amount of time to wait to reconnect after a disconnect. Exponential backoff is performed
|
||||
* with jitter after each connection failure.
|
||||
*/
|
||||
uint64_t m_maxReconnectDelayMs;
|
||||
|
||||
/**
|
||||
* Amount of time that must elapse with an established connection before the reconnect delay is reset to
|
||||
* the minimum. This helps alleviate bandwidth-waste in fast reconnect cycles due to permission failures
|
||||
* on operations.
|
||||
*/
|
||||
uint64_t m_minConnectedTimeToResetReconnectDelayMs;
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple statistics about the current state of the client's queue of operations
|
||||
*/
|
||||
struct AWS_CRT_CPP_API Mqtt5ClientOperationStatistics
|
||||
{
|
||||
/**
|
||||
* total number of operations submitted to the client that have not yet been completed. Unacked
|
||||
* operations are a subset of this.
|
||||
*/
|
||||
uint64_t incompleteOperationCount;
|
||||
|
||||
/**
|
||||
* total packet size of operations submitted to the client that have not yet been completed. Unacked
|
||||
* operations are a subset of this.
|
||||
*/
|
||||
uint64_t incompleteOperationSize;
|
||||
|
||||
/**
|
||||
* total number of operations that have been sent to the server and are waiting for a corresponding ACK
|
||||
* before they can be completed.
|
||||
*/
|
||||
uint64_t unackedOperationCount;
|
||||
|
||||
/**
|
||||
* total packet size of operations that have been sent to the server and are waiting for a corresponding
|
||||
* ACK before they can be completed.
|
||||
*/
|
||||
uint64_t unackedOperationSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* The data returned when AttemptingConnect is invoked in the LifecycleEvents callback.
|
||||
* Currently empty, but may be used in the future for passing additional data.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API OnAttemptingConnectEventData
|
||||
{
|
||||
OnAttemptingConnectEventData() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* The data returned when OnConnectionFailure is invoked in the LifecycleEvents callback.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API OnConnectionFailureEventData
|
||||
{
|
||||
OnConnectionFailureEventData() : errorCode(AWS_ERROR_SUCCESS), connAckPacket(nullptr) {}
|
||||
|
||||
int errorCode;
|
||||
std::shared_ptr<ConnAckPacket> connAckPacket;
|
||||
};
|
||||
|
||||
/**
|
||||
* The data returned when OnConnectionSuccess is invoked in the LifecycleEvents callback.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API OnConnectionSuccessEventData
|
||||
{
|
||||
OnConnectionSuccessEventData() : connAckPacket(nullptr), negotiatedSettings(nullptr) {}
|
||||
|
||||
std::shared_ptr<ConnAckPacket> connAckPacket;
|
||||
std::shared_ptr<NegotiatedSettings> negotiatedSettings;
|
||||
};
|
||||
|
||||
/**
|
||||
* The data returned when OnDisconnect is invoked in the LifecycleEvents callback.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API OnDisconnectionEventData
|
||||
{
|
||||
OnDisconnectionEventData() : errorCode(AWS_ERROR_SUCCESS), disconnectPacket(nullptr) {}
|
||||
|
||||
int errorCode;
|
||||
std::shared_ptr<DisconnectPacket> disconnectPacket;
|
||||
};
|
||||
|
||||
/**
|
||||
* The data returned when OnStopped is invoked in the LifecycleEvents callback.
|
||||
* Currently empty, but may be used in the future for passing additional data.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API OnStoppedEventData
|
||||
{
|
||||
OnStoppedEventData() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* The data returned when a publish is made to a topic the MQTT5 client is subscribed to.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API PublishReceivedEventData
|
||||
{
|
||||
PublishReceivedEventData() : publishPacket(nullptr) {}
|
||||
std::shared_ptr<PublishPacket> publishPacket;
|
||||
};
|
||||
|
||||
/**
|
||||
* Type signature of the callback invoked when connection succeed
|
||||
* Mandatory event fields: client, connack_data, settings
|
||||
*/
|
||||
using OnConnectionSuccessHandler = std::function<void(const OnConnectionSuccessEventData &)>;
|
||||
|
||||
/**
|
||||
* Type signature of the callback invoked when connection failed
|
||||
*/
|
||||
using OnConnectionFailureHandler = std::function<void(const OnConnectionFailureEventData &)>;
|
||||
|
||||
/**
|
||||
* Type signature of the callback invoked when the internal connection is shutdown
|
||||
*/
|
||||
using OnDisconnectionHandler = std::function<void(const OnDisconnectionEventData &)>;
|
||||
|
||||
/**
|
||||
* Type signature of the callback invoked when attempting connect to client
|
||||
* Mandatory event fields: client
|
||||
*/
|
||||
using OnAttemptingConnectHandler = std::function<void(const OnAttemptingConnectEventData &)>;
|
||||
|
||||
/**
|
||||
* Type signature of the callback invoked when client connection stopped
|
||||
* Mandatory event fields: client
|
||||
*/
|
||||
using OnStoppedHandler = std::function<void(const OnStoppedEventData &)>;
|
||||
|
||||
/**
|
||||
* Type signature of the callback invoked when a Publish Complete
|
||||
*/
|
||||
using OnPublishCompletionHandler = std::function<void(int, std::shared_ptr<PublishResult>)>;
|
||||
|
||||
/**
|
||||
* Type signature of the callback invoked when a Subscribe Complete
|
||||
*/
|
||||
using OnSubscribeCompletionHandler = std::function<void(int, std::shared_ptr<SubAckPacket>)>;
|
||||
|
||||
/**
|
||||
* Type signature of the callback invoked when a Unsubscribe Complete
|
||||
*/
|
||||
using OnUnsubscribeCompletionHandler = std::function<void(int, std::shared_ptr<UnSubAckPacket>)>;
|
||||
|
||||
/**
|
||||
* Type signature of the callback invoked when a PacketPublish message received (OnMessageHandler)
|
||||
*/
|
||||
using OnPublishReceivedHandler = std::function<void(const PublishReceivedEventData &)>;
|
||||
|
||||
/**
|
||||
* Callback for users to invoke upon completion of, presumably asynchronous, OnWebSocketHandshakeIntercept
|
||||
* callback's initiated process.
|
||||
*/
|
||||
using OnWebSocketHandshakeInterceptComplete =
|
||||
std::function<void(const std::shared_ptr<Http::HttpRequest> &, int)>;
|
||||
|
||||
/**
|
||||
* Invoked during websocket handshake to give users opportunity to transform an http request for purposes
|
||||
* such as signing/authorization etc... Returning from this function does not continue the websocket
|
||||
* handshake since some work flows may be asynchronous. To accommodate that, onComplete must be invoked upon
|
||||
* completion of the signing process.
|
||||
*/
|
||||
using OnWebSocketHandshakeIntercept =
|
||||
std::function<void(std::shared_ptr<Http::HttpRequest>, const OnWebSocketHandshakeInterceptComplete &)>;
|
||||
|
||||
/**
|
||||
* An MQTT5 client. This is a move-only type. Unless otherwise specified,
|
||||
* all function arguments need only to live through the duration of the
|
||||
* function call.
|
||||
*/
|
||||
class AWS_CRT_CPP_API Mqtt5Client final : public std::enable_shared_from_this<Mqtt5Client>
|
||||
{
|
||||
friend class Mqtt::MqttConnection;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Factory function for mqtt5 client
|
||||
*
|
||||
* @param options: Mqtt5 Client Options
|
||||
* @param allocator allocator to use
|
||||
* @return a new mqtt5 client
|
||||
*/
|
||||
static std::shared_ptr<Mqtt5Client> NewMqtt5Client(
|
||||
const Mqtt5ClientOptions &options,
|
||||
Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Get shared poitner of the Mqtt5Client. Mqtt5Client is inherited to enable_shared_from_this to help
|
||||
* with memory safety.
|
||||
*
|
||||
* @return shared_ptr for the Mqtt5Client
|
||||
*/
|
||||
std::shared_ptr<Mqtt5Client> getptr() { return shared_from_this(); }
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const noexcept;
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int LastError() const noexcept;
|
||||
|
||||
/**
|
||||
* Notifies the MQTT5 client that you want it to attempt to connect to the configured endpoint.
|
||||
* The client will attempt to stay connected using the properties of the reconnect-related parameters
|
||||
* from the client configuration.
|
||||
*
|
||||
* @return bool: true if operation succeed, otherwise false.
|
||||
*/
|
||||
bool Start() const noexcept;
|
||||
|
||||
/**
|
||||
* Notifies the MQTT5 client that you want it to transition to the stopped state, disconnecting any
|
||||
* existing connection and stopping subsequent reconnect attempts.
|
||||
*
|
||||
* @return bool: true if operation succeed, otherwise false
|
||||
*/
|
||||
bool Stop() noexcept;
|
||||
|
||||
/**
|
||||
* Notifies the MQTT5 client that you want it to transition to the stopped state, disconnecting any
|
||||
* existing connection and stopping subsequent reconnect attempts.
|
||||
*
|
||||
* @param disconnectPacket (optional) properties of a DISCONNECT packet to send as part of the shutdown
|
||||
* process
|
||||
*
|
||||
* @return bool: true if operation succeed, otherwise false
|
||||
*/
|
||||
bool Stop(std::shared_ptr<DisconnectPacket> disconnectPacket) noexcept;
|
||||
|
||||
/**
|
||||
* Tells the client to attempt to send a PUBLISH packet
|
||||
*
|
||||
* @param publishPacket: packet PUBLISH to send to the server
|
||||
* @param onPublishCompletionCallback: callback on publish complete, default to NULL
|
||||
*
|
||||
* @return true if the publish operation succeed otherwise false
|
||||
*/
|
||||
bool Publish(
|
||||
std::shared_ptr<PublishPacket> publishPacket,
|
||||
OnPublishCompletionHandler onPublishCompletionCallback = NULL) noexcept;
|
||||
|
||||
/**
|
||||
* Tells the client to attempt to subscribe to one or more topic filters.
|
||||
*
|
||||
* @param subscribePacket: SUBSCRIBE packet to send to the server
|
||||
* @param onSubscribeCompletionCallback: callback on subscribe complete, default to NULL
|
||||
*
|
||||
* @return true if the subscription operation succeed otherwise false
|
||||
*/
|
||||
bool Subscribe(
|
||||
std::shared_ptr<SubscribePacket> subscribePacket,
|
||||
OnSubscribeCompletionHandler onSubscribeCompletionCallback = NULL) noexcept;
|
||||
|
||||
/**
|
||||
* Tells the client to attempt to unsubscribe to one or more topic filters.
|
||||
*
|
||||
* @param unsubscribePacket: UNSUBSCRIBE packet to send to the server
|
||||
* @param onUnsubscribeCompletionCallback: callback on unsubscribe complete, default to NULL
|
||||
*
|
||||
* @return true if the unsubscription operation succeed otherwise false
|
||||
*/
|
||||
bool Unsubscribe(
|
||||
std::shared_ptr<UnsubscribePacket> unsubscribePacket,
|
||||
OnUnsubscribeCompletionHandler onUnsubscribeCompletionCallback = NULL) noexcept;
|
||||
|
||||
/**
|
||||
* Get the statistics about the current state of the client's queue of operations
|
||||
*
|
||||
* @return Mqtt5ClientOperationStatistics
|
||||
*/
|
||||
const Mqtt5ClientOperationStatistics &GetOperationStatistics() noexcept;
|
||||
|
||||
virtual ~Mqtt5Client();
|
||||
|
||||
private:
|
||||
Mqtt5Client(const Mqtt5ClientOptions &options, Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/* The client core to handle the user callbacks and c client termination */
|
||||
std::shared_ptr<Mqtt5ClientCore> m_client_core;
|
||||
|
||||
Mqtt5ClientOperationStatistics m_operationStatistics;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration interface for mqtt5 clients
|
||||
*/
|
||||
class AWS_CRT_CPP_API Mqtt5ClientOptions final
|
||||
{
|
||||
friend class Mqtt5ClientCore;
|
||||
friend class Mqtt5to3AdapterOptions;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default constructior of Mqtt5ClientOptions
|
||||
*/
|
||||
Mqtt5ClientOptions(Crt::Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Sets host to connect to.
|
||||
*
|
||||
* @param hostname endpoint to connect to
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithHostName(Crt::String hostname);
|
||||
|
||||
/**
|
||||
* Set port to connect to
|
||||
*
|
||||
* @param port port to connect to
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithPort(uint32_t port) noexcept;
|
||||
|
||||
/**
|
||||
* Set booststrap for mqtt5 client
|
||||
*
|
||||
* @param bootStrap bootstrap used for mqtt5 client. The default ClientBootstrap see
|
||||
* Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap.
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithBootstrap(Io::ClientBootstrap *bootStrap) noexcept;
|
||||
|
||||
/**
|
||||
* Sets the aws socket options
|
||||
*
|
||||
* @param socketOptions Io::SocketOptions used to setup socket
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithSocketOptions(Io::SocketOptions socketOptions) noexcept;
|
||||
|
||||
/**
|
||||
* Sets the tls connection options
|
||||
*
|
||||
* @param tslOptions Io::TlsConnectionOptions
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithTlsConnectionOptions(const Io::TlsConnectionOptions &tslOptions) noexcept;
|
||||
|
||||
/**
|
||||
* Sets http proxy options.
|
||||
*
|
||||
* @param proxyOptions http proxy configuration for connection establishment
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithHttpProxyOptions(
|
||||
const Crt::Http::HttpClientConnectionProxyOptions &proxyOptions) noexcept;
|
||||
|
||||
/**
|
||||
* Sets mqtt5 connection options
|
||||
*
|
||||
* @param connectPacket package connection options
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithConnectOptions(std::shared_ptr<ConnectPacket> connectPacket) noexcept;
|
||||
|
||||
/**
|
||||
* Sets session behavior. Overrides how the MQTT5 client should behave with respect to MQTT sessions.
|
||||
*
|
||||
* @param sessionBehavior
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithSessionBehavior(ClientSessionBehaviorType sessionBehavior) noexcept;
|
||||
|
||||
/**
|
||||
* Sets client extended validation and flow control, additional controls for client behavior with
|
||||
* respect to operation validation and flow control; these checks go beyond the base MQTT5 spec to
|
||||
* respect limits of specific MQTT brokers.
|
||||
*
|
||||
* @param clientExtendedValidationAndFlowControl
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithClientExtendedValidationAndFlowControl(
|
||||
ClientExtendedValidationAndFlowControl clientExtendedValidationAndFlowControl) noexcept;
|
||||
|
||||
/**
|
||||
* Sets OfflineQueueBehavior, controls how disconnects affect the queued and in-progress operations
|
||||
* tracked by the client. Also controls how new operations are handled while the client is not
|
||||
* connected. In particular, if the client is not connected, then any operation that would be failed
|
||||
* on disconnect (according to these rules) will also be rejected.
|
||||
*
|
||||
* @param offlineQueueBehavior
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithOfflineQueueBehavior(
|
||||
ClientOperationQueueBehaviorType offlineQueueBehavior) noexcept;
|
||||
|
||||
/**
|
||||
* Sets ReconnectOptions. Reconnect options, includes retryJitterMode, min reconnect delay time and
|
||||
* max reconnect delay time and reset reconnect delay time
|
||||
*
|
||||
* @param reconnectOptions
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithReconnectOptions(ReconnectOptions reconnectOptions) noexcept;
|
||||
|
||||
/**
|
||||
* Sets the topic aliasing behavior for the client.
|
||||
*
|
||||
* @param topicAliasingOptions topic aliasing behavior options to use
|
||||
* @return this options object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithTopicAliasingOptions(TopicAliasingOptions topicAliasingOptions) noexcept;
|
||||
|
||||
/**
|
||||
* Sets ping timeout (ms). Time interval to wait after sending a PINGREQ for a PINGRESP to arrive.
|
||||
* If one does not arrive, the client will close the current connection.
|
||||
*
|
||||
* @param pingTimeoutMs
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithPingTimeoutMs(uint32_t pingTimeoutMs) noexcept;
|
||||
|
||||
/**
|
||||
* Sets Connack Timeout (ms). Time interval to wait after sending a CONNECT request for a CONNACK
|
||||
* to arrive. If one does not arrive, the connection will be shut down.
|
||||
*
|
||||
* @param connackTimeoutMs
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithConnackTimeoutMs(uint32_t connackTimeoutMs) noexcept;
|
||||
|
||||
/**
|
||||
* @deprecated The function is deprecated, please use `Mqtt5ClientOptions::WithAckTimeoutSec(uint32_t)`
|
||||
*
|
||||
* Sets Operation Timeout(Seconds). Time interval to wait for an ack after sending a QoS 1+ PUBLISH,
|
||||
* SUBSCRIBE, or UNSUBSCRIBE before failing the operation.
|
||||
*
|
||||
* @param ackTimeoutSec
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithAckTimeoutSeconds(uint32_t ackTimeoutSec) noexcept;
|
||||
|
||||
/**
|
||||
* Sets Operation Timeout(Seconds). Time interval to wait for an ack after sending a QoS 1+ PUBLISH,
|
||||
* SUBSCRIBE, or UNSUBSCRIBE before failing the operation.
|
||||
*
|
||||
* @param ackTimeoutSec
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithAckTimeoutSec(uint32_t ackTimeoutSec) noexcept;
|
||||
|
||||
/**
|
||||
* Sets callback for transform HTTP request.
|
||||
* This callback allows a custom transformation of the HTTP request that acts as the websocket
|
||||
* handshake. Websockets will be used if this is set to a valid transformation callback. To use
|
||||
* websockets but not perform a transformation, just set this as a trivial completion callback. If
|
||||
* undefined, the connection will be made with direct MQTT.
|
||||
*
|
||||
* @param callback
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithWebsocketHandshakeTransformCallback(
|
||||
OnWebSocketHandshakeIntercept callback) noexcept;
|
||||
|
||||
/**
|
||||
* Sets callback trigged when client successfully establishes an MQTT connection
|
||||
*
|
||||
* @param callback
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithClientConnectionSuccessCallback(OnConnectionSuccessHandler callback) noexcept;
|
||||
|
||||
/**
|
||||
* Sets callback trigged when client fails to establish an MQTT connection
|
||||
*
|
||||
* @param callback
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithClientConnectionFailureCallback(OnConnectionFailureHandler callback) noexcept;
|
||||
|
||||
/**
|
||||
* Sets callback trigged when client's current MQTT connection is closed
|
||||
*
|
||||
* @param callback
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithClientDisconnectionCallback(OnDisconnectionHandler callback) noexcept;
|
||||
|
||||
/**
|
||||
* Sets callback trigged when client reaches the "Stopped" state
|
||||
*
|
||||
* @param callback
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithClientStoppedCallback(OnStoppedHandler callback) noexcept;
|
||||
|
||||
/**
|
||||
* Sets callback trigged when client begins an attempt to connect to the remote endpoint.
|
||||
*
|
||||
* @param callback
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithClientAttemptingConnectCallback(OnAttemptingConnectHandler callback) noexcept;
|
||||
|
||||
/**
|
||||
* Sets callback trigged when a PUBLISH packet is received by the client
|
||||
*
|
||||
* @param callback
|
||||
*
|
||||
* @return this option object
|
||||
*/
|
||||
Mqtt5ClientOptions &WithPublishReceivedCallback(OnPublishReceivedHandler callback) noexcept;
|
||||
|
||||
/**
|
||||
* Initializes the C aws_mqtt5_client_options from Mqtt5ClientOptions. For internal use
|
||||
*
|
||||
* @param raw_options - output parameter containing low level client options to be passed to the C
|
||||
* interface
|
||||
*
|
||||
*/
|
||||
bool initializeRawOptions(aws_mqtt5_client_options &raw_options) const noexcept;
|
||||
|
||||
virtual ~Mqtt5ClientOptions();
|
||||
Mqtt5ClientOptions(const Mqtt5ClientOptions &) = delete;
|
||||
Mqtt5ClientOptions(Mqtt5ClientOptions &&) = delete;
|
||||
Mqtt5ClientOptions &operator=(const Mqtt5ClientOptions &) = delete;
|
||||
Mqtt5ClientOptions &operator=(Mqtt5ClientOptions &&) = delete;
|
||||
|
||||
private:
|
||||
/**
|
||||
* This callback allows a custom transformation of the HTTP request that acts as the websocket
|
||||
* handshake. Websockets will be used if this is set to a valid transformation callback. To use
|
||||
* websockets but not perform a transformation, just set this as a trivial completion callback. If
|
||||
* undefined, the connection will be made with direct MQTT.
|
||||
*/
|
||||
OnWebSocketHandshakeIntercept websocketHandshakeTransform;
|
||||
|
||||
/**
|
||||
* Callback handler trigged when client successfully establishes an MQTT connection
|
||||
*/
|
||||
OnConnectionSuccessHandler onConnectionSuccess;
|
||||
|
||||
/**
|
||||
* Callback handler trigged when client fails to establish an MQTT connection
|
||||
*/
|
||||
OnConnectionFailureHandler onConnectionFailure;
|
||||
|
||||
/**
|
||||
* Callback handler trigged when client's current MQTT connection is closed
|
||||
*/
|
||||
OnDisconnectionHandler onDisconnection;
|
||||
|
||||
/**
|
||||
* Callback handler trigged when client reaches the "Stopped" state
|
||||
*
|
||||
* @param Mqtt5Client: The shared client
|
||||
*/
|
||||
OnStoppedHandler onStopped;
|
||||
|
||||
/**
|
||||
* Callback handler trigged when client begins an attempt to connect to the remote endpoint.
|
||||
*
|
||||
* @param Mqtt5Client: The shared client
|
||||
*/
|
||||
OnAttemptingConnectHandler onAttemptingConnect;
|
||||
|
||||
/**
|
||||
* Callback handler trigged when an MQTT PUBLISH packet is received by the client
|
||||
*
|
||||
* @param Mqtt5Client: The shared client
|
||||
* @param PublishPacket: received Publish Packet
|
||||
*/
|
||||
OnPublishReceivedHandler onPublishReceived;
|
||||
|
||||
/**
|
||||
* Host name of the MQTT server to connect to.
|
||||
*/
|
||||
Crt::String m_hostName;
|
||||
|
||||
/**
|
||||
* Network port of the MQTT server to connect to.
|
||||
*/
|
||||
uint32_t m_port;
|
||||
|
||||
/**
|
||||
* Client bootstrap to use. In almost all cases, this can be left undefined.
|
||||
*/
|
||||
Io::ClientBootstrap *m_bootstrap;
|
||||
|
||||
/**
|
||||
* Controls socket properties of the underlying MQTT connections made by the client. Leave undefined to
|
||||
* use defaults (no TCP keep alive, 10 second socket timeout).
|
||||
*/
|
||||
Crt::Io::SocketOptions m_socketOptions;
|
||||
|
||||
/**
|
||||
* TLS context for secure socket connections.
|
||||
* If undefined, a plaintext connection will be used.
|
||||
*/
|
||||
Crt::Optional<Crt::Io::TlsConnectionOptions> m_tlsConnectionOptions;
|
||||
|
||||
/**
|
||||
* Configures (tunneling) HTTP proxy usage when establishing MQTT connections
|
||||
*/
|
||||
Crt::Optional<Crt::Http::HttpClientConnectionProxyOptions> m_proxyOptions;
|
||||
|
||||
/**
|
||||
* All configurable options with respect to the CONNECT packet sent by the client, including the will.
|
||||
* These connect properties will be used for every connection attempt made by the client.
|
||||
*/
|
||||
std::shared_ptr<ConnectPacket> m_connectOptions;
|
||||
|
||||
/**
|
||||
* Controls how the MQTT5 client should behave with respect to MQTT sessions.
|
||||
*/
|
||||
ClientSessionBehaviorType m_sessionBehavior;
|
||||
|
||||
/**
|
||||
* Additional controls for client behavior with respect to operation validation and flow control; these
|
||||
* checks go beyond the base MQTT5 spec to respect limits of specific MQTT brokers.
|
||||
*/
|
||||
ClientExtendedValidationAndFlowControl m_extendedValidationAndFlowControlOptions;
|
||||
|
||||
/**
|
||||
* Controls how disconnects affect the queued and in-progress operations tracked by the client. Also
|
||||
* controls how new operations are handled while the client is not connected. In particular, if the
|
||||
* client is not connected, then any operation that would be failed on disconnect (according to these
|
||||
* rules) will also be rejected.
|
||||
*/
|
||||
ClientOperationQueueBehaviorType m_offlineQueueBehavior;
|
||||
|
||||
/**
|
||||
* Reconnect options, includes retryJitterMode, min reconnect delay time and max reconnect delay time
|
||||
*/
|
||||
ReconnectOptions m_reconnectionOptions;
|
||||
|
||||
/**
|
||||
* Controls client topic aliasing behavior
|
||||
*/
|
||||
aws_mqtt5_client_topic_alias_options m_topicAliasingOptions;
|
||||
|
||||
/**
|
||||
* Time interval to wait after sending a PINGREQ for a PINGRESP to arrive. If one does not arrive, the
|
||||
* client will close the current connection.
|
||||
*/
|
||||
uint32_t m_pingTimeoutMs;
|
||||
|
||||
/**
|
||||
* Time interval to wait after sending a CONNECT request for a CONNACK to arrive. If one does not
|
||||
* arrive, the connection will be shut down.
|
||||
*/
|
||||
uint32_t m_connackTimeoutMs;
|
||||
|
||||
/**
|
||||
* Time interval to wait for an ack after sending a QoS 1+ PUBLISH, SUBSCRIBE, or UNSUBSCRIBE before
|
||||
* failing the operation.
|
||||
*/
|
||||
uint32_t m_ackTimeoutSec;
|
||||
|
||||
/* Underlying Parameters */
|
||||
Crt::Allocator *m_allocator;
|
||||
aws_http_proxy_options m_httpProxyOptionsStorage;
|
||||
aws_mqtt5_packet_connect_view m_packetConnectViewStorage;
|
||||
};
|
||||
|
||||
} // namespace Mqtt5
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,313 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/mqtt/v5/mqtt5_client.h>
|
||||
#include <aws/mqtt/v5/mqtt5_types.h>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Mqtt5
|
||||
{
|
||||
/**
|
||||
* MQTT message delivery quality of service.
|
||||
*
|
||||
* Enum values match [MQTT5
|
||||
* spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901234) encoding values.
|
||||
*
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_QOS_AT_MOST_ONCE</TD><TD>https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901235</TD>
|
||||
* <TR><TD>AWS_MQTT5_QOS_AT_LEAST_ONCE</TD><TD>https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901236</TD>
|
||||
* <TR><TD>AWS_MQTT5_QOS_EXACTLY_ONCE</TD><TD>https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901237</TD>
|
||||
* </TABLE>
|
||||
*
|
||||
*/
|
||||
using QOS = aws_mqtt5_qos;
|
||||
|
||||
/**
|
||||
* Server return code for connect attempts.
|
||||
*
|
||||
* Enum values match [MQTT5
|
||||
* spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901079) encoding values.
|
||||
*
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_CRC_SUCCESS</TD><TD>0</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_UNSPECIFIED_ERROR</TD><TD>128</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_MALFORMED_PACKET</TD><TD>129</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_PROTOCOL_ERROR</TD><TD>130</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_IMPLEMENTATION_SPECIFIC_ERROR</TD><TD>131</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_UNSUPPORTED_PROTOCOL_VERSION</TD><TD>132</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_CLIENT_IDENTIFIER_NOT_VALID</TD><TD>133</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_BAD_USERNAME_OR_PASSWORD</TD><TD>134</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_NOT_AUTHORIZED</TD><TD>135</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_SERVER_UNAVAILABLE</TD><TD>136</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_SERVER_BUSY</TD><TD>137</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_BANNED</TD><TD>138</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_BAD_AUTHENTICATION_METHOD</TD><TD>140</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_TOPIC_NAME_INVALID</TD><TD>144</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_PACKET_TOO_LARGE</TD><TD>149</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_QUOTA_EXCEEDED</TD><TD>151</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_PAYLOAD_FORMAT_INVALID</TD><TD>153</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_RETAIN_NOT_SUPPORTED</TD><TD>154</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_QOS_NOT_SUPPORTED</TD><TD>155</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_USE_ANOTHER_SERVER</TD><TD>156</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_SERVER_MOVED</TD><TD>157</TD>
|
||||
* <TR><TD>AWS_MQTT5_CRC_CONNECTION_RATE_EXCEEDED</TD><TD>159</TD>
|
||||
* </TABLE>
|
||||
*
|
||||
*
|
||||
*/
|
||||
using ConnectReasonCode = aws_mqtt5_connect_reason_code;
|
||||
|
||||
/**
|
||||
* Reason code inside DISCONNECT packets. Helps determine why a connection was terminated.
|
||||
*
|
||||
* Enum values match [MQTT5
|
||||
* spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901208) encoding values.
|
||||
*
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_DRC_NORMAL_DISCONNECTION</TD><TD>0</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_DISCONNECT_WITH_WILL_MESSAGE</TD><TD>4</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_UNSPECIFIED_ERROR</TD><TD>128</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_MALFORMED_PACKET</TD><TD>129</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_PROTOCOL_ERROR</TD><TD>130</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_IMPLEMENTATION_SPECIFIC_ERROR</TD><TD>131</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_NOT_AUTHORIZED</TD><TD>135</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_SERVER_BUSY</TD><TD>137</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_SERVER_SHUTTING_DOWN</TD><TD>139</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_KEEP_ALIVE_TIMEOUT</TD><TD>141</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_SESSION_TAKEN_OVER</TD><TD>142</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_TOPIC_FILTER_INVALID</TD><TD>143</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_TOPIC_NAME_INVALID</TD><TD>144</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_RECEIVE_MAXIMUM_EXCEEDED</TD><TD>147</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_TOPIC_ALIAS_INVALID</TD><TD>148</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_PACKET_TOO_LARGE</TD><TD>149</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_MESSAGE_RATE_TOO_HIGH</TD><TD>150</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_QUOTA_EXCEEDED</TD><TD>151</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_ADMINISTRATIVE_ACTION</TD><TD>152</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_PAYLOAD_FORMAT_INVALID</TD><TD>153</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_RETAIN_NOT_SUPPORTED</TD><TD>154</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_QOS_NOT_SUPPORTED</TD><TD>155</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_USE_ANOTHER_SERVER</TD><TD>156</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_SERVER_MOVED</TD><TD>157</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED</TD><TD>158</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_CONNECTION_RATE_EXCEEDED</TD><TD>159</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_MAXIMUM_CONNECT_TIME</TD><TD>160</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED</TD><TD>161</TD>
|
||||
* <TR><TD>AWS_MQTT5_DRC_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED</TD><TD>162</TD>
|
||||
* </TABLE>
|
||||
*
|
||||
*/
|
||||
using DisconnectReasonCode = aws_mqtt5_disconnect_reason_code;
|
||||
|
||||
/**
|
||||
* Reason code inside PUBACK packets
|
||||
*
|
||||
* Data model of an [MQTT5
|
||||
* PUBACK](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901121) packet
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_PARC_SUCCESS</TD><TD>0</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_NO_MATCHING_SUBSCRIBERS</TD><TD>16</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_UNSPECIFIED_ERROR</TD><TD>128</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_IMPLEMENTATION_SPECIFIC_ERROR</TD><TD>131</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_NOT_AUTHORIZED</TD><TD>135</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_TOPIC_NAME_INVALID</TD><TD>144</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_PACKET_IDENTIFIER_IN_USE</TD><TD>145</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_QUOTA_EXCEEDED</TD><TD>151</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_PAYLOAD_FORMAT_INVALID</TD><TD>153</TD>
|
||||
* </TABLE>
|
||||
*/
|
||||
using PubAckReasonCode = aws_mqtt5_puback_reason_code;
|
||||
|
||||
/**
|
||||
* Reason code inside PUBACK packets that indicates the result of the associated PUBLISH request.
|
||||
*
|
||||
* Enum values match [MQTT5
|
||||
* spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901124) encoding values.
|
||||
*
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_PARC_SUCCESS</TD><TD>0</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_NO_MATCHING_SUBSCRIBERS</TD><TD>16</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_UNSPECIFIED_ERROR</TD><TD>128</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_IMPLEMENTATION_SPECIFIC_ERROR</TD><TD>131</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_NOT_AUTHORIZED</TD><TD>135</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_TOPIC_NAME_INVALID</TD><TD>144</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_PACKET_IDENTIFIER_IN_USE</TD><TD>145</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_QUOTA_EXCEEDED</TD><TD>151</TD>
|
||||
* <TR><TD>AWS_MQTT5_PARC_PAYLOAD_FORMAT_INVALID</TD><TD>153</TD>
|
||||
* </TABLE>
|
||||
*/
|
||||
using SubAckReasonCode = aws_mqtt5_suback_reason_code;
|
||||
|
||||
/**
|
||||
* Reason codes inside UNSUBACK packet payloads that specify the results for each topic filter in the
|
||||
* associated UNSUBSCRIBE packet.
|
||||
*
|
||||
* Enum values match [MQTT5
|
||||
* spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901194) encoding values.
|
||||
*
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_UARC_SUCCESS</TD><TD>0</TD>
|
||||
* <TR><TD>AWS_MQTT5_UARC_NO_SUBSCRIPTION_EXISTED</TD><TD>17</TD>
|
||||
* <TR><TD>AWS_MQTT5_UARC_UNSPECIFIED_ERROR</TD><TD>128</TD>
|
||||
* <TR><TD>AWS_MQTT5_UARC_IMPLEMENTATION_SPECIFIC_ERROR</TD><TD>131</TD>
|
||||
* <TR><TD>AWS_MQTT5_UARC_NOT_AUTHORIZED</TD><TD>135</TD>
|
||||
* <TR><TD>AWS_MQTT5_UARC_TOPIC_FILTER_INVALID</TD><TD>143</TD>
|
||||
* <TR><TD>AWS_MQTT5_UARC_PACKET_IDENTIFIER_IN_USE</TD><TD>145</TD>
|
||||
* </TABLE>
|
||||
*
|
||||
*/
|
||||
using UnSubAckReasonCode = aws_mqtt5_unsuback_reason_code;
|
||||
|
||||
/**
|
||||
* Controls how the MQTT5 client should behave with respect to MQTT sessions.
|
||||
*
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_CSBT_DEFAULT</TD><TD>Maps to AWS_MQTT5_CSBT_CLEAN</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_CSBT_CLEAN</TD><TD>Always join a new, clean session</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_CSBT_REJOIN_POST_SUCCESS</TD><TD>Always attempt to rejoin an existing session after an
|
||||
* initial connection success.</TD></TR> <TR><TD>AWS_MQTT5_CSBT_REJOIN_ALWAYS</TD><TD>Always attempt to
|
||||
* rejoin an existing session. Since the client does not support durable session persistence, this option is
|
||||
* not guaranteed to be spec compliant because any unacknowledged qos1 publishes (which are part of the
|
||||
* client session state) will not be present on the initial connection. Until we support durable session
|
||||
* resumption, this option is technically spec-breaking, but useful.</TD></TR>
|
||||
* </TABLE>
|
||||
*/
|
||||
using ClientSessionBehaviorType = aws_mqtt5_client_session_behavior_type;
|
||||
|
||||
/**
|
||||
* Additional controls for client behavior with respect to operation validation and flow control; these
|
||||
* checks go beyond the MQTT5 spec to respect limits of specific MQTT brokers.
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_EVAFCO_NONE</TD><TD>Do not do any additional validation or flow control outside of the
|
||||
* MQTT5 spec</TD></TR> <TR><TD>AWS_MQTT5_EVAFCO_AWS_IOT_CORE_DEFAULTS</TD><TD>Apply additional client-side
|
||||
* operational flow control that respects the default AWS IoT Core limits. Applies the following flow
|
||||
* control: (1) Outbound throughput throttled to 512KB/s (2) Outbound publish TPS throttled to 100</TD></TR>
|
||||
* </TABLE>
|
||||
*
|
||||
*/
|
||||
using ClientExtendedValidationAndFlowControl = aws_mqtt5_extended_validation_and_flow_control_options;
|
||||
|
||||
/**
|
||||
* Controls how disconnects affect the queued and in-progress operations tracked by the client. Also
|
||||
* controls how operations are handled while the client is not connected. In particular, if the client is
|
||||
* not connected, then any operation that would be failed on disconnect (according to these rules) will be
|
||||
* rejected.
|
||||
*
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_COQBT_DEFAULT</TD><TD>Maps to AWS_MQTT5_COQBT_FAIL_QOS0_PUBLISH_ON_DISCONNECT</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_COQBT_FAIL_NON_QOS1_PUBLISH_ON_DISCONNECT</TD><TD>Requeues QoS 1+ publishes on
|
||||
* disconnect; unacked publishes go to the front, unprocessed publishes stay in place. All other operations
|
||||
* (QoS 0 publishes, subscribe, unsubscribe) are failed.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_COQBT_FAIL_QOS0_PUBLISH_ON_DISCONNECT</TD><TD>Qos 0 publishes that are not complete at
|
||||
* the time of disconnection are failed. Unacked QoS 1+ publishes are requeued at the head of the line for
|
||||
* immediate retransmission on a session resumption. All other operations are requeued in the original order
|
||||
* behind any retransmissions.</TD></TR> <TR><TD>AWS_MQTT5_COQBT_FAIL_ALL_ON_DISCONNECT</TD><TD>All
|
||||
* operations that are not complete at the time of disconnection are failed, except those operations that
|
||||
* the MQTT 5 spec requires to be retransmitted (unacked QoS 1+ publishes).</TD></TR>
|
||||
* </TABLE>
|
||||
*
|
||||
*/
|
||||
using ClientOperationQueueBehaviorType = aws_mqtt5_client_operation_queue_behavior_type;
|
||||
|
||||
/**
|
||||
* Controls how the reconnect delay is modified in order to smooth out the distribution of reconnection
|
||||
* attempt timepoints for a large set of reconnecting clients.
|
||||
*
|
||||
* See [Exponential Backoff and
|
||||
* Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/)
|
||||
*
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_EXPONENTIAL_BACKOFF_JITTER_DEFAULT</TD><TD>Uses AWS_EXPONENTIAL_BACKOFF_JITTER_FULL</TD></TR>
|
||||
* <TR><TD>AWS_EXPONENTIAL_BACKOFF_JITTER_NONE</TD><TD>No jitter is applied to the exponential
|
||||
* backoff</TD></TR> <TR><TD>AWS_EXPONENTIAL_BACKOFF_JITTER_FULL</TD><TD>Full jitter is applied to the
|
||||
* exponential backoff</TD></TR> <TR><TD>AWS_EXPONENTIAL_BACKOFF_JITTER_DECORRELATED</TD><TD>Jitter is
|
||||
* decorrelated from the backoff sequence</TD></TR>
|
||||
* </TABLE>
|
||||
*
|
||||
*/
|
||||
using ExponentialBackoffJitterMode = aws_exponential_backoff_jitter_mode;
|
||||
|
||||
/** @deprecated JitterMode is deprecated, please use Aws::Crt::Mqtt5::ExponentialBackoffJitterMode */
|
||||
using JitterMode = ExponentialBackoffJitterMode;
|
||||
|
||||
/**
|
||||
* Optional property describing a PUBLISH payload's format.
|
||||
*
|
||||
* Enum values match [MQTT5
|
||||
* spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901111) encoding values.
|
||||
*
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_PFI_BYTES</TD><TD>Bytes format.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PFI_UTF8</TD><TD>UTF-8 format.</TD></TR>
|
||||
* </TABLE>
|
||||
*/
|
||||
using PayloadFormatIndicator = aws_mqtt5_payload_format_indicator;
|
||||
|
||||
/**
|
||||
* Configures how retained messages should be handled when subscribing with a topic filter that matches
|
||||
* topics with associated retained messages.
|
||||
*
|
||||
* Enum values match [MQTT5
|
||||
* spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169) encoding values.
|
||||
*
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE</TD><TD>Server should send all retained messages on topics that
|
||||
* match the subscription's filter.</TD></TR> <TR><TD>AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE_IF_NEW</TD><TD>Server
|
||||
* should send all retained messages on topics that match the subscription's filter, where this is the first
|
||||
* (relative to connection) subscription filter that matches the topic with a retained message.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_RHT_DONT_SEND</TD><TD>Subscribe must not trigger any retained message publishes from
|
||||
* the server.</TD></TR>
|
||||
* </TABLE>
|
||||
*/
|
||||
using RetainHandlingType = aws_mqtt5_retain_handling_type;
|
||||
|
||||
/**
|
||||
* Type of mqtt packet.
|
||||
* Enum values match mqtt spec encoding values.
|
||||
*
|
||||
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901022
|
||||
*
|
||||
* <TABLE>
|
||||
* <TR><TH colspan="2">Enumerator</TH>
|
||||
* <TR><TD>AWS_MQTT5_PT_NONE</TD><TD>Internal indicator that the associated packet is null.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_RESERVED</TD><TD>Reserved.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_CONNECT</TD><TD>CONNECT packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_CONNACK</TD><TD>CONNACK packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_PUBLISH</TD><TD>PUBLISH packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_PUBACK</TD><TD>PUBACK packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_PUBREC</TD><TD>PUBREC packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_PUBREL</TD><TD>PUBREL packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_PUBCOMP</TD><TD>PUBCOMP packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_SUBSCRIBE</TD><TD>SUBSCRIBE packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_SUBACK</TD><TD>SUBACK packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_UNSUBSCRIBE</TD><TD>UNSUBSCRIBE packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_UNSUBACK</TD><TD>UNSUBACK packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_PINGREQ</TD><TD>PINGREQ packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_PINGRESP</TD><TD>PINGRESP packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_DISCONNECT</TD><TD>DISCONNECT packet.</TD></TR>
|
||||
* <TR><TD>AWS_MQTT5_PT_AUTH</TD><TD>AUTH packet.</TD></TR>
|
||||
* </TABLE>
|
||||
*
|
||||
*/
|
||||
using PacketType = aws_mqtt5_packet_type;
|
||||
|
||||
} // namespace Mqtt5
|
||||
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,121 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/StlAllocator.h>
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/crt/http/HttpConnection.h>
|
||||
#include <aws/crt/io/SocketOptions.h>
|
||||
#include <aws/crt/io/TlsOptions.h>
|
||||
#include <aws/crt/mqtt/MqttConnection.h>
|
||||
|
||||
#include <aws/mqtt/client.h>
|
||||
#include <aws/mqtt/v5/mqtt5_client.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Io
|
||||
{
|
||||
class ClientBootstrap;
|
||||
}
|
||||
|
||||
namespace Http
|
||||
{
|
||||
class HttpRequest;
|
||||
}
|
||||
|
||||
namespace Mqtt5
|
||||
{
|
||||
class Mqtt5ClientCore;
|
||||
}
|
||||
|
||||
namespace Mqtt
|
||||
{
|
||||
/**
|
||||
* An MQTT client. This is a move-only type. Unless otherwise specified,
|
||||
* all function arguments need only to live through the duration of the
|
||||
* function call.
|
||||
*/
|
||||
class AWS_CRT_CPP_API MqttClient final
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initialize an MqttClient using bootstrap and allocator
|
||||
*/
|
||||
MqttClient(Io::ClientBootstrap &bootstrap, Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
/**
|
||||
* Initialize an MqttClient using a allocator and the default ClientBootstrap
|
||||
*
|
||||
* For more information on the default ClientBootstrap see
|
||||
* Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap
|
||||
*/
|
||||
MqttClient(Allocator *allocator = ApiAllocator()) noexcept;
|
||||
|
||||
~MqttClient();
|
||||
MqttClient(const MqttClient &) = delete;
|
||||
MqttClient(MqttClient &&) noexcept;
|
||||
MqttClient &operator=(const MqttClient &) = delete;
|
||||
MqttClient &operator=(MqttClient &&) noexcept;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const noexcept;
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int LastError() const noexcept;
|
||||
|
||||
/**
|
||||
* Create a new connection object using TLS from the client. The client must outlive
|
||||
* all of its connection instances.
|
||||
*
|
||||
* @param hostName endpoint to connect to
|
||||
* @param port port to connect to
|
||||
* @param socketOptions socket options to use when establishing the connection
|
||||
* @param tlsContext tls context to use with the connection
|
||||
* @param useWebsocket should the connection use websockets or should it use direct mqtt?
|
||||
*
|
||||
* @return a new connection object. Connect() will still need to be called after all further
|
||||
* configuration is finished.
|
||||
*/
|
||||
std::shared_ptr<MqttConnection> NewConnection(
|
||||
const char *hostName,
|
||||
uint32_t port,
|
||||
const Io::SocketOptions &socketOptions,
|
||||
const Crt::Io::TlsContext &tlsContext,
|
||||
bool useWebsocket = false) noexcept;
|
||||
|
||||
/**
|
||||
* Create a new connection object over plain text from the client. The client must outlive
|
||||
* all of its connection instances.
|
||||
* @param hostName endpoint to connect to
|
||||
* @param port port to connect to
|
||||
* @param socketOptions socket options to use when establishing the connection
|
||||
* @param useWebsocket should the connection use websockets or should it use direct mqtt?
|
||||
*
|
||||
* @return a new connection object. Connect() will still need to be called after all further
|
||||
* configuration is finished.
|
||||
*/
|
||||
std::shared_ptr<MqttConnection> NewConnection(
|
||||
const char *hostName,
|
||||
uint32_t port,
|
||||
const Io::SocketOptions &socketOptions,
|
||||
bool useWebsocket = false) noexcept;
|
||||
|
||||
private:
|
||||
aws_mqtt_client *m_client;
|
||||
};
|
||||
} // namespace Mqtt
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,462 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Exports.h>
|
||||
#include <aws/crt/StlAllocator.h>
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/crt/http/HttpConnection.h>
|
||||
#include <aws/crt/io/SocketOptions.h>
|
||||
#include <aws/crt/io/TlsOptions.h>
|
||||
#include <aws/crt/mqtt/MqttTypes.h>
|
||||
|
||||
#include <aws/mqtt/client.h>
|
||||
#include <aws/mqtt/v5/mqtt5_client.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Http
|
||||
{
|
||||
class HttpRequest;
|
||||
}
|
||||
|
||||
namespace Mqtt5
|
||||
{
|
||||
class Mqtt5Client;
|
||||
class Mqtt5ClientCore;
|
||||
} // namespace Mqtt5
|
||||
|
||||
namespace Mqtt
|
||||
{
|
||||
class MqttClient;
|
||||
class MqttConnectionCore;
|
||||
class MqttConnection;
|
||||
|
||||
/**
|
||||
* The data returned when the connection closed callback is invoked in a connection.
|
||||
* Note: This class is currently empty, but this may contain data in the future.
|
||||
*/
|
||||
struct OnConnectionClosedData
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* The data returned when the connection success callback is invoked in a connection.
|
||||
*/
|
||||
struct OnConnectionSuccessData
|
||||
{
|
||||
/**
|
||||
* The Connect return code received from the server.
|
||||
*/
|
||||
ReturnCode returnCode;
|
||||
|
||||
/**
|
||||
* Returns whether a session was present and resumed for this successful connection.
|
||||
* Will be set to true if the connection resumed an already present MQTT connection session.
|
||||
*/
|
||||
bool sessionPresent;
|
||||
};
|
||||
|
||||
/**
|
||||
* The data returned when the connection failure callback is invoked in a connection.
|
||||
*/
|
||||
struct OnConnectionFailureData
|
||||
{
|
||||
/**
|
||||
* The AWS CRT error code for the connection failure.
|
||||
* Use Aws::Crt::ErrorDebugString to get a human readable string from the error code.
|
||||
*/
|
||||
int error;
|
||||
};
|
||||
|
||||
/**
|
||||
* Invoked Upon Connection loss.
|
||||
*/
|
||||
using OnConnectionInterruptedHandler = std::function<void(MqttConnection &connection, int error)>;
|
||||
|
||||
/**
|
||||
* Invoked Upon Connection resumed.
|
||||
*/
|
||||
using OnConnectionResumedHandler =
|
||||
std::function<void(MqttConnection &connection, ReturnCode connectCode, bool sessionPresent)>;
|
||||
|
||||
/**
|
||||
* Invoked when a connack message is received, or an error occurred.
|
||||
*/
|
||||
using OnConnectionCompletedHandler = std::function<
|
||||
void(MqttConnection &connection, int errorCode, ReturnCode returnCode, bool sessionPresent)>;
|
||||
|
||||
/**
|
||||
* Invoked when a connection is disconnected and shutdown successfully.
|
||||
*
|
||||
* Note: Currently callbackData will always be nullptr, but this may change in the future to send additional
|
||||
* data.
|
||||
*/
|
||||
using OnConnectionClosedHandler =
|
||||
std::function<void(MqttConnection &connection, OnConnectionClosedData *callbackData)>;
|
||||
|
||||
/**
|
||||
* Invoked whenever the connection successfully connects.
|
||||
*
|
||||
* This callback is invoked for every successful connect and every successful reconnect.
|
||||
*/
|
||||
using OnConnectionSuccessHandler =
|
||||
std::function<void(MqttConnection &connection, OnConnectionSuccessData *callbackData)>;
|
||||
|
||||
/**
|
||||
* Invoked whenever the connection fails to connect.
|
||||
*
|
||||
* This callback is invoked for every failed connect and every failed reconnect.
|
||||
*/
|
||||
using OnConnectionFailureHandler =
|
||||
std::function<void(MqttConnection &connection, OnConnectionFailureData *callbackData)>;
|
||||
|
||||
/**
|
||||
* Invoked when a disconnect message has been sent.
|
||||
*/
|
||||
using OnDisconnectHandler = std::function<void(MqttConnection &connection)>;
|
||||
|
||||
/**
|
||||
* @deprecated Use OnMessageReceivedHandler
|
||||
*/
|
||||
using OnPublishReceivedHandler =
|
||||
std::function<void(MqttConnection &connection, const String &topic, const ByteBuf &payload)>;
|
||||
|
||||
/**
|
||||
* Callback for users to invoke upon completion of, presumably asynchronous, OnWebSocketHandshakeIntercept
|
||||
* callback's initiated process.
|
||||
*/
|
||||
using OnWebSocketHandshakeInterceptComplete =
|
||||
std::function<void(const std::shared_ptr<Http::HttpRequest> &, int errorCode)>;
|
||||
|
||||
/**
|
||||
* Invoked during websocket handshake to give users opportunity to transform an http request for purposes
|
||||
* such as signing/authorization etc... Returning from this function does not continue the websocket
|
||||
* handshake since some work flows may be asynchronous. To accommodate that, onComplete must be invoked upon
|
||||
* completion of the signing process.
|
||||
*/
|
||||
using OnWebSocketHandshakeIntercept = std::function<
|
||||
void(std::shared_ptr<Http::HttpRequest> req, const OnWebSocketHandshakeInterceptComplete &onComplete)>;
|
||||
|
||||
/**
|
||||
* Represents a persistent Mqtt Connection. The memory is owned by MqttClient or Mqtt5Client.
|
||||
*
|
||||
* To get a new instance of this class, use MqttClient::NewConnection or Mqtt5Client::NewConnection. Unless
|
||||
* specified all function arguments need only to live through the duration of the function call.
|
||||
*
|
||||
* @sa MqttClient::NewConnection
|
||||
* @sa Mqtt5Client::NewConnection
|
||||
*/
|
||||
class AWS_CRT_CPP_API MqttConnection final : public std::enable_shared_from_this<MqttConnection>
|
||||
{
|
||||
friend class MqttClient;
|
||||
friend class Mqtt5::Mqtt5ClientCore;
|
||||
|
||||
public:
|
||||
~MqttConnection();
|
||||
MqttConnection(const MqttConnection &) = delete;
|
||||
MqttConnection(MqttConnection &&) = delete;
|
||||
MqttConnection &operator=(const MqttConnection &) = delete;
|
||||
MqttConnection &operator=(MqttConnection &&) = delete;
|
||||
|
||||
/**
|
||||
* Create a new MqttConnection object from the Mqtt5Client.
|
||||
* @param mqtt5client The shared ptr of Mqtt5Client
|
||||
*
|
||||
* @return std::shared_ptr<Crt::Mqtt::MqttConnection>
|
||||
*/
|
||||
static std::shared_ptr<Crt::Mqtt::MqttConnection> NewConnectionFromMqtt5Client(
|
||||
std::shared_ptr<Mqtt5::Mqtt5Client> mqtt5client) noexcept;
|
||||
|
||||
/**
|
||||
* @return true if the instance is in a valid state, false otherwise.
|
||||
*/
|
||||
operator bool() const noexcept;
|
||||
|
||||
/**
|
||||
* @return the value of the last aws error encountered by operations on this instance.
|
||||
*/
|
||||
int LastError() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets LastWill for the connection.
|
||||
* @param topic topic the will message should be published to
|
||||
* @param qos QOS the will message should be published with
|
||||
* @param retain true if the will publish should be treated as a retained publish
|
||||
* @param payload payload of the will message
|
||||
* @return success/failure in setting the will
|
||||
*/
|
||||
bool SetWill(const char *topic, QOS qos, bool retain, const ByteBuf &payload) noexcept;
|
||||
|
||||
/**
|
||||
* Sets login credentials for the connection. The must get set before the Connect call
|
||||
* if it is to be used.
|
||||
* @param username user name to add to the MQTT CONNECT packet
|
||||
* @param password password to add to the MQTT CONNECT packet
|
||||
* @return success/failure
|
||||
*/
|
||||
bool SetLogin(const char *username, const char *password) noexcept;
|
||||
|
||||
/**
|
||||
* @deprecated Sets websocket proxy options. Replaced by SetHttpProxyOptions.
|
||||
*/
|
||||
bool SetWebsocketProxyOptions(const Http::HttpClientConnectionProxyOptions &proxyOptions) noexcept;
|
||||
|
||||
/**
|
||||
* Sets http proxy options. In order to use an http proxy with mqtt either
|
||||
* (1) Websockets are used
|
||||
* (2) Mqtt-over-tls is used and the ALPN list of the tls context contains a tag that resolves to mqtt
|
||||
*
|
||||
* @param proxyOptions proxy configuration for making the mqtt connection
|
||||
*
|
||||
* @return success/failure
|
||||
*/
|
||||
bool SetHttpProxyOptions(const Http::HttpClientConnectionProxyOptions &proxyOptions) noexcept;
|
||||
|
||||
/**
|
||||
* Customize time to wait between reconnect attempts.
|
||||
* The time will start at min and multiply by 2 until max is reached.
|
||||
* The time resets back to min after a successful connection.
|
||||
* This function should only be called before Connect().
|
||||
*
|
||||
* @param min_seconds minimum time to wait before attempting a reconnect
|
||||
* @param max_seconds maximum time to wait before attempting a reconnect
|
||||
*
|
||||
* @return success/failure
|
||||
*/
|
||||
bool SetReconnectTimeout(uint64_t min_seconds, uint64_t max_seconds) noexcept;
|
||||
|
||||
/**
|
||||
* Initiates the connection, OnConnectionCompleted will
|
||||
* be invoked in an event-loop thread.
|
||||
*
|
||||
* @param clientId client identifier to use when establishing the mqtt connection
|
||||
* @param cleanSession false to attempt to rejoin an existing session for the client id, true to skip
|
||||
* and start with a new session
|
||||
* @param keepAliveTimeSecs time interval to space mqtt pings apart by
|
||||
* @param pingTimeoutMs timeout in milliseconds before the keep alive ping is considered to have failed
|
||||
* @param protocolOperationTimeoutMs timeout in milliseconds to give up waiting for a response packet
|
||||
* for an operation. Necessary due to throttling properties on certain server implementations that do
|
||||
* not return an ACK for throttled operations.
|
||||
*
|
||||
* @return true if the connection attempt was successfully started (implying a callback will be invoked
|
||||
* with the eventual result), false if it could not be started (no callback will happen)
|
||||
*/
|
||||
bool Connect(
|
||||
const char *clientId,
|
||||
bool cleanSession,
|
||||
uint16_t keepAliveTimeSecs = 0,
|
||||
uint32_t pingTimeoutMs = 0,
|
||||
uint32_t protocolOperationTimeoutMs = 0) noexcept;
|
||||
|
||||
/**
|
||||
* Initiates disconnect, OnDisconnectHandler will be invoked in an event-loop thread.
|
||||
* @return success/failure in initiating disconnect
|
||||
*/
|
||||
bool Disconnect() noexcept;
|
||||
|
||||
/// @private
|
||||
aws_mqtt_client_connection *GetUnderlyingConnection() noexcept;
|
||||
|
||||
/**
|
||||
* Subscribes to topicFilter. OnMessageReceivedHandler will be invoked from an event-loop
|
||||
* thread upon an incoming Publish message. OnSubAckHandler will be invoked
|
||||
* upon receipt of a suback message.
|
||||
*
|
||||
* @param topicFilter topic filter to subscribe to
|
||||
* @param qos maximum qos client is willing to receive matching messages on
|
||||
* @param onMessage callback to invoke when a message is received based on matching this filter
|
||||
* @param onSubAck callback to invoke with the server's response to the subscribe request
|
||||
*
|
||||
* @return packet id of the subscribe request, or 0 if the attempt failed synchronously
|
||||
*/
|
||||
uint16_t Subscribe(
|
||||
const char *topicFilter,
|
||||
QOS qos,
|
||||
OnMessageReceivedHandler &&onMessage,
|
||||
OnSubAckHandler &&onSubAck) noexcept;
|
||||
|
||||
/**
|
||||
* @deprecated Use alternate Subscribe()
|
||||
*/
|
||||
uint16_t Subscribe(
|
||||
const char *topicFilter,
|
||||
QOS qos,
|
||||
OnPublishReceivedHandler &&onPublish,
|
||||
OnSubAckHandler &&onSubAck) noexcept;
|
||||
|
||||
/**
|
||||
* Subscribes to multiple topicFilters. OnMessageReceivedHandler will be invoked from an event-loop
|
||||
* thread upon an incoming Publish message. OnMultiSubAckHandler will be invoked
|
||||
* upon receipt of a suback message.
|
||||
*
|
||||
* @param topicFilters list of pairs of topic filters and message callbacks to invoke on a matching
|
||||
* publish
|
||||
* @param qos maximum qos client is willing to receive matching messages on
|
||||
* @param onOpComplete callback to invoke with the server's response to the subscribe request
|
||||
*
|
||||
* @return packet id of the subscribe request, or 0 if the attempt failed synchronously
|
||||
*/
|
||||
uint16_t Subscribe(
|
||||
const Vector<std::pair<const char *, OnMessageReceivedHandler>> &topicFilters,
|
||||
QOS qos,
|
||||
OnMultiSubAckHandler &&onOpComplete) noexcept;
|
||||
|
||||
/**
|
||||
* @deprecated Use alternate Subscribe()
|
||||
*/
|
||||
uint16_t Subscribe(
|
||||
const Vector<std::pair<const char *, OnPublishReceivedHandler>> &topicFilters,
|
||||
QOS qos,
|
||||
OnMultiSubAckHandler &&onOpComplete) noexcept;
|
||||
|
||||
/**
|
||||
* Installs a handler for all incoming publish messages, regardless of if Subscribe has been
|
||||
* called on the topic.
|
||||
*
|
||||
* @param onMessage callback to invoke for all received messages
|
||||
* @return success/failure
|
||||
*/
|
||||
bool SetOnMessageHandler(OnMessageReceivedHandler &&onMessage) noexcept;
|
||||
|
||||
/**
|
||||
* @deprecated Use alternate SetOnMessageHandler()
|
||||
*/
|
||||
bool SetOnMessageHandler(OnPublishReceivedHandler &&onPublish) noexcept;
|
||||
|
||||
/**
|
||||
* Unsubscribes from topicFilter. OnOperationCompleteHandler will be invoked upon receipt of
|
||||
* an unsuback message.
|
||||
*
|
||||
* @param topicFilter topic filter to unsubscribe the session from
|
||||
* @param onOpComplete callback to invoke on receipt of the server's UNSUBACK message
|
||||
*
|
||||
* @return packet id of the unsubscribe request, or 0 if the attempt failed synchronously
|
||||
*/
|
||||
uint16_t Unsubscribe(const char *topicFilter, OnOperationCompleteHandler &&onOpComplete) noexcept;
|
||||
|
||||
/**
|
||||
* Publishes to a topic.
|
||||
*
|
||||
* @param topic topic to publish to
|
||||
* @param qos QOS to publish the message with
|
||||
* @param retain should this message replace the current retained message of the topic?
|
||||
* @param payload payload of the message
|
||||
* @param onOpComplete completion callback to invoke when the operation is complete. If QoS is 0, then
|
||||
* the callback is invoked when the message is passed to the tls handler, otherwise it's invoked
|
||||
* on receipt of the final response from the server.
|
||||
*
|
||||
* @return packet id of the publish request, or 0 if the attempt failed synchronously
|
||||
*/
|
||||
uint16_t Publish(
|
||||
const char *topic,
|
||||
QOS qos,
|
||||
bool retain,
|
||||
const ByteBuf &payload,
|
||||
OnOperationCompleteHandler &&onOpComplete) noexcept;
|
||||
|
||||
/**
|
||||
* Get the statistics about the current state of the connection's queue of operations
|
||||
*
|
||||
* @return MqttConnectionOperationStatistics
|
||||
*/
|
||||
const MqttConnectionOperationStatistics &GetOperationStatistics() noexcept;
|
||||
|
||||
/**
|
||||
* A callback invoked every time the connections is interrupted.
|
||||
*/
|
||||
OnConnectionInterruptedHandler OnConnectionInterrupted;
|
||||
|
||||
/**
|
||||
* A callback invoked every time the connection is resumed.
|
||||
*/
|
||||
OnConnectionResumedHandler OnConnectionResumed;
|
||||
|
||||
/**
|
||||
* Invoked when a connack message is received, or an error occurred.
|
||||
*/
|
||||
OnConnectionCompletedHandler OnConnectionCompleted;
|
||||
|
||||
/**
|
||||
* A callback invoked on disconnect.
|
||||
*/
|
||||
OnDisconnectHandler OnDisconnect;
|
||||
|
||||
/**
|
||||
* Invoked during websocket handshake to give users opportunity to transform an http request for
|
||||
* purposes such as signing/authorization etc... Returning from this function does not continue the
|
||||
* websocket handshake since some work flows may be asynchronous. To accommodate that, onComplete must
|
||||
* be invoked upon completion of the signing process.
|
||||
*/
|
||||
OnWebSocketHandshakeIntercept WebsocketInterceptor;
|
||||
|
||||
/**
|
||||
* Invoked when a connection is disconnected and shutdown successfully.
|
||||
*
|
||||
* @note Currently callbackData will always be nullptr, but this may change in the future to send
|
||||
* additional data.
|
||||
* @note From the user perspective, this callback is indistinguishable from OnDisconnect.
|
||||
*/
|
||||
OnConnectionClosedHandler OnConnectionClosed;
|
||||
|
||||
/**
|
||||
* Invoked whenever the connection successfully connects.
|
||||
*
|
||||
* This callback is invoked for every successful connect and every successful reconnect.
|
||||
*/
|
||||
OnConnectionSuccessHandler OnConnectionSuccess;
|
||||
|
||||
/**
|
||||
* Invoked whenever the connection fails to connect.
|
||||
*
|
||||
* This callback is invoked for every failed connect and every failed reconnect.
|
||||
*/
|
||||
OnConnectionFailureHandler OnConnectionFailure;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Make private to restrict ability to create MqttConnections objects to certain classes.
|
||||
*/
|
||||
MqttConnection() = default;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Factory method for creating MqttConnection.
|
||||
*
|
||||
* @param client MQTT3 client.
|
||||
* @param options Options required for MqttConnection creation.
|
||||
* @return New instance of MqttConnection.
|
||||
*/
|
||||
static std::shared_ptr<MqttConnection> s_CreateMqttConnection(
|
||||
aws_mqtt_client *client,
|
||||
MqttConnectionOptions options) noexcept;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Factory method for creating MqttConnection.
|
||||
*
|
||||
* @param mqtt5Client MQTT5 client.
|
||||
* @param options Options required for MqttConnection creation.
|
||||
* @return New instance of MqttConnection.
|
||||
*/
|
||||
static std::shared_ptr<MqttConnection> s_CreateMqttConnection(
|
||||
aws_mqtt5_client *mqtt5Client,
|
||||
MqttConnectionOptions options) noexcept;
|
||||
/**
|
||||
* @internal
|
||||
* Internal handler for the underlying connection.
|
||||
*/
|
||||
std::shared_ptr<MqttConnectionCore> m_connectionCore;
|
||||
};
|
||||
} // namespace Mqtt
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
@@ -0,0 +1,130 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*/
|
||||
|
||||
#include <aws/crt/Types.h>
|
||||
#include <aws/crt/io/SocketOptions.h>
|
||||
#include <aws/crt/io/TlsOptions.h>
|
||||
|
||||
#include <aws/mqtt/client.h>
|
||||
#include <aws/mqtt/v5/mqtt5_client.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Aws
|
||||
{
|
||||
namespace Crt
|
||||
{
|
||||
namespace Mqtt
|
||||
{
|
||||
class MqttConnection;
|
||||
|
||||
/**
|
||||
* Options required to create an MqttConnection.
|
||||
*/
|
||||
struct MqttConnectionOptions
|
||||
{
|
||||
const char *hostName = nullptr;
|
||||
uint32_t port = 0;
|
||||
Io::SocketOptions socketOptions;
|
||||
Crt::Io::TlsContext tlsContext;
|
||||
Crt::Io::TlsConnectionOptions tlsConnectionOptions;
|
||||
bool useWebsocket = false;
|
||||
bool useTls = false;
|
||||
Allocator *allocator = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Invoked upon receipt of a Publish message on a subscribed topic.
|
||||
*
|
||||
* @param connection The connection object.
|
||||
* @param topic The information channel to which the payload data was published.
|
||||
* @param payload The payload data.
|
||||
* @param dup DUP flag. If true, this might be re-delivery of an earlier attempt to send the message.
|
||||
* @param qos Quality of Service used to deliver the message.
|
||||
* @param retain Retain flag. If true, the message was sent as a result of a new subscription being made by
|
||||
* the client.
|
||||
*/
|
||||
using OnMessageReceivedHandler = std::function<void(
|
||||
MqttConnection &connection,
|
||||
const String &topic,
|
||||
const ByteBuf &payload,
|
||||
bool dup,
|
||||
QOS qos,
|
||||
bool retain)>;
|
||||
|
||||
/**
|
||||
* Invoked when a suback message is received.
|
||||
*
|
||||
* @param connection The connection object.
|
||||
* @param packetId Packet ID of the corresponding subscribe request.
|
||||
* @param topic The information channel to which the payload data was published.
|
||||
* @param qos Quality of Service used to deliver the message.
|
||||
* @param errorCode Indicating if an error occurred.
|
||||
*/
|
||||
using OnSubAckHandler = std::function<
|
||||
void(MqttConnection &connection, uint16_t packetId, const String &topic, QOS qos, int errorCode)>;
|
||||
|
||||
/**
|
||||
* Invoked when a suback message for multiple topics is received.
|
||||
*
|
||||
* @param connection The connection object.
|
||||
* @param packetId Packet ID of the corresponding subscribe request.
|
||||
* @param topics The information channels to which the payload data was published.
|
||||
* @param qos Quality of Service used to deliver the message.
|
||||
* @param errorCode Indicating if an error occurred.
|
||||
*/
|
||||
using OnMultiSubAckHandler = std::function<void(
|
||||
MqttConnection &connection,
|
||||
uint16_t packetId,
|
||||
const Vector<String> &topics,
|
||||
QOS qos,
|
||||
int errorCode)>;
|
||||
|
||||
/**
|
||||
* Invoked when an operation completes.
|
||||
*
|
||||
* For QoS 0, this is when the packet is passed to the tls layer. For QoS 1 (and 2, in theory) this is when
|
||||
* the final ACK packet is received from the server.
|
||||
*
|
||||
* @param connection The connection object.
|
||||
* @param packetId Packet ID of the corresponding subscribe request.
|
||||
* @param errorCode Indicating if an error occurred.
|
||||
*/
|
||||
using OnOperationCompleteHandler =
|
||||
std::function<void(MqttConnection &connection, uint16_t packetId, int errorCode)>;
|
||||
|
||||
/**
|
||||
* Simple statistics about the current state of the client's queue of operations.
|
||||
*/
|
||||
struct AWS_CRT_CPP_API MqttConnectionOperationStatistics
|
||||
{
|
||||
/*
|
||||
* Total number of operations submitted to the connection that have not yet been completed. Unacked
|
||||
* operations are a subset of this.
|
||||
*/
|
||||
uint64_t incompleteOperationCount;
|
||||
|
||||
/*
|
||||
* Total packet size of operations submitted to the connection that have not yet been completed. Unacked
|
||||
* operations are a subset of this.
|
||||
*/
|
||||
uint64_t incompleteOperationSize;
|
||||
|
||||
/*
|
||||
* Total number of operations that have been sent to the server and are waiting for a corresponding ACK
|
||||
* before they can be completed.
|
||||
*/
|
||||
uint64_t unackedOperationCount;
|
||||
|
||||
/*
|
||||
* Total packet size of operations that have been sent to the server and are waiting for a corresponding
|
||||
* ACK before they can be completed.
|
||||
*/
|
||||
uint64_t unackedOperationSize;
|
||||
};
|
||||
} // namespace Mqtt
|
||||
} // namespace Crt
|
||||
} // namespace Aws
|
||||
Reference in New Issue
Block a user