spectrum2/3rdparty/cpprestsdk/include/cpprest/details/web_utilities.h
2015-11-19 15:19:14 +01:00

248 lines
7.9 KiB
C++

/***
* ==++==
*
* Copyright (c) Microsoft Corporation. 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.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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.
*
* ==--==
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
*
* utility classes used by the different web:: clients
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
****/
#pragma once
#include "cpprest/asyncrt_utils.h"
namespace web
{
namespace http { namespace client { namespace details {
class winhttp_client;
class winrt_client;
}}}
namespace websockets { namespace client { namespace details {
class winrt_callback_client;
class wspp_callback_client;
}}}
namespace details
{
class zero_memory_deleter
{
public:
_ASYNCRTIMP void operator()(::utility::string_t *data) const;
};
typedef std::unique_ptr<::utility::string_t, zero_memory_deleter> plaintext_string;
#if defined(_WIN32) && !defined(CPPREST_TARGET_XP)
#if defined(__cplusplus_winrt)
#if !(WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP && _MSC_VER < 1800)
class winrt_encryption
{
public:
winrt_encryption() {}
_ASYNCRTIMP winrt_encryption(const std::wstring &data);
_ASYNCRTIMP plaintext_string decrypt() const;
private:
::pplx::task<Windows::Storage::Streams::IBuffer ^> m_buffer;
};
#endif
#else
class win32_encryption
{
public:
win32_encryption() {}
_ASYNCRTIMP win32_encryption(const std::wstring &data);
_ASYNCRTIMP ~win32_encryption();
_ASYNCRTIMP plaintext_string decrypt() const;
private:
std::vector<char> m_buffer;
size_t m_numCharacters;
};
#endif
#endif
}
/// <summary>
/// Represents a set of user credentials (user name and password) to be used
/// for authentication.
/// </summary>
class credentials
{
public:
/// <summary>
/// Constructs an empty set of credentials without a user name or password.
/// </summary>
credentials() {}
/// <summary>
/// Constructs credentials from given user name and password.
/// </summary>
/// <param name="username">User name as a string.</param>
/// <param name="password">Password as a string.</param>
credentials(utility::string_t username, const utility::string_t & password) :
m_username(std::move(username)),
m_password(password)
{}
/// <summary>
/// The user name associated with the credentials.
/// </summary>
/// <returns>A string containing the user name.</returns>
const utility::string_t &username() const { return m_username; }
/// <summary>
/// The password for the user name associated with the credentials.
/// </summary>
/// <returns>A string containing the password.</returns>
CASABLANCA_DEPRECATED("This API is deprecated for security reasons to avoid unnecessary password copies stored in plaintext.")
utility::string_t password() const
{
#if defined(_WIN32) && !defined(CPPREST_TARGET_XP)
#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP && _MSC_VER < 1800
return m_password;
#else
return utility::string_t(*m_password.decrypt());
#endif
#else
return m_password;
#endif
}
/// <summary>
/// Checks if credentials have been set
/// </summary>
/// <returns><c>true</c> if user name and password is set, <c>false</c> otherwise.</returns>
bool is_set() const { return !m_username.empty(); }
private:
friend class http::client::details::winhttp_client;
friend class http::client::details::winrt_client;
friend class websockets::client::details::winrt_callback_client;
friend class websockets::client::details::wspp_callback_client;
details::plaintext_string decrypt() const
{
// Encryption APIs not supported on Windows Phone 8.0 or XP
#if defined(_WIN32) && !defined(CPPREST_TARGET_XP)
#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP && _MSC_VER < 1800
return details::plaintext_string(new ::utility::string_t(m_password));
#else
return m_password.decrypt();
#endif
#else
return details::plaintext_string(new ::utility::string_t(m_password));
#endif
}
::utility::string_t m_username;
#if defined(_WIN32) && !defined(CPPREST_TARGET_XP)
#if defined(__cplusplus_winrt)
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP && _MSC_VER < 1800
::utility::string_t m_password;
#else
details::winrt_encryption m_password;
#endif
#else
details::win32_encryption m_password;
#endif
#else
::utility::string_t m_password;
#endif
};
/// <summary>
/// web_proxy represents the concept of the web proxy, which can be auto-discovered,
/// disabled, or specified explicitly by the user.
/// </summary>
class web_proxy
{
enum web_proxy_mode_internal{ use_default_, use_auto_discovery_, disabled_, user_provided_ };
public:
enum web_proxy_mode{ use_default = use_default_, use_auto_discovery = use_auto_discovery_, disabled = disabled_};
/// <summary>
/// Constructs a proxy with the default settings.
/// </summary>
web_proxy() : m_address(_XPLATSTR("")), m_mode(use_default_) {}
/// <summary>
/// Creates a proxy with specified mode.
/// </summary>
/// <param name="mode">Mode to use.</param>
web_proxy( web_proxy_mode mode ) : m_address(_XPLATSTR("")), m_mode(static_cast<web_proxy_mode_internal>(mode)) {}
/// <summary>
/// Creates a proxy explicitly with provided address.
/// </summary>
/// <param name="address">Proxy URI to use.</param>
web_proxy( uri address ) : m_address(address), m_mode(user_provided_) {}
/// <summary>
/// Gets this proxy's URI address. Returns an empty URI if not explicitly set by user.
/// </summary>
/// <returns>A reference to this proxy's URI.</returns>
const uri& address() const { return m_address; }
/// <summary>
/// Gets the credentials used for authentication with this proxy.
/// </summary>
/// <returns>Credentials to for this proxy.</returns>
const web::credentials& credentials() const { return m_credentials; }
/// <summary>
/// Sets the credentials to use for authentication with this proxy.
/// </summary>
/// <param name="cred">Credentials to use for this proxy.</param>
void set_credentials(web::credentials cred) {
if( m_mode == disabled_ )
{
throw std::invalid_argument("Cannot attach credentials to a disabled proxy");
}
m_credentials = std::move(cred);
}
/// <summary>
/// Checks if this proxy was constructed with default settings.
/// </summary>
/// <returns>True if default, false otherwise.</param>
bool is_default() const { return m_mode == use_default_; }
/// <summary>
/// Checks if using a proxy is disabled.
/// </summary>
/// <returns>True if disabled, false otherwise.</returns>
bool is_disabled() const { return m_mode == disabled_; }
/// <summary>
/// Checks if the auto discovery protocol, WPAD, is to be used.
/// </summary>
/// <returns>True if auto discovery enabled, false otherwise.</returns>
bool is_auto_discovery() const { return m_mode == use_auto_discovery_; }
/// <summary>
/// Checks if a proxy address is explicitly specified by the user.
/// </summary>
/// <returns>True if a proxy address was explicitly specified, false otherwise.</returns>
bool is_specified() const { return m_mode == user_provided_; }
private:
web::uri m_address;
web_proxy_mode_internal m_mode;
web::credentials m_credentials;
};
}