xbox-live-api/Source/Shared/http_call_wrapper_internal.h

264 строки
9.0 KiB
C++

#pragma once
#include "httpClient/httpClient.h"
#include "shared_macros.h"
#include "xbox_live_context_settings_internal.h"
const char CONTENT_TYPE_HEADER[] = "Content-Type";
const char ACCEPT_LANGUAGE_HEADER[] = "Accept-Language";
const char CONTRACT_VERSION_HEADER[] = "x-xbl-contract-version";
const char USER_AGENT_HEADER[] = "User-Agent";
NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN
enum class xbox_live_api
{
unspecified,
add_user_to_club,
add_club_role,
allocate_cluster,
allocate_cluster_inline,
allocate_session_host,
browse_catalog_bundles_helper,
browse_catalog_helper,
check_multiple_permissions_with_multiple_target_users,
check_permission_with_target_user,
clear_activity,
clear_search_handle,
consume_inventory_item,
create_club,
create_match_ticket,
delete_blob,
delete_club,
delete_match_ticket,
download_blob,
events_upload,
get_achievement,
get_achievements,
get_activities_for_social_group,
get_activities_for_users,
get_avoid_or_mute_list,
get_blob_metadata,
get_broadcasts,
get_catalog_item_details,
get_club,
get_club_batch,
get_clubs_owned,
get_configuration,
get_current_session,
get_current_session_by_handle,
get_game_clips,
get_game_server_metadata,
get_hopper_statistics,
get_inventory_item,
get_inventory_items,
get_leaderboard_for_social_group_internal,
get_leaderboard_internal,
get_match_ticket_details,
get_multiple_user_statistics_for_multiple_service_configurations,
get_presence,
get_presence_for_multiple_users,
get_presence_for_social_group,
get_quality_of_service_servers,
get_quota,
get_quota_for_session_storage,
get_search_handles,
delete_search_handle,
get_session_host_allocation_status,
get_sessions,
get_single_user_statistics,
get_social_graph,
get_social_relationships,
get_stats_value_document,
get_ticket_status,
get_teams,
get_team_details,
get_user_profiles,
get_user_profiles_for_social_group,
get_users_club_associations,
recommend_clubs,
register_team,
remove_user_from_club,
remove_club_role,
rename_club,
search_clubs,
send_invites,
set_activity,
set_presence_helper,
set_search_handle,
set_transfer_handle,
set_user_presence_within_club,
submit_batch_reputation_feedback,
submit_reputation_feedback,
subscribe_to_notifications,
suggest_clubs,
update_achievement,
patch_stats_value_document,
post_stats_value_document,
upload_blob,
verify_strings,
write_session_using_subpath,
xbox_one_pins_add_item,
xbox_one_pins_contains_item,
xbox_one_pins_remove_item,
post_recent_players,
get_activity_batch,
delete_activity,
mpa_send_invites
};
using HttpHeaders = xsapi_internal_map<xsapi_internal_string, xsapi_internal_string>;
using HttpResult = Result<std::shared_ptr<class HttpCall>>;
// RAII wrapper around HCHttpCall. No Xbox Live specific logic.
class HttpCall : public RefCounter, public std::enable_shared_from_this<HttpCall>
{
public:
HttpCall() = default;
virtual ~HttpCall();
HRESULT Init(
_In_ const xsapi_internal_string& httpMethod,
_In_ const xsapi_internal_string& fullUrl
);
virtual HRESULT SetHeader(
_In_ const xsapi_internal_string& key,
_In_ const xsapi_internal_string& value,
_In_ bool allowTracing = true
);
virtual HRESULT SetTracing(bool traceCall);
virtual HRESULT SetRequestBody(const xsapi_internal_vector<uint8_t>& bytes);
virtual HRESULT SetRequestBody(_In_reads_bytes_(requestBodySize) const uint8_t* requestBodyBytes, _In_ uint32_t requestBodySize);
virtual HRESULT SetRequestBody(const xsapi_internal_string& bodyString);
virtual HRESULT SetRequestBody(const JsonValue& bodyJson);
virtual HRESULT SetRequestBody(_In_z_ const char* requestBodyString);
virtual HRESULT SetRetryAllowed(bool retryAllowed);
virtual HRESULT SetRetryCacheId(uint32_t retryAfterCacheId);
virtual HRESULT SetRetryDelay(uint32_t retryDelayInSeconds);
virtual HRESULT SetTimeout(uint32_t timeoutInSeconds);
virtual HRESULT SetTimeoutWindow(uint32_t timeoutWindowInSeconds);
virtual HRESULT Perform(
AsyncContext<HttpResult> async,
bool forceRefresh = false
);
virtual HRESULT GetRequestUrl(const char** url) const;
virtual HRESULT GetErrorMessage(const char** errorMessage) const;
virtual HRESULT Result() const;
virtual uint32_t HttpStatus() const;
virtual xsapi_internal_string GetResponseHeader(const xsapi_internal_string& key) const;
virtual HttpHeaders GetResponseHeaders() const;
virtual xsapi_internal_vector<uint8_t> GetResponseBodyBytes() const;
virtual HRESULT GetResponseBodyBytesSize(_Out_ size_t* bufferSize);
virtual HRESULT GetResponseBodyBytes(_In_ size_t bufferSize, _Out_writes_bytes_to_(bufferSize, *bufferUsed) uint8_t* buffer, _Out_opt_ size_t* bufferUsed);
virtual xsapi_internal_string GetResponseBodyString() const;
virtual HRESULT GetResponseString(_Out_ const char** responseString);
virtual JsonDocument GetResponseBodyJson() const;
virtual HRESULT GetNetworkErrorCode(_Out_ HRESULT* networkErrorCode, _Out_ uint32_t* platformNetworkErrorCode);
virtual HRESULT GetPlatformNetworkErrorMessage(_Out_ const char** platformNetworkErrorMessage);
virtual HRESULT ResponseGetHeader(_In_z_ const char* headerName, _Out_ const char** headerValue);
virtual HRESULT ResponseGetNumHeaders(_Out_ uint32_t* numHeaders);
virtual HRESULT ResponseGetHeaderAtIndex(_In_ uint32_t headerIndex, _Out_ const char** headerName, _Out_ const char** headerValue);
private:
HttpCall(const HttpCall&) = delete;
HttpCall& operator=(HttpCall) = delete;
static void CALLBACK CompletionCallback(_In_ XAsyncBlock* async);
std::shared_ptr<RefCounter> GetSharedThis() override;
static HRESULT ConvertHttpStatusToHRESULT(_In_ uint32_t httpStatusCode);
HRESULT CopyHttpCallHandle();
XAsyncBlock m_asyncBlock{};
AsyncContext<HttpResult> m_asyncContext;
bool m_performAlreadyCalled{ false };
enum class Step
{
Uninitialized,
Pending,
Running,
Done
} m_step{ Step::Uninitialized };
protected:
HCCallHandle m_callHandle{ nullptr };
HRESULT ResetAndCopyForRetry();
};
NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END
using namespace xbox::services;
// Xbox Live specific http call wrapper that gets and attaches the Xbox Live token,
// signs the request, and adds Xbox Live specific headers automatically.
// Handles 401 token refresh logic, and 429 throttling logic
struct XblHttpCall : public HttpCall
{
public:
XblHttpCall(User&& user);
virtual HRESULT Init(
_In_ std::shared_ptr<XboxLiveContextSettings> contextSettings,
_In_ const xsapi_internal_string& httpMethod,
_In_ const xsapi_internal_string& fullUrl,
_In_ xbox_live_api xboxLiveApi
);
HRESULT SetHeader(
_In_ const xsapi_internal_string& key,
_In_ const xsapi_internal_string& value,
_In_ bool allowTracing = true
) override;
// Override the UserAgent that was specified in the contextSettings
HRESULT SetUserAgent(_In_ HttpCallAgent userAgent);
void SetLongHttpCall(_In_ bool longHttpCall);
HRESULT SetXblServiceContractVersion(uint32_t contractVersion);
HRESULT SetRequestBody(const xsapi_internal_vector<uint8_t>& bytes) override;
HRESULT SetRequestBody(_In_reads_bytes_(requestBodySize) const uint8_t* requestBodyBytes, _In_ uint32_t requestBodySize) override;
HRESULT SetRequestBody(const xsapi_internal_string& bodyString) override;
HRESULT SetRequestBody(const JsonValue& bodyJson) override;
HRESULT SetRequestBody(_In_z_ const char* requestBodyString) override;
void SetAuthRetryAllowed(bool authRetryAllowed);
HRESULT Perform(
AsyncContext<HttpResult> async,
bool forceRefresh = false
) override;
static xsapi_internal_string BuildUrl(
xsapi_internal_string&& serviceName,
const xsapi_internal_string& pathQueryFragment
);
private:
XblHttpCall(const XblHttpCall&) = delete;
XblHttpCall& operator=(XblHttpCall) = delete;
void IntermediateHttpCallCompleteCallback(HttpResult result);
HRESULT HandleAuthError(_In_ std::shared_ptr<class HttpCall> httpCall, _Out_ bool& wasHandled);
void HandleThrottleError(_In_ std::shared_ptr<class HttpCall> httpCall);
HRESULT CalcHttpTimeout();
User m_user;
xsapi_internal_vector<uint8_t> m_requestBody;
HttpHeaders m_requestHeaders;
xsapi_internal_string m_httpMethod;
xsapi_internal_string m_fullUrl;
bool m_longHttpCall{ false };
uint32_t m_longHttpTimeout{ 0 };
uint32_t m_httpTimeoutWindowInSeconds{ 0 };
chrono_clock_t::time_point m_firstCallStartTime;
chrono_clock_t::time_point m_requestStartTime;
uint32_t m_iterationNumber{ 0 };
AsyncContext<HttpResult> m_asyncContext;
bool m_authRetryExplicitlyAllowed{ false };
bool m_hasPerformedRetryOn401{ false };
};